diff --git a/.ackrc b/.ackrc new file mode 100644 index 00000000..f9e9717e --- /dev/null +++ b/.ackrc @@ -0,0 +1,4 @@ +--ignore-dir=vendor +--ignore-dir=yoeunes +--ignore-dir=node_modules + diff --git a/.all-contributorsrc b/.all-contributorsrc index 417b7b53..3a826ba3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1 +1,90 @@ -undefined +{ + "projectName": "php-flasher", + "projectOwner": "php-flasher", + "repoType": "github", + "repoHost": "https://github.com", + "files": [ + "README.md" + ], + "imageSize": 100, + "commit": false, + "commitConvention": "angular", + "contributorsPerLine": 7, + "linkToUsage": false, + "contributors": [ + { + "login": "yoeunes", + "name": "Younes ENNAJI", + "avatar_url": "https://avatars.githubusercontent.com/u/10859693?v=4", + "profile": "https://www.linkedin.com/in/younes--ennaji/", + "contributions": [ + "code", + "doc", + "maintenance" + ] + }, + { + "login": "salmayno", + "name": "Salma Mourad", + "avatar_url": "https://avatars.githubusercontent.com/u/27933199?v=4", + "profile": "https://github.com/salmayno", + "contributions": [ + "financial" + ] + }, + { + "login": "codenashwan", + "name": "Nashwan Abdullah", + "avatar_url": "https://avatars.githubusercontent.com/u/35005761?v=4", + "profile": "https://www.youtube.com/rstacode", + "contributions": [ + "financial" + ] + }, + { + "login": "darviscommerce", + "name": "Arvid de Jong", + "avatar_url": "https://avatars.githubusercontent.com/u/7394837?v=4", + "profile": "https://darvis.nl/", + "contributions": [ + "financial" + ] + }, + { + "login": "ash-jc-allen", + "name": "Ash Allen", + "avatar_url": "https://avatars.githubusercontent.com/u/39652331?v=4", + "profile": "https://ashallendesign.co.uk/", + "contributions": [ + "design" + ] + }, + { + "login": "murrant", + "name": "Tony Murray", + "avatar_url": "https://avatars.githubusercontent.com/u/39462?v=4", + "profile": "https://about.me/murrant", + "contributions": [ + "code" + ] + }, + { + "login": "n3wborn", + "name": "Stéphane P", + "avatar_url": "https://avatars.githubusercontent.com/u/10246722?v=4", + "profile": "https://github.com/n3wborn", + "contributions": [ + "doc" + ] + }, + { + "login": "LucasStorm", + "name": "Lucas Maciel", + "avatar_url": "https://avatars.githubusercontent.com/u/80225404?v=4", + "profile": "https://www.instagram.com/lucas.maciel_z", + "contributions": [ + "design" + ] + } + ] +} diff --git a/.babelrc.json b/.babelrc.json new file mode 100644 index 00000000..1c6831ce --- /dev/null +++ b/.babelrc.json @@ -0,0 +1,3 @@ +{ + "presets": [["@babel/env", { "modules": false }]] +} diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 00000000..214388fe --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not dead diff --git a/src/Cli/Prime/Resources/bin/notifu/notifu.exe b/.cache/.gitkeep similarity index 100% rename from src/Cli/Prime/Resources/bin/notifu/notifu.exe rename to .cache/.gitkeep diff --git a/.czrc b/.czrc deleted file mode 100644 index d1bcc209..00000000 --- a/.czrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "path": "cz-conventional-changelog" -} diff --git a/.editorconfig b/.editorconfig index cd8eb86e..4999145a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,4 +12,11 @@ insert_final_newline = true trim_trailing_whitespace = true [*.md] +max_line_length = 0 trim_trailing_whitespace = false + +[auto_closer.yaml] +indent_size = 2 + +[COMMIT_EDITMSG] +max_line_length = 0 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..bcd0e31e --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +**/node_modules +src/**/Resources/public/** +src/**/Resources/dist/** diff --git a/.gitattributes b/.gitattributes index 3383d44b..30f46647 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,13 +1,16 @@ +* text=auto -# Path-based git attributes -# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +*.css diff=css +*.md diff=markdown +*.php diff=php -# Ignore all test and documentation with "export-ignore". -/.gitattributes export-ignore -/.gitignore export-ignore -/.travis.yml export-ignore -/phpunit.xml.dist export-ignore -/.scrutinizer.yml export-ignore -/.styleci.yml export-ignore -/tests export-ignore -/.editorconfig export-ignore +/.github export-ignore +/bin export-ignore +/tests export-ignore +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/CHANGELOG-* export-ignore +/CODE_OF_CONDUCT.md export-ignore +/CONTRIBUTING.md export-ignore +/phpunit.xml.dist export-ignore diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ee7f0542..f383baa2 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,147 +1,169 @@ -name: tests +name: 🧪 Run Tests & 🛠️ Static Analysis on: push: + branches: + - main + - 2.x + pull_request: + schedule: + - cron: '0 0 * * *' # Daily at midnight jobs: - symfony-test: - runs-on: ${{ matrix.os }} + static-analysis: + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - os: [ubuntu-latest] - symfony: [ 7.1.*, 7.0.*, 6.4.*, 6.3.*, 6.2.*, 6.1.*, 6.0.*, 5.4.*, 5.3.*, 5.2.*, 5.1.*, 5.0.*, 4.4.*, 4.3.*, 4.2.*, 4.1.*, 4.0.*, 3.4.*, 3.3.*, 3.2.*, 3.1.*, 3.0.*, 2.8.*, 2.7.*, 2.6.*, 2.5.*, 2.4.*, 2.3.*, 2.2.*, 2.1.*, 2.0.* ] - include: - - { symfony: 7.1.*, php: 8.3, phpunit: 10.5.* } - - { symfony: 7.0.*, php: 8.2, phpunit: 10.5.* } - - { symfony: 6.4.*, php: 8.2, phpunit: 9.5.* } - - { symfony: 6.3.*, php: 8.2, phpunit: 9.5.* } - - { symfony: 6.2.*, php: 8.1, phpunit: 9.5.* } - - { symfony: 6.1.*, php: 8.1, phpunit: 9.5.* } - - { symfony: 6.0.*, php: 8.0, phpunit: 9.5.* } - - { symfony: 5.4.*, php: 7.2, phpunit: 8.3.* } - - { symfony: 5.3.*, php: 7.2, phpunit: 8.3.* } - - { symfony: 5.2.*, php: 7.2, phpunit: 8.3.* } - - { symfony: 5.1.*, php: 7.2, phpunit: 8.3.* } - - { symfony: 5.0.*, php: 7.2, phpunit: 8.3.* } - - { symfony: 4.4.*, php: 7.1, phpunit: 7.0.* } - - { symfony: 4.3.*, php: 7.1, phpunit: 7.0.* } - - { symfony: 4.2.*, php: 7.1, phpunit: 7.0.* } - - { symfony: 4.1.*, php: 7.1, phpunit: 7.0.* } - - { symfony: 4.0.*, php: 7.1, phpunit: 7.0.* } - - { symfony: 3.4.*, php: 5.5, phpunit: 4.8.36 } - - { symfony: 3.3.*, php: 5.5, phpunit: 4.8.36 } - - { symfony: 3.2.*, php: 5.5, phpunit: 4.8.36 } - - { symfony: 3.1.*, php: 5.5, phpunit: 4.8.36 } - - { symfony: 3.0.*, php: 5.5, phpunit: 4.8.36 } - - { symfony: 2.8.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.7.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.6.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.5.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.4.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.3.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.2.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.1.*, php: 5.3, phpunit: 4.8.36 } - - { symfony: 2.0.*, php: 5.3, phpunit: 4.8.36 } + php: [ 8.2 ] - name: symfony[${{ matrix.symfony }}] php[${{ matrix.php }}] - ${{ matrix.os }} + name: 🐘 PHP ${{ matrix.php }} Static Analysis steps: - - name: Checkout code + - name: 📥 Checkout Code uses: actions/checkout@v4 - - name: Setup PHP + - name: 🔧 Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} coverage: none - - name: Cache dependencies - uses: actions/cache@v3 + - name: 🚚 Cache Composer Dependencies + uses: actions/cache@v4 with: path: ~/.composer/cache - key: ${{ runner.os }}-composer-${{ hashFiles('composer.json') }} - restore-keys: ${{ runner.os }}-composer + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}- - - name: Install dependencies + - name: 📦 Install Dependencies run: | - sed -i '/\"require\": {/,/},/d; /\"require-dev\": {/,/},/d' composer.json composer config --global allow-plugins true - composer config extra.symfony.require "${{ matrix.symfony }}" + composer install - if [[ "${{ matrix.symfony }}" == "7.0.*" || "${{ matrix.symfony }}" == "7.1.*" ]]; then - composer require "symfony/config:${{ matrix.symfony }}" \ - "symfony/console:${{ matrix.symfony }}" \ - "symfony/dependency-injection:${{ matrix.symfony }}" \ - "symfony/http-kernel:${{ matrix.symfony }}" \ - "symfony/translation:${{ matrix.symfony }}" \ - "symfony/framework-bundle:${{ matrix.symfony }}" \ - "symfony/twig-bundle:${{ matrix.symfony }}" \ - "phpunit/phpunit:${{ matrix.phpunit }}" \ - "monolog/monolog" --no-interaction --no-update - else - composer require "symfony/symfony:${{ matrix.symfony }}" "phpunit/phpunit:${{ matrix.phpunit }}" "monolog/monolog" --no-interaction --no-update - fi + - name: 🧹 Run PHP CS Fixer (Code Style) + run: vendor/bin/php-cs-fixer fix --dry-run - composer update --prefer-stable --prefer-dist + - name: 🔍 Run PHPStan (Static Analysis) + run: vendor/bin/phpstan analyse - - name: Execute tests - run: vendor/bin/phpunit --configuration=phpunit-symfony.xml + - name: 🚀 Run PHPLint (Syntax Check) + run: vendor/bin/phplint - laravel-test: - runs-on: ${{ matrix.os }} + prime-test: + runs-on: ubuntu-latest strategy: fail-fast: false matrix: - os: [ubuntu-latest] - laravel: [ 11.*, 10.*, 9.*, 8.*, 7.*, 6.*, 5.8.*, 5.7.*, 5.6.*, 5.5.*, 5.4.*, 5.3.*, 5.2.*, 5.1.*, 5.0.*, 4.2.*, 4.1.*, 4.0.* ] include: - - { laravel: 11.*, testbench: 9.*, php: 8.3, phpunit: 10.5.* } - - { laravel: 11.*, testbench: 9.*, php: 8.2, phpunit: 10.5.* } - - { laravel: 10.*, testbench: 8.*, php: 8.2, phpunit: 10.2.* } - - { laravel: 9.*, testbench: 7.*, php: 8.1, phpunit: 9.5.* } - - { laravel: 8.*, testbench: 6.*, php: 7.3, phpunit: 9.3.* } - - { laravel: 7.*, testbench: 5.*, php: 7.3, phpunit: 8.4.* } - - { laravel: 6.*, testbench: 4.*, php: 7.2, phpunit: 8.3.* } - - { laravel: 5.8.*, testbench: 3.8.*, php: 7.1, phpunit: 7.5.* } - - { laravel: 5.7.*, testbench: 3.7.*, php: 7.1, phpunit: 7.0.* } - - { laravel: 5.6.*, testbench: 3.6.*, php: 7.1, phpunit: 7.0.* } - - { laravel: 5.5.*, testbench: 3.5.*, php: 7.0, phpunit: 6.0.* } - - { laravel: 5.4.*, testbench: 3.4.*, php: 5.6, phpunit: 5.7.* } - - { laravel: 5.3.*, testbench: 3.3.*, php: 5.6, phpunit: 4.8.* } - - { laravel: 5.2.*, testbench: 3.2.*, php: 5.5, phpunit: 4.8.* } - - { laravel: 5.1.*, testbench: 3.1.*, php: 5.5, phpunit: 4.8.* } - - { laravel: 5.0.*, testbench: 3.0.*, php: 5.4, phpunit: 4.8.* } - - { laravel: 4.2.*, testbench: 2.2.*, php: 5.4, phpunit: 4.8.* } - - { laravel: 4.1.*, testbench: 2.1.*, php: 5.4, phpunit: 4.8.* } - - { laravel: 4.0.*, testbench: 2.0.*, php: 5.4, phpunit: 4.8.* } + - { php: 8.4, phpunit: 10.5.* } + - { php: 8.3, phpunit: 10.5.* } + - { php: 8.2, phpunit: 10.5.* } - name: laravel[${{ matrix.laravel }}] php[${{ matrix.php }}] - ${{ matrix.os }} + name: 🐘 PHP ${{ matrix.php }} steps: - - name: Checkout code + - name: 📥 Checkout code uses: actions/checkout@v4 - - name: Setup PHP + - name: 🔧 Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + + - name: 🚚 Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}- + + - name: 📦 Install dependencies + run: | + sed -i '/"require": {/,/},/d; /"require-dev": {/,/},/d' composer.json + composer config --global allow-plugins true + composer require "phpunit/phpunit:${{ matrix.phpunit }}" "mockery/mockery" "psr/container" --no-interaction --no-update + composer update --prefer-lowest -W + + - name: ✅ Execute tests + run: vendor/bin/phpunit --testsuite prime + + symfony-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - { symfony: 7.1.*, php: 8.4, phpunit: 10.5.* } + - { symfony: 7.1.*, php: 8.3, phpunit: 10.5.* } + - { symfony: 7.0.*, php: 8.2, phpunit: 10.5.* } + + name: 🌉 Symfony ${{ matrix.symfony }} PHP ${{ matrix.php }} + + steps: + - name: 📥 Checkout code + uses: actions/checkout@v4 + + - name: 🔧 Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + + - name: 🚚 Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}- + + - name: 📦 Install dependencies + run: | + sed -i '/"require": {/,/},/d; /"require-dev": {/,/},/d' composer.json + composer config --global allow-plugins true + composer config extra.symfony.require "${{ matrix.symfony }}" + composer require "symfony/config:${{ matrix.symfony }}" "symfony/console:${{ matrix.symfony }}" "symfony/dependency-injection:${{ matrix.symfony }}" "symfony/framework-bundle:${{ matrix.symfony }}" "symfony/http-kernel:${{ matrix.symfony }}" "symfony/translation:${{ matrix.symfony }}" "symfony/twig-bundle:${{ matrix.symfony }}" "phpunit/phpunit:${{ matrix.phpunit }}" "mockery/mockery" "psr/container" "monolog/monolog" --no-interaction --no-update + composer update --prefer-lowest -W + + - name: ✅ Execute tests + run: vendor/bin/phpunit --testsuite symfony + + laravel-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - { laravel: 11.*, testbench: 9.*, php: 8.3, phpunit: 10.5.* } + - { laravel: 11.*, testbench: 9.*, php: 8.2, phpunit: 10.5.* } + + name: 🏗 Laravel ${{ matrix.laravel }} PHP ${{ matrix.php }} + + steps: + - name: 📥 Checkout code + uses: actions/checkout@v4 + + - name: 🔧 Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} extensions: fileinfo coverage: none - - name: Cache dependencies - uses: actions/cache@v3 + - name: 🚚 Cache dependencies + uses: actions/cache@v4 with: path: ~/.composer/cache - key: ${{ runner.os }}-composer-${{ hashFiles('composer.json') }} - restore-keys: ${{ runner.os }}-composer + key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + restore-keys: ${{ matrix.php }}-composer - - name: Install dependencies + - name: 📦 Install dependencies run: | sed -i '/\"require\": {/,/},/d; /\"require-dev\": {/,/},/d' composer.json composer config --global allow-plugins true composer require "laravel/framework:${{ matrix.laravel }}" "phpunit/phpunit:${{ matrix.phpunit }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update - composer update --prefer-stable --prefer-dist + composer update --prefer-lowest -W - - name: Execute tests - run: vendor/bin/phpunit --configuration=phpunit-laravel.xml + - name: ✅ Execute tests + run: vendor/bin/phpunit --testsuite laravel diff --git a/.gitignore b/.gitignore index fdcc8999..a29685c9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,22 @@ -.idea -vendor -composer.lock -.phpunit.result.cache -.phpcs-cache -.php-cs-fixer.cache - -packs/**/composer.lock -packs/**/vendor/ +.idea/ +.DS_Store +vendor/ node_modules/ -coverage/ -.phpunit.cache/ -.run/ + +.cache/php-cs-fixer/ +.cache/phpunit/ +.cache/phpstan/ +.cache/phplint/ +.cache/nx/ +.nx/ + +.php-cs-fixer.php +phpunit.xml +taskfile.yml +phpstan.neon + +lerna-debug.log +npm-debug.log + +tests/Symfony/Fixtures/project/public/vendor/ diff --git a/.ncurc b/.ncurc new file mode 100644 index 00000000..23fb70e5 --- /dev/null +++ b/.ncurc @@ -0,0 +1,4 @@ +{ + "upgrade": true, + "target": "semver" +} diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..51bafa45 --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +*.log +npm-debug.log* + +# Coverage directory used by tools like istanbul +coverage + +# Dependency directories +node_modules diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..79694963 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +ignore-workspace-root-check=true +shell-emulator=true diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..8b0beab1 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20.11.0 diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index a5b03318..92242bc4 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -1,29 +1,35 @@ - */ +declare(strict_types=1); -$header = <<<'EOF' -This file is part of the PHPFlasher package. -(c) Younes KHOUBZA -EOF; +$finder = PhpCsFixer\Finder::create() + ->in([ + __DIR__.'/src', + __DIR__.'/tests', + __DIR__.'/phpstorm', + ]) + ->append([__FILE__]) +; -$rules = array( - '@Symfony' => true, - 'header_comment' => array('header' => $header), - 'array_syntax' => array('syntax' => 'long'), - 'visibility_required' => array('elements' => array('property', 'method')), - 'ordered_class_elements' => true, -); - -$finder = new PhpCsFixer\Finder(); -$finder->in(__DIR__)->exclude(__DIR__.'/vendor'); - -$config = new PhpCsFixer\Config(); - -return $config->setFinder($finder) - ->setUsingCache(false) +return (new PhpCsFixer\Config()) ->setRiskyAllowed(true) - ->setRules($rules); + ->setRules([ + '@PSR12' => true, + 'declare_strict_types' => true, + '@PHP71Migration' => true, + '@PHPUnit75Migration:risky' => true, + '@Symfony' => true, + '@Symfony:risky' => true, + 'protected_to_private' => false, + 'native_constant_invocation' => ['strict' => false], + 'no_superfluous_phpdoc_tags' => [ + 'remove_inheritdoc' => true, + 'allow_unused_params' => true, // for future-ready params, to be replaced with https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/7377 + ], + 'modernize_strpos' => true, + 'get_class_to_class_keyword' => true, + 'nullable_type_declaration' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays', 'match', 'parameters']], + ]) + ->setFinder($finder) + ->setCacheFile('.cache/php-cs-fixer/cache.json'); diff --git a/.php-version b/.php-version new file mode 100644 index 00000000..2983cad0 --- /dev/null +++ b/.php-version @@ -0,0 +1 @@ +8.2 diff --git a/.phplint.yml b/.phplint.yml new file mode 100644 index 00000000..5073fd4e --- /dev/null +++ b/.phplint.yml @@ -0,0 +1,12 @@ +exclude: + - vendor/ + - demo/ + - docs/ + - node_modules/ + +jobs: 10 + +extensions: + - php + +cache: .cache/phplint/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..81bef90d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +pnpm-lock.yaml +pnpm-workspace.yaml + +**/node_modules +src/**/Resources/public/** +src/**/Resources/dist/** diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..40d34241 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,46 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 4, + "arrowParens": "avoid", + "jsxBracketSameLine": true, + "overrides": [ + { + "files": "*.scss", + "options": { + "parser": "scss", + "singleQuote": false, + "tabWidth": 4 + } + }, + { + "files": "*.json", + "options": { + "parser": "json", + "singleQuote": false, + "tabWidth": 4 + } + }, + { + "files": "*.{ts,tsx}", + "options": { + "parser": "typescript" + } + }, + { + "files": "*.{js,jsx}", + "options": { + "parser": "babel" + } + }, + { + "files": "*.yaml", + "options": { + "parser": "yaml", + "tabWidth": 4 + } + } + ] +} diff --git a/packs/php-pack/.github/FUNDING.yml b/.shared/.github/FUNDING.yml similarity index 51% rename from packs/php-pack/.github/FUNDING.yml rename to .shared/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/packs/php-pack/.github/FUNDING.yml +++ b/.shared/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/.shared/.github/workflows/auto_closer.yaml b/.shared/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/.shared/.github/workflows/auto_closer.yaml +++ b/.shared/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 00000000..80d44c6b --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,3 @@ +{ + "extends": ["stylelint-config-standard-scss", "stylelint-config-recess-order"] +} diff --git a/LICENSE b/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 70a05eb4..b0eba9a3 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Shining stars of our community: - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes-ennaji/) +- [Email me directly](mailto:younes.ennaji@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/bin/assets b/bin/assets deleted file mode 100755 index d4b4b1ea..00000000 --- a/bin/assets +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env php -getScripts(); - - foreach ($scripts['cdn'] as $index => $script) { - echo $script . PHP_EOL; - - $path = $plugin->getAssetsDir() . '/'. pathinfo($script, PATHINFO_BASENAME); - $content = file_get_contents($script); - file_put_contents($path, $content); - } - - $styles = $plugin->getStyles(); - - foreach ($styles['cdn'] as $index => $script) { - echo $script . PHP_EOL; - - $path = $plugin->getAssetsDir() . '/'. pathinfo($script, PATHINFO_BASENAME); - $content = file_get_contents($script); - file_put_contents($path, $content); - } -} - -echo 'DONE' . PHP_EOL; diff --git a/bin/cp b/bin/cp new file mode 100755 index 00000000..9e9961b9 --- /dev/null +++ b/bin/cp @@ -0,0 +1,35 @@ +#!/bin/bash + +# Default to the current directory if no directory is provided +dir=${1:-.} + +# Optional: A list of file extensions to filter by, e.g., "txt md". Leave empty to include all files. +extensions=($2) + +# Temporary file to store results +temp_file=$(mktemp) + +# Function to print file details (now inline within find command) +print_file_details() { + echo "File Path: $1" + echo "Contents:" + cat "$1" + echo +} + +# Finding and processing files +if [ ${#extensions[@]} -eq 0 ]; then + # If no extensions are specified, process all files + find "$dir" -type f -exec bash -c 'echo "File Path: $1"; echo "Contents:"; cat "$1"; echo' bash {} \; >> "$temp_file" +else + # Process only files with specified extensions + for ext in "${extensions[@]}"; do + find "$dir" -type f -name "*.$ext" -exec bash -c 'echo "File Path: $1"; echo "Contents:"; cat "$1"; echo' bash {} \; >> "$temp_file" + done +fi + +# Copy results to clipboard and remove the temporary file +cat "$temp_file" | pbcopy +rm "$temp_file" + +echo "Results copied to clipboard." diff --git a/bin/release b/bin/release index 1ce91d87..b7909c3b 100755 --- a/bin/release +++ b/bin/release @@ -53,13 +53,10 @@ git push origin --tags --force # Tag Repositories for REMOTE in flasher flasher-laravel flasher-symfony \ - flasher-toastr flasher-toastr-laravel flasher-toastr-symfony \ + flasher-noty flasher-noty-laravel flasher-noty-symfony \ flasher-notyf flasher-notyf-laravel flasher-notyf-symfony \ flasher-sweetalert flasher-sweetalert-laravel flasher-sweetalert-symfony \ - flasher-pnotify flasher-pnotify-laravel flasher-pnotify-symfony \ - flasher-noty flasher-noty-laravel flasher-noty-symfony \ - flasher-cli flasher-cli-laravel flasher-cli-symfony \ - laravel-pack php-pack symfony-pack + flasher-toastr flasher-toastr-laravel flasher-toastr-symfony do echo "" echo "" diff --git a/bin/split b/bin/split index ac69e3c3..81c061b9 100755 --- a/bin/split +++ b/bin/split @@ -28,21 +28,9 @@ REMOTES=( 'src/SweetAlert/Laravel:flasher-sweetalert-laravel' 'src/SweetAlert/Symfony:flasher-sweetalert-symfony' - 'src/Pnotify/Prime:flasher-pnotify' - 'src/Pnotify/Laravel:flasher-pnotify-laravel' - 'src/Pnotify/Symfony:flasher-pnotify-symfony' - 'src/Noty/Prime:flasher-noty' 'src/Noty/Laravel:flasher-noty-laravel' 'src/Noty/Symfony:flasher-noty-symfony' - - 'src/Cli/Prime:flasher-cli' - 'src/Cli/Laravel:flasher-cli-laravel' - 'src/Cli/Symfony:flasher-cli-symfony' - - 'packs/laravel-pack:laravel-pack' - 'packs/php-pack:php-pack' - 'packs/symfony-pack:symfony-pack' ) # Define a function to split and push code to a remote repository diff --git a/composer.json b/composer.json index 4b054bc3..e841d8da 100644 --- a/composer.json +++ b/composer.json @@ -1,121 +1,81 @@ { "name": "php-flasher/php-flasher", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "Elevate user engagement in Laravel and Symfony projects with PHPFlasher, a comprehensive flash messaging toolkit. This library facilitates streamlined user feedback management and supports a variety of popular notification styles including Noty, Notyf, SweetAlert, and Toastr. PHPFlasher is designed for ease of use, making it accessible to both beginners and experienced developers seeking to enhance the interactive elements of their web applications.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "require": { - "php": ">=5.3" - }, - "require-dev": { - "ext-json": "*", - "ext-mbstring": "*", - "ergebnis/composer-normalize": "^2.31", - "friendsofphp/php-cs-fixer": "^3.17", - "illuminate/routing": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0", - "illuminate/support": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0", - "livewire/livewire": "^2.12.3 || ^3.0", - "orchestra/testbench": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0", - "phpro/grumphp": "^1.16", - "phpstan/phpstan": "^1.10.16", - "phpunit/phpunit": "^10.2.1", - "symfony/config": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/console": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/dependency-injection": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/framework-bundle": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0", - "symfony/http-kernel": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/translation": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/twig-bundle": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symplify/monorepo-builder": "^11.2.3.72", - "vimeo/psalm": "^5.12" - }, - "replace": { - "php-flasher/flasher": "self.version", - "php-flasher/flasher-cli": "self.version", - "php-flasher/flasher-cli-laravel": "self.version", - "php-flasher/flasher-cli-symfony": "self.version", - "php-flasher/flasher-laravel": "self.version", - "php-flasher/flasher-noty": "self.version", - "php-flasher/flasher-noty-laravel": "self.version", - "php-flasher/flasher-noty-symfony": "self.version", - "php-flasher/flasher-notyf": "self.version", - "php-flasher/flasher-notyf-laravel": "self.version", - "php-flasher/flasher-notyf-symfony": "self.version", - "php-flasher/flasher-pnotify": "self.version", - "php-flasher/flasher-pnotify-laravel": "self.version", - "php-flasher/flasher-pnotify-symfony": "self.version", - "php-flasher/flasher-sweetalert": "self.version", - "php-flasher/flasher-sweetalert-laravel": "self.version", - "php-flasher/flasher-sweetalert-symfony": "self.version", - "php-flasher/flasher-symfony": "self.version", - "php-flasher/flasher-toastr": "self.version", - "php-flasher/flasher-toastr-laravel": "self.version", - "php-flasher/flasher-toastr-symfony": "self.version" - }, "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "ext-intl": "*" + }, + "require-dev": { + "illuminate/routing": "^11.0", + "illuminate/support": "^11.0", + "larastan/larastan": "^2.9.2", + "laravel/octane": "^2.3", + "livewire/livewire": "^3.3", + "mockery/mockery": "^1.6.10", + "orchestra/testbench": "^9.0.1", + "overtrue/phplint": "^9.1.2", + "php-cs-fixer/shim": "^3.52.1", + "phpstan/phpstan": "^1.10.63", + "phpstan/phpstan-mockery": "^1.1.2", + "phpstan/phpstan-symfony": "^1.3.9", + "phpunit/phpunit": "^10.5.13", + "psr/container": "^1.1|^2.0", + "rector/rector": "^1.0.3", + "rector/swiss-knife": "^0.2.2", + "symfony/config": "^7.0", + "symfony/console": "^7.0", + "symfony/dependency-injection": "^7.0", + "symfony/framework-bundle": "^7.0", + "symfony/http-kernel": "^7.0", + "symfony/translation": "^7.0", + "symfony/twig-bundle": "^7.0", + "symfony/ux-twig-component": "^2.14", + "symplify/monorepo-builder": "^11.2" + }, "autoload": { "psr-4": { - "Flasher\\": "src/", - "Flasher\\Cli\\Laravel\\": "src/Cli/Laravel/", - "Flasher\\Cli\\Prime\\": "src/Cli/Prime/", - "Flasher\\Cli\\Symfony\\": "src/Cli/Symfony/", - "Flasher\\Laravel\\": "src/Laravel/", - "Flasher\\Noty\\Laravel\\": "src/Noty/Laravel/", - "Flasher\\Noty\\Prime\\": "src/Noty/Prime/", - "Flasher\\Noty\\Symfony\\": "src/Noty/Symfony/", - "Flasher\\Notyf\\Laravel\\": "src/Notyf/Laravel/", - "Flasher\\Notyf\\Prime\\": "src/Notyf/Prime/", - "Flasher\\Notyf\\Symfony\\": "src/Notyf/Symfony/", - "Flasher\\Pnotify\\Laravel\\": "src/Pnotify/Laravel/", - "Flasher\\Pnotify\\Prime\\": "src/Pnotify/Prime/", - "Flasher\\Pnotify\\Symfony\\": "src/Pnotify/Symfony/", - "Flasher\\Prime\\": "src/Prime/", - "Flasher\\SweetAlert\\Laravel\\": "src/SweetAlert/Laravel/", - "Flasher\\SweetAlert\\Prime\\": "src/SweetAlert/Prime/", - "Flasher\\SweetAlert\\Symfony\\": "src/SweetAlert/Symfony/", - "Flasher\\Symfony\\": "src/Symfony/", - "Flasher\\Toastr\\Laravel\\": "src/Toastr/Laravel/", - "Flasher\\Toastr\\Prime\\": "src/Toastr/Prime/", - "Flasher\\Toastr\\Symfony\\": "src/Toastr/Symfony/" + "Flasher\\": "src/" }, "files": [ - "src/Cli/Prime/helpers.php", - "src/Noty/Prime/helpers.php", - "src/Notyf/Prime/helpers.php", - "src/Pnotify/Prime/helpers.php", + "src/Prime/functions.php", "src/Prime/helpers.php", + "src/Noty/Prime/functions.php", + "src/Noty/Prime/helpers.php", + "src/Notyf/Prime/functions.php", + "src/Notyf/Prime/helpers.php", + "src/SweetAlert/Prime/functions.php", "src/SweetAlert/Prime/helpers.php", + "src/Toastr/Prime/functions.php", "src/Toastr/Prime/helpers.php" ] }, @@ -125,40 +85,30 @@ } }, "config": { - "allow-plugins": { - "ergebnis/composer-normalize": true, - "kylekatarnls/update-helper": true, - "phpro/grumphp": true - }, "preferred-install": "dist", "sort-packages": true }, "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, "laravel": { - "aliases": { - "Flasher": "Flasher\\Laravel\\Facade\\Flasher", - "Noty": "Flasher\\Laravel\\Facade\\Flasher", - "Notyf": "Flasher\\Notyf\\Laravel\\Facade\\Notyf", - "Pnotify": "Flasher\\Pnotify\\Laravel\\Facade\\Pnotify", - "SweetAlert": "Flasher\\SweetAlert\\Laravel\\Facade\\SweetAlert", - "Toastr": "Flasher\\Toastr\\Laravel\\Facade\\Toastr" - }, "providers": [ - "Flasher\\Cli\\Laravel\\FlasherCliServiceProvider", - "Flasher\\Toastr\\Laravel\\FlasherToastrServiceProvider", "Flasher\\Laravel\\FlasherServiceProvider", "Flasher\\Noty\\Laravel\\FlasherNotyServiceProvider", - "Flasher\\Pnotify\\Laravel\\FlasherPnotifyServiceProvider", "Flasher\\Notyf\\Laravel\\FlasherNotyfServiceProvider", - "Flasher\\SweetAlert\\Laravel\\FlasherSweetAlertServiceProvider" - ] + "Flasher\\SweetAlert\\Laravel\\FlasherSweetAlertServiceProvider", + "Flasher\\Toastr\\Laravel\\FlasherToastrServiceProvider" + ], + "aliases": { + "Flasher": "Flasher\\Laravel\\Facade\\Flasher", + "Noty": "Flasher\\Noty\\Laravel\\Facade\\Noty", + "Notyf": "Flasher\\Notyf\\Laravel\\Facade\\Notyf", + "SweetAlert": "Flasher\\SweetAlert\\Laravel\\Facade\\SweetAlert", + "Toastr": "Flasher\\Toastr\\Laravel\\Facade\\Toastr" + } } - }, - "scripts": { - "check-syntax": "test `find ./src -iname \"*.php\" | xargs -n1 -P6 php -l | grep -Fv \"No syntax errors\" | wc -l` -eq 0", - "lint": "git diff --staged | php ./vendor/bin/grumphp run", - "normalize-composer": "find src -name \"composer.json\" -exec composer normalize {} \\;", - "normalize-packs": "find packs -name \"composer.json\" -exec composer normalize {} \\;", - "validate-composer": "find src -name \"composer.json\" -exec composer validate --strict {} \\;" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..089a81d5 --- /dev/null +++ b/composer.lock @@ -0,0 +1,10755 @@ +{ + "_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": "ca255ba6b69a66b542d306bca711b866", + "packages": [], + "packages-dev": [ + { + "name": "brick/math", + "version": "0.9.3", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.9.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.9.3" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" + } + ], + "time": "2021-08-15T20:50:18+00:00" + }, + { + "name": "carbonphp/carbon-doctrine-types", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "3c430083d0b41ceed84ecccf9dac613241d7305d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/3c430083d0b41ceed84ecccf9dac613241d7305d", + "reference": "3c430083d0b41ceed84ecccf9dac613241d7305d", + "shasum": "" + }, + "require": { + "php": "^7.1.8 || ^8.0" + }, + "conflict": { + "doctrine/dbal": ">=3.7.0" + }, + "require-dev": { + "doctrine/dbal": ">=2.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/1.0.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2023-10-01T12:35:29+00:00" + }, + { + "name": "composer/semver", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3426bd5efa8a12d230824536c42a8a4ad30b7940" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3426bd5efa8a12d230824536c42a8a4ad30b7940", + "reference": "3426bd5efa8a12d230824536c42a8a4ad30b7940", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.19", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-05-26T18:22:04+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" + }, + "time": "2021-08-13T13:06:58+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", + "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "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" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.5" + }, + "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%2Finflector", + "type": "tidelift" + } + ], + "time": "2022-09-07T09:01:28+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "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": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.1" + }, + "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%2Flexer", + "type": "tidelift" + } + ], + "time": "2020-05-25T17:44:05+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8", + "reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-09-10T18:51:20+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f88dcf4b14af14a98ad96b14b2b317969eab6715", + "reference": "f88dcf4b14af14a98ad96b14b2b317969eab6715", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2022-06-18T20:57:19+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", + "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "v1.21-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.23.0" + }, + "time": "2023-06-12T08:44:38+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2023-10-12T05:21:21+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "84afea85c6841deeea872f36249a206e878a5de0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/84afea85c6841deeea872f36249a206e878a5de0", + "reference": "84afea85c6841deeea872f36249a206e878a5de0", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "phpoption/phpoption": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2021-08-28T21:34:50+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1110f66a6530a40fe7aea0378fe608ee2b2248f9", + "reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-08-27T10:20:53+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-05-21T12:31:43+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-04-17T16:00:37+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "88fcf8a3ea7489a8af6b25c9dfd3f688ddb51966" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/88fcf8a3ea7489a8af6b25c9dfd3f688ddb51966", + "reference": "88fcf8a3ea7489a8af6b25c9dfd3f688ddb51966", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.19 || ^9.5.8", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos", + "role": "Developer" + } + ], + "description": "A polyfill class for uri_template of PHP", + "homepage": "https://github.com/guzzlehttp/uri-template", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2021-08-14T22:34:51+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "laminas/laminas-diactoros", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-diactoros.git", + "reference": "2515f4134258b1b418c23cb86606b8a09dd01aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/2515f4134258b1b418c23cb86606b8a09dd01aea", + "reference": "2515f4134258b1b418c23cb86606b8a09dd01aea", + "shasum": "" + }, + "require": { + "php": "~8.0.0 || ~8.1.0 || ~8.2.0", + "psr/http-factory": "^1.0.2", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.1 || ^2.0", + "psr/http-message-implementation": "^1.1 || ^2.0" + }, + "require-dev": { + "ext-curl": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-libxml": "*", + "http-interop/http-factory-tests": "^0.9.0", + "laminas/laminas-coding-standard": "~2.5.0", + "php-http/psr7-integration-tests": "^1.3", + "phpunit/phpunit": "^9.5.28", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.9" + }, + "type": "library", + "extra": { + "laminas": { + "config-provider": "Laminas\\Diactoros\\ConfigProvider", + "module": "Laminas\\Diactoros" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php" + ], + "psr-4": { + "Laminas\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "http", + "laminas", + "psr", + "psr-17", + "psr-7" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-diactoros/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-diactoros/issues", + "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", + "source": "https://github.com/laminas/laminas-diactoros" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2023-05-04T21:18:23+00:00" + }, + { + "name": "larastan/larastan", + "version": "v2.9.2", + "source": { + "type": "git", + "url": "https://github.com/larastan/larastan.git", + "reference": "a79b46b96060504b400890674b83f66aa7f5db6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/larastan/larastan/zipball/a79b46b96060504b400890674b83f66aa7f5db6d", + "reference": "a79b46b96060504b400890674b83f66aa7f5db6d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/container": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/contracts": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/database": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/http": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/pipeline": "^9.52.16 || ^10.28.0 || ^11.0", + "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.0", + "php": "^8.0.2", + "phpmyadmin/sql-parser": "^5.8.2", + "phpstan/phpstan": "^1.10.50" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0", + "nikic/php-parser": "^4.17.1", + "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.0", + "orchestra/testbench": "^7.33.0 || ^8.13.0 || ^9.0.0", + "phpunit/phpunit": "^9.6.13 || ^10.5" + }, + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Larastan\\Larastan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Can Vural", + "email": "can9119@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/larastan/larastan/issues", + "source": "https://github.com/larastan/larastan/tree/v2.9.2" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/canvural", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-02-27T03:16:03+00:00" + }, + { + "name": "laravel/framework", + "version": "v11.0.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "efead50a4470068abe47f56e3488a08158039dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/efead50a4470068abe47f56e3488a08158039dc3", + "reference": "efead50a4470068abe47f56e3488a08158039dc3", + "shasum": "" + }, + "require": { + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.3.2", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.1.15", + "laravel/serializable-closure": "^1.3", + "league/commonmark": "^2.2.1", + "league/flysystem": "^3.8.0", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^2.72.2|^3.0", + "nunomaduro/termwind": "^2.0", + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^7.0", + "symfony/error-handler": "^7.0", + "symfony/finder": "^7.0", + "symfony/http-foundation": "^7.0", + "symfony/http-kernel": "^7.0", + "symfony/mailer": "^7.0", + "symfony/mime": "^7.0", + "symfony/polyfill-php83": "^1.28", + "symfony/process": "^7.0", + "symfony/routing": "^7.0", + "symfony/uid": "^7.0", + "symfony/var-dumper": "^7.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "mockery/mockery": "1.6.8", + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version", + "spatie/once": "*" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.235.5", + "ext-gmp": "*", + "fakerphp/faker": "^1.23", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-path-prefixing": "^3.3", + "league/flysystem-read-only": "^3.3", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.6", + "nyholm/psr7": "^1.2", + "orchestra/testbench-core": "^9.0", + "pda/pheanstalk": "^5.0", + "phpstan/phpstan": "^1.4.7", + "phpunit/phpunit": "^10.5|^11.0", + "predis/predis": "^2.0.2", + "resend/resend-php": "^0.10.0", + "symfony/cache": "^7.0", + "symfony/http-client": "^7.0", + "symfony/psr-http-message-bridge": "^7.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", + "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", + "league/flysystem-read-only": "Required to use read-only disks (^3.3)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.6).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).", + "predis/predis": "Required to use the predis connector (^2.0.2).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-03-12T19:22:44+00:00" + }, + { + "name": "laravel/octane", + "version": "v2.3.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/octane.git", + "reference": "ddb5e7fe33fe7aff24c61d262d7d9dc00918888f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/octane/zipball/ddb5e7fe33fe7aff24c61d262d7d9dc00918888f", + "reference": "ddb5e7fe33fe7aff24c61d262d7d9dc00918888f", + "shasum": "" + }, + "require": { + "laminas/laminas-diactoros": "^3.0", + "laravel/framework": "^10.10.1|^11.0", + "laravel/serializable-closure": "^1.3.0", + "nesbot/carbon": "^2.66.0|^3.0", + "php": "^8.1.0", + "symfony/psr-http-message-bridge": "^2.2.0|^6.4|^7.0" + }, + "conflict": { + "spiral/roadrunner": "<2023.1.0", + "spiral/roadrunner-cli": "<2.6.0", + "spiral/roadrunner-http": "<3.3.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.6.1", + "inertiajs/inertia-laravel": "^0.6.9|^1.0", + "laravel/scout": "^10.2.1", + "laravel/socialite": "^5.6.1", + "livewire/livewire": "^2.12.3|^3.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/collision": "^6.4.0|^7.5.2|^8.0", + "orchestra/testbench": "^8.5.2|^9.0", + "phpstan/phpstan": "^1.10.15", + "phpunit/phpunit": "^10.4", + "spiral/roadrunner-cli": "^2.6.0", + "spiral/roadrunner-http": "^3.3.0" + }, + "bin": [ + "bin/roadrunner-worker", + "bin/swoole-server" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Octane\\OctaneServiceProvider" + ], + "aliases": { + "Octane": "Laravel\\Octane\\Facades\\Octane" + } + } + }, + "autoload": { + "psr-4": { + "Laravel\\Octane\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Supercharge your Laravel application's performance.", + "keywords": [ + "frankenphp", + "laravel", + "octane", + "roadrunner", + "swoole" + ], + "support": { + "issues": "https://github.com/laravel/octane/issues", + "source": "https://github.com/laravel/octane" + }, + "time": "2024-01-30T03:05:25+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.1.15", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "d814a27514d99b03c85aa42b22cfd946568636c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/d814a27514d99b03c85aa42b22cfd946568636c1", + "reference": "d814a27514d99b03c85aa42b22cfd946568636c1", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.15" + }, + "time": "2023-12-29T22:37:42+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", + "reference": "f23fe9d4e95255dacee1bf3525e0810d1a1b0f37", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2023-01-30T18:31:20+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.9.0" + }, + "time": "2024-01-04T16:10:04+00:00" + }, + { + "name": "league/commonmark", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a", + "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4", + "phpstan/phpstan": "^0.12.88 || ^1.0.0", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2022-01-25T14:37:33+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" + }, + { + "name": "league/flysystem", + "version": "3.8.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "3d2ed6215e096e900662bd8f993fc5ad81cc4135" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3d2ed6215e096e900662bd8f993fc5ad81cc4135", + "reference": "3d2ed6215e096e900662bd8f993fc5ad81cc4135", + "shasum": "" + }, + "require": { + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5", + "async-aws/simple-s3": "^1.0", + "aws/aws-sdk-php": "^3.198.1", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^3.0.14", + "phpstan/phpstan": "^0.12.26", + "phpunit/phpunit": "^9.5.11", + "sabre/dav": "^4.3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.8.0" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-10-18T06:54:34+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69", + "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2021-11-21T11:48:40+00:00" + }, + { + "name": "livewire/livewire", + "version": "v3.3.5", + "source": { + "type": "git", + "url": "https://github.com/livewire/livewire.git", + "reference": "1ef880fbcdc7b6e5e405cc9135a62cd5fdbcd06a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/livewire/zipball/1ef880fbcdc7b6e5e405cc9135a62cd5fdbcd06a", + "reference": "1ef880fbcdc7b6e5e405cc9135a62cd5fdbcd06a", + "shasum": "" + }, + "require": { + "illuminate/database": "^10.0|^11.0", + "illuminate/support": "^10.0|^11.0", + "illuminate/validation": "^10.0|^11.0", + "league/mime-type-detection": "^1.9", + "php": "^8.1", + "symfony/http-kernel": "^6.2|^7.0" + }, + "require-dev": { + "calebporzio/sushi": "^2.1", + "laravel/framework": "^10.0|^11.0", + "laravel/prompts": "^0.1.6", + "mockery/mockery": "^1.3.1", + "orchestra/testbench": "^8.0|^9.0", + "orchestra/testbench-dusk": "^8.0|^9.0", + "phpunit/phpunit": "^10.4", + "psy/psysh": "^0.11.22|^0.12" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Livewire\\LivewireServiceProvider" + ], + "aliases": { + "Livewire": "Livewire\\Livewire" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "A front-end framework for Laravel.", + "support": { + "issues": "https://github.com/livewire/livewire/issues", + "source": "https://github.com/livewire/livewire/tree/v3.3.5" + }, + "funding": [ + { + "url": "https://github.com/livewire", + "type": "github" + } + ], + "time": "2024-01-02T14:29:17+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.10", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "47065d1be1fa05def58dc14c03cf831d3884ef0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/47065d1be1fa05def58dc14c03cf831d3884ef0b", + "reference": "47065d1be1fa05def58dc14c03cf831d3884ef0b", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-03-19T16:15:45+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "60ad5183b5e5d6c9d4047e9f3072d36071dcc161" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/60ad5183b5e5d6c9d4047e9f3072d36071dcc161", + "reference": "60ad5183b5e5d6c9d4047e9f3072d36071dcc161", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.3", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^9.5.16", + "predis/predis": "^1.1", + "ruflin/elastica": "^7", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2022-05-10T10:39:55+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.x" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-06-29T13:22:24+00:00" + }, + { + "name": "nesbot/carbon", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "7ae1c6fd10d2a93a0a0f5ab8fc8be37cb0830dec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7ae1c6fd10d2a93a0a0f5ab8fc8be37cb0830dec", + "reference": "7ae1c6fd10d2a93a0a0f5ab8fc8be37cb0830dec", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "*", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3 || ^7.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.18.0", + "kylekatarnls/multi-tester": "^2.2.0", + "ondrejmirtes/better-reflection": "^6.11.0.0", + "phpmd/phpmd": "^2.13.0", + "phpstan/extension-installer": "^1.3.0", + "phpstan/phpstan": "^1.10.20", + "phpunit/phpunit": "^10.2.2", + "squizlabs/php_codesniffer": "^3.7.2" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2024-01-31T20:20:32+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "reference": "abbdbb70e0245d5f3bf77874cea1dfb0c930d06f", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.3" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.3" + }, + "time": "2022-10-13T01:24:26+00:00" + }, + { + "name": "nette/utils", + "version": "v2.5.7", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "d272f87cd6491377231702b1ccd920b6e981b713" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/d272f87cd6491377231702b1ccd920b6e981b713", + "reference": "d272f87cd6491377231702b1ccd920b6e981b713", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "files": [ + "src/loader.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v2.5.7" + }, + "time": "2020-12-13T14:12:17+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.15.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "617d0220b903895537b25791f52af4698dd19339" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/617d0220b903895537b25791f52af4698dd19339", + "reference": "617d0220b903895537b25791f52af4698dd19339", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.0" + }, + "time": "2022-09-03T19:54:32+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "e534f661e09b712e51971e2cf0f662f83116d5ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/e534f661e09b712e51971e2cf0f662f83116d5ad", + "reference": "e534f661e09b712e51971e2cf0f662f83116d5ad", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.0.1" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^2.1.0", + "illuminate/console": "^11.0.0", + "laravel/pint": "^1.13.7", + "mockery/mockery": "^1.6.6", + "pestphp/pest": "^2.28.0", + "phpstan/phpstan": "^1.10.48", + "phpstan/phpstan-strict-rules": "^1.5.2", + "symfony/var-dumper": "^7.0.0", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2023-12-08T16:23:40+00:00" + }, + { + "name": "orchestra/canvas", + "version": "v9.0.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/canvas.git", + "reference": "c0c62745ffe8d1295bcdb6c9fc8aad4f0c5927b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/canvas/zipball/c0c62745ffe8d1295bcdb6c9fc8aad4f0c5927b2", + "reference": "c0c62745ffe8d1295bcdb6c9fc8aad4f0c5927b2", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "composer/semver": "^3.0", + "illuminate/console": "^11.0", + "illuminate/database": "^11.0", + "illuminate/filesystem": "^11.0", + "illuminate/support": "^11.0", + "orchestra/canvas-core": "^9.0", + "orchestra/testbench-core": "^9.0", + "php": "^8.2", + "symfony/polyfill-php83": "^1.28", + "symfony/yaml": "^7.0" + }, + "require-dev": { + "laravel/framework": "^11.0", + "laravel/pint": "^1.6", + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^1.10.6", + "phpunit/phpunit": "^10.5", + "spatie/laravel-ray": "^1.35" + }, + "bin": [ + "canvas" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.0-dev" + }, + "laravel": { + "providers": [ + "Orchestra\\Canvas\\LaravelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Orchestra\\Canvas\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Code Generators for Laravel Applications and Packages", + "support": { + "issues": "https://github.com/orchestral/canvas/issues", + "source": "https://github.com/orchestral/canvas/tree/v9.0.0" + }, + "time": "2024-03-12T14:13:22+00:00" + }, + { + "name": "orchestra/canvas-core", + "version": "v9.0.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/canvas-core.git", + "reference": "3a29eecf324fe02e3e5628e422314b5cd1a80e48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/canvas-core/zipball/3a29eecf324fe02e3e5628e422314b5cd1a80e48", + "reference": "3a29eecf324fe02e3e5628e422314b5cd1a80e48", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "composer/semver": "^3.0", + "illuminate/console": "^11.0", + "illuminate/filesystem": "^11.0", + "php": "^8.2", + "symfony/polyfill-php83": "^1.28" + }, + "require-dev": { + "laravel/framework": "^11.0", + "laravel/pint": "^1.6", + "mockery/mockery": "^1.5.1", + "orchestra/testbench-core": "^9.0", + "phpstan/phpstan": "^1.10.6", + "phpunit/phpunit": "^10.1", + "symfony/yaml": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.0-dev" + }, + "laravel": { + "providers": [ + "Orchestra\\Canvas\\Core\\LaravelServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Orchestra\\Canvas\\Core\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Code Generators Builder for Laravel Applications and Packages", + "support": { + "issues": "https://github.com/orchestral/canvas/issues", + "source": "https://github.com/orchestral/canvas-core/tree/v9.0.0" + }, + "time": "2024-03-06T10:00:21+00:00" + }, + { + "name": "orchestra/testbench", + "version": "v9.0.1", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench.git", + "reference": "30640d88b173f9ab44341a282260993f454ed187" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/30640d88b173f9ab44341a282260993f454ed187", + "reference": "30640d88b173f9ab44341a282260993f454ed187", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "fakerphp/faker": "^1.23", + "laravel/framework": "^11.0", + "mockery/mockery": "^1.6", + "orchestra/testbench-core": "^9.0.6", + "orchestra/workbench": "^9.0", + "php": "^8.2", + "phpunit/phpunit": "^10.5 || ^11.0.1", + "symfony/process": "^7.0", + "symfony/yaml": "^7.0", + "vlucas/phpdotenv": "^5.4.1" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Laravel Testing Helper for Packages Development", + "homepage": "https://packages.tools/testbench/", + "keywords": [ + "BDD", + "TDD", + "dev", + "laravel", + "laravel-packages", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/testbench/issues", + "source": "https://github.com/orchestral/testbench/tree/v9.0.1" + }, + "time": "2024-03-19T13:04:45+00:00" + }, + { + "name": "orchestra/testbench-core", + "version": "v9.0.6", + "source": { + "type": "git", + "url": "https://github.com/orchestral/testbench-core.git", + "reference": "ea532af82da288d363b7dc7c96edae6bbb329efe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/ea532af82da288d363b7dc7c96edae6bbb329efe", + "reference": "ea532af82da288d363b7dc7c96edae6bbb329efe", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "php": "^8.2", + "symfony/polyfill-php83": "^1.28" + }, + "conflict": { + "brianium/paratest": "<7.3.0 || >=8.0.0", + "laravel/framework": "<11.0.3 || >=12.0.0", + "nunomaduro/collision": "<8.0.0 || >=9.0.0", + "phpunit/phpunit": "<10.5.0 || 11.0.0 || >=11.1.0" + }, + "require-dev": { + "fakerphp/faker": "^1.23", + "laravel/framework": "^11.0.3", + "laravel/pint": "^1.6", + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^1.10.50", + "phpunit/phpunit": "^10.5 || ^11.0.1", + "spatie/laravel-ray": "^1.35", + "symfony/process": "^7.0", + "symfony/yaml": "^7.0", + "vlucas/phpdotenv": "^5.4.1" + }, + "suggest": { + "brianium/paratest": "Allow using parallel tresting (^7.3).", + "ext-pcntl": "Required to use all features of the console signal trapping.", + "fakerphp/faker": "Allow using Faker for testing (^1.23).", + "laravel/framework": "Required for testing (^11.0.3).", + "mockery/mockery": "Allow using Mockery for testing (^1.6).", + "nunomaduro/collision": "Allow using Laravel style tests output and parallel testing (^8.0).", + "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^9.0).", + "phpunit/phpunit": "Allow using PHPUnit for testing (^10.5).", + "symfony/process": "Required to use Orchestra\\Testbench\\remote function (^7.0).", + "symfony/yaml": "Required for Testbench CLI (^7.0).", + "vlucas/phpdotenv": "Required for Testbench CLI (^5.4.1)." + }, + "bin": [ + "testbench" + ], + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Orchestra\\Testbench\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com", + "homepage": "https://github.com/crynobone" + } + ], + "description": "Testing Helper for Laravel Development", + "homepage": "https://packages.tools/testbench", + "keywords": [ + "BDD", + "TDD", + "dev", + "laravel", + "laravel-packages", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/testbench/issues", + "source": "https://github.com/orchestral/testbench-core" + }, + "time": "2024-03-19T11:20:27+00:00" + }, + { + "name": "orchestra/workbench", + "version": "v9.0.0", + "source": { + "type": "git", + "url": "https://github.com/orchestral/workbench.git", + "reference": "979ebf99e4167b68446a4b60f5fcab9521d209cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/orchestral/workbench/zipball/979ebf99e4167b68446a4b60f5fcab9521d209cd", + "reference": "979ebf99e4167b68446a4b60f5fcab9521d209cd", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "fakerphp/faker": "^1.23", + "laravel/framework": "^11.0", + "laravel/tinker": "^2.9", + "orchestra/canvas": "^9.0", + "orchestra/testbench-core": "^9.0", + "php": "^8.1", + "spatie/laravel-ray": "^1.35", + "symfony/polyfill-php83": "^1.28", + "symfony/yaml": "^7.0" + }, + "require-dev": { + "laravel/pint": "^1.6", + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^1.10.50", + "phpunit/phpunit": "^10.5 || ^11.0", + "symfony/process": "^7.0" + }, + "suggest": { + "ext-pcntl": "Required to use all features of the console signal trapping." + }, + "type": "library", + "autoload": { + "psr-4": { + "Orchestra\\Workbench\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mior Muhammad Zaki", + "email": "crynobone@gmail.com" + } + ], + "description": "Workbench Companion for Laravel Packages Development", + "keywords": [ + "dev", + "laravel", + "laravel-packages", + "testing" + ], + "support": { + "issues": "https://github.com/orchestral/workbench/issues", + "source": "https://github.com/orchestral/workbench/tree/v9.0.0" + }, + "time": "2024-03-13T06:19:29+00:00" + }, + { + "name": "overtrue/phplint", + "version": "9.1.2", + "source": { + "type": "git", + "url": "https://github.com/overtrue/phplint.git", + "reference": "7a9822c863d19fa8ec42f862c0e135da58b5cb4b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/overtrue/phplint/zipball/7a9822c863d19fa8ec42f862c0e135da58b5cb4b", + "reference": "7a9822c863d19fa8ec42f862c0e135da58b5cb4b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.1", + "symfony/cache": "^6.4 || ^7.0", + "symfony/console": "^6.4 || ^7.0", + "symfony/event-dispatcher": "^6.4 || ^7.0", + "symfony/finder": "^6.4 || ^7.0", + "symfony/options-resolver": "^6.4 || ^7.0", + "symfony/process": "^6.4 || ^7.0", + "symfony/yaml": "^6.4 || ^7.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4", + "brainmaestro/composer-git-hooks": "^2.8.5 || 3.0.0-alpha.1", + "jetbrains/phpstorm-stubs": "^2021.3 || ^2022.3 || ^2023.3", + "php-parallel-lint/php-console-highlighter": "^1.0" + }, + "bin": [ + "bin/phplint" + ], + "type": "library", + "extra": { + "hooks": { + "pre-commit": [ + "composer style:fix", + "composer code:check" + ], + "pre-push": [ + "composer qa:check" + ] + }, + "branch-alias": { + "dev-main": "9.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Overtrue\\PHPLint\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "overtrue", + "email": "anzhengchao@gmail.com" + }, + { + "name": "Laurent Laville", + "homepage": "https://github.com/llaville" + } + ], + "description": "`phplint` is a tool that can speed up linting of php files by running several lint processes at once.", + "keywords": [ + "check", + "lint", + "phplint", + "static analysis", + "syntax" + ], + "support": { + "issues": "https://github.com/overtrue/phplint/issues", + "source": "https://github.com/overtrue/phplint/tree/9.1.2" + }, + "funding": [ + { + "url": "https://github.com/overtrue", + "type": "github" + } + ], + "time": "2024-02-06T10:43:30+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "a1d9f267eb8b8ad560e54e397a5ed1e3b78097d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a1d9f267eb8b8ad560e54e397a5ed1e3b78097d1", + "reference": "a1d9f267eb8b8ad560e54e397a5ed1e3b78097d1", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2015-09-07T01:49:23+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", + "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/master" + }, + "time": "2020-06-27T14:39:04+00:00" + }, + { + "name": "php-cs-fixer/shim", + "version": "v3.52.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/shim.git", + "reference": "baec5a6d4b24bad4c930d39fde34b2b0c1c8cd94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/shim/zipball/baec5a6d4b24bad4c930d39fde34b2b0c1c8cd94", + "reference": "baec5a6d4b24bad4c930d39fde34b2b0c1c8cd94", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "replace": { + "friendsofphp/php-cs-fixer": "self.version" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer", + "php-cs-fixer.phar" + ], + "type": "application", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/PHP-CS-Fixer/shim/issues", + "source": "https://github.com/PHP-CS-Fixer/shim/tree/v3.52.1" + }, + "time": "2024-03-19T21:03:12+00:00" + }, + { + "name": "phpmyadmin/sql-parser", + "version": "5.8.2", + "source": { + "type": "git", + "url": "https://github.com/phpmyadmin/sql-parser.git", + "reference": "f1720ae19abe6294cb5599594a8a57bc3c8cc287" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/f1720ae19abe6294cb5599594a8a57bc3c8cc287", + "reference": "f1720ae19abe6294cb5599594a8a57bc3c8cc287", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "phpmyadmin/motranslator": "<3.0" + }, + "require-dev": { + "phpbench/phpbench": "^1.1", + "phpmyadmin/coding-standard": "^3.0", + "phpmyadmin/motranslator": "^4.0 || ^5.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.9.12", + "phpstan/phpstan-phpunit": "^1.3.3", + "phpunit/php-code-coverage": "*", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.16.1", + "vimeo/psalm": "^4.11", + "zumba/json-serializer": "~3.0.2" + }, + "suggest": { + "ext-mbstring": "For best performance", + "phpmyadmin/motranslator": "Translate messages to your favorite locale" + }, + "bin": [ + "bin/highlight-query", + "bin/lint-query", + "bin/tokenize-query" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpMyAdmin\\SqlParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "The phpMyAdmin Team", + "email": "developers@phpmyadmin.net", + "homepage": "https://www.phpmyadmin.net/team/" + } + ], + "description": "A validating SQL lexer and parser with a focus on MySQL dialect.", + "homepage": "https://github.com/phpmyadmin/sql-parser", + "keywords": [ + "analysis", + "lexer", + "parser", + "query linter", + "sql", + "sql lexer", + "sql linter", + "sql parser", + "sql syntax highlighter", + "sql tokenizer" + ], + "support": { + "issues": "https://github.com/phpmyadmin/sql-parser/issues", + "source": "https://github.com/phpmyadmin/sql-parser" + }, + "funding": [ + { + "url": "https://www.phpmyadmin.net/donate/", + "type": "other" + } + ], + "time": "2023-09-19T12:34:29+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "5455cb38aed4523f99977c4a12ef19da4bfe2a28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/5455cb38aed4523f99977c4a12ef19da4bfe2a28", + "reference": "5455cb38aed4523f99977c4a12ef19da4bfe2a28", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "phpunit/phpunit": "^6.5.14 || ^7.0.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2021-08-28T21:27:29+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.63", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "ad12836d9ca227301f5fb9960979574ed8628339" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ad12836d9ca227301f5fb9960979574ed8628339", + "reference": "ad12836d9ca227301f5fb9960979574ed8628339", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2024-03-18T16:53:53+00:00" + }, + { + "name": "phpstan/phpstan-mockery", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-mockery.git", + "reference": "88ae85931768efd3aaf3cce4cb9cb54c4d157d03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-mockery/zipball/88ae85931768efd3aaf3cce4cb9cb54c4d157d03", + "reference": "88ae85931768efd3aaf3cce4cb9cb54c4d157d03", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10" + }, + "require-dev": { + "mockery/mockery": "^1.2.4", + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan Mockery extension", + "support": { + "issues": "https://github.com/phpstan/phpstan-mockery/issues", + "source": "https://github.com/phpstan/phpstan-mockery/tree/1.1.2" + }, + "time": "2024-01-10T13:50:05+00:00" + }, + { + "name": "phpstan/phpstan-symfony", + "version": "1.3.9", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-symfony.git", + "reference": "a32bc86da24495025d7aafd1ba62444d4a364a98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/a32bc86da24495025d7aafd1ba62444d4a364a98", + "reference": "a32bc86da24495025d7aafd1ba62444d4a364a98", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10.62" + }, + "conflict": { + "symfony/framework-bundle": "<3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.3.11", + "phpstan/phpstan-strict-rules": "^1.5.1", + "phpunit/phpunit": "^8.5.29 || ^9.5", + "psr/container": "1.0 || 1.1.1", + "symfony/config": "^5.4 || ^6.1", + "symfony/console": "^5.4 || ^6.1", + "symfony/dependency-injection": "^5.4 || ^6.1", + "symfony/form": "^5.4 || ^6.1", + "symfony/framework-bundle": "^5.4 || ^6.1", + "symfony/http-foundation": "^5.4 || ^6.1", + "symfony/messenger": "^5.4", + "symfony/polyfill-php80": "^1.24", + "symfony/serializer": "^5.4", + "symfony/service-contracts": "^2.2.0" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukáš Unger", + "email": "looky.msc@gmail.com", + "homepage": "https://lookyman.net" + } + ], + "description": "Symfony Framework extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-symfony/issues", + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.3.9" + }, + "time": "2024-03-16T16:50:20+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "1df504e42a88044c27a90136910f0b3fe9e91939" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1df504e42a88044c27a90136910f0b3fe9e91939", + "reference": "1df504e42a88044c27a90136910f0b3fe9e91939", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.15", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-12T14:37:22+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "7d66d4e816d34e90acec9db9d8d94b5cfbfe926f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/7d66d4e816d34e90acec9db9d8d94b5cfbfe926f", + "reference": "7d66d4e816d34e90acec9db9d8d94b5cfbfe926f", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:55:11+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "9f3d3709577a527025f55bcf0f7ab8052c8bb37d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/9f3d3709577a527025f55bcf0f7ab8052c8bb37d", + "reference": "9f3d3709577a527025f55bcf0f7ab8052c8bb37d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:46+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.13", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "20a63fc1c6db29b15da3bd02d4b6cf59900088a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/20a63fc1c6db29b15da3bd02d4b6cf59900088a7", + "reference": "20a63fc1c6db29b15da3bd02d4b6cf59900088a7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.13" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-03-12T15:37:41+00:00" + }, + { + "name": "psr/cache", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/2.0.0" + }, + "time": "2021-02-03T23:23:37+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "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/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+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": "psr/simple-cache", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/753fa598e8f3b9966c886fe13f370baa45ef0e24", + "reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/1.0.0" + }, + "time": "2017-01-02T13:31:39+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.12.0", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/750bf031a48fd07c673dbe3f11f72362ea306d0d", + "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.12.x-dev" + }, + "bamarni-bin": { + "bin-links": false, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.0" + }, + "time": "2023-12-20T15:28:09+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/2.0.5" + }, + "time": "2016-02-11T07:05:27+00:00" + }, + { + "name": "ramsey/collection", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "4d85fbcd9d2fb1cfd6f81b2f00e687b1c6056b3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/4d85fbcd9d2fb1cfd6f81b2f00e687b1c6056b3a", + "reference": "4d85fbcd9d2fb1cfd6f81b2f00e687b1c6056b3a", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" + }, + "require-dev": { + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP 7.2+ library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-08-05T14:54:37+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.7.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "5ed9ad582647bbc3864ef78db34bdc1afdcf9b49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5ed9ad582647bbc3864ef78db34bdc1afdcf9b49", + "reference": "5ed9ad582647bbc3864ef78db34bdc1afdcf9b49", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2022-12-19T22:30:49+00:00" + }, + { + "name": "rector/rector", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "c59507a9090b465d65e1aceed91e5b81986e375b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/c59507a9090b465d65e1aceed91e5b81986e375b", + "reference": "c59507a9090b465d65e1aceed91e5b81986e375b", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.57" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2024-03-14T15:04:18+00:00" + }, + { + "name": "rector/swiss-knife", + "version": "0.2.2", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/swiss-knife.git", + "reference": "125cecb26acb03b97862f1bb525194e69698d5ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/swiss-knife/zipball/125cecb26acb03b97862f1bb525194e69698d5ef", + "reference": "125cecb26acb03b97862f1bb525194e69698d5ef", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "bin": [ + "bin/swiss-knife" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Swiss knife in pocket of every upgrade architect", + "support": { + "issues": "https://github.com/rectorphp/swiss-knife/issues", + "source": "https://github.com/rectorphp/swiss-knife/tree/0.2.2" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2024-03-11T08:31:59+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", + "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:15+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/72f01e6586e0caf6af81297897bd112eb7e9627c", + "reference": "72f01e6586e0caf6af81297897bd112eb7e9627c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:07:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:47+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "70dd1b20bc198da394ad542e988381b44e64e39f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/70dd1b20bc198da394ad542e988381b44e64e39f", + "reference": "70dd1b20bc198da394ad542e988381b44e64e39f", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:00:31+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "b6f3694c6386c7959915a0037652e0c40f6f69cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/b6f3694c6386c7959915a0037652e0c40f6f69cc", + "reference": "b6f3694c6386c7959915a0037652e0c40f6f69cc", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:03:04+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "c3fa8483f9539b190f7cd4bfc4a07631dd1df344" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c3fa8483f9539b190f7cd4bfc4a07631dd1df344", + "reference": "c3fa8483f9539b190f7cd4bfc4a07631dd1df344", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-09-18T07:15:37+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-07-19T07:19:23+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/17c4d940ecafb3d15d2cf916f4108f664e28b130", + "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.10", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:02+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "5facf5a20311ac44f79221274cdeb6c569ca11dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/5facf5a20311ac44f79221274cdeb6c569ca11dd", + "reference": "5facf5a20311ac44f79221274cdeb6c569ca11dd", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:11:37+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "3440fe023a7d5b4497090fb6b2dcdc747daf7873" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/3440fe023a7d5b4497090fb6b2dcdc747daf7873", + "reference": "3440fe023a7d5b4497090fb6b2dcdc747daf7873", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2021-01-29T09:20:43+00:00" + }, + { + "name": "spatie/laravel-ray", + "version": "1.35.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ray.git", + "reference": "f504d3787d88c7e5de7a4290658f7ad9b1352f22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/f504d3787d88c7e5de7a4290658f7ad9b1352f22", + "reference": "f504d3787d88c7e5de7a4290658f7ad9b1352f22", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/contracts": "^7.20|^8.19|^9.0|^10.0|^11.0", + "illuminate/database": "^7.20|^8.19|^9.0|^10.0|^11.0", + "illuminate/queue": "^7.20|^8.19|^9.0|^10.0|^11.0", + "illuminate/support": "^7.20|^8.19|^9.0|^10.0|^11.0", + "php": "^7.4|^8.0", + "rector/rector": "^0.19.2|^1.0", + "spatie/backtrace": "^1.0", + "spatie/ray": "^1.41.1", + "symfony/stopwatch": "4.2|^5.1|^6.0|^7.0", + "zbateson/mail-mime-parser": "^1.3.1|^2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.3", + "laravel/framework": "^7.20|^8.19|^9.0|^10.0|^11.0", + "orchestra/testbench-core": "^5.0|^6.0|^7.0|^8.0|^9.0", + "pestphp/pest": "^1.22|^2.0", + "phpstan/phpstan": "^1.10.57", + "phpunit/phpunit": "^9.3|^10.1", + "spatie/pest-plugin-snapshots": "^1.1|^2.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.29.x-dev" + }, + "laravel": { + "providers": [ + "Spatie\\LaravelRay\\RayServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\LaravelRay\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily debug Laravel apps", + "homepage": "https://github.com/spatie/laravel-ray", + "keywords": [ + "laravel-ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-ray/issues", + "source": "https://github.com/spatie/laravel-ray/tree/1.35.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-02-13T14:19:41+00:00" + }, + { + "name": "spatie/macroable", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "7a99549fc001c925714b329220dea680c04bfa48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/7a99549fc001c925714b329220dea680c04bfa48", + "reference": "7a99549fc001c925714b329220dea680c04bfa48", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/1.0.1" + }, + "time": "2020-11-03T10:15:05+00:00" + }, + { + "name": "spatie/ray", + "version": "1.41.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/ray.git", + "reference": "051a0facb1d2462fafef87ff77eb74d6f2d12944" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ray/zipball/051a0facb1d2462fafef87ff77eb74d6f2d12944", + "reference": "051a0facb1d2462fafef87ff77eb74d6f2d12944", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": "^7.3|^8.0", + "ramsey/uuid": "^3.0|^4.1", + "spatie/backtrace": "^1.1", + "spatie/macroable": "^1.0|^2.0", + "symfony/stopwatch": "^4.0|^5.1|^6.0|^7.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0" + }, + "require-dev": { + "illuminate/support": "6.x|^8.18|^9.0", + "nesbot/carbon": "^2.63", + "pestphp/pest": "^1.22", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.19.2", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2" + }, + "bin": [ + "bin/remove-ray.sh" + ], + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Ray\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Debug with Ray to fix problems faster", + "homepage": "https://github.com/spatie/ray", + "keywords": [ + "ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/ray/issues", + "source": "https://github.com/spatie/ray/tree/1.41.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-01-25T10:15:50+00:00" + }, + { + "name": "symfony/cache", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "ac2d25f97b17eec6e19760b6b9962a4f7c44356a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/ac2d25f97b17eec6e19760b6b9962a4f7c44356a", + "reference": "ac2d25f97b17eec6e19760b6b9962a4f7c44356a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.3.6|^7.0" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "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 extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v6.4.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": "2023-11-24T19:28:07+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "ac2e168102a2e06a2624f0379bde94cd5854ced2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ac2e168102a2e06a2624f0379bde94cd5854ced2", + "reference": "ac2e168102a2e06a2624f0379bde94cd5854ced2", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "^1.0|^2.0|^3.0" + }, + "suggest": { + "symfony/cache-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\\Cache\\": "" + } + }, + "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 caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v2.5.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": "2021-08-17T14:20:01+00:00" + }, + { + "name": "symfony/clock", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "48102bcc56b26d453c7f5e7f72829abc9df25a16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/48102bcc56b26d453c7f5e7f72829abc9df25a16", + "reference": "48102bcc56b26d453c7f5e7f72829abc9df25a16", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "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": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v6.4.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": "2023-10-13T14:46:14+00:00" + }, + { + "name": "symfony/config", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/8789646600f4e7e451dde9e1dc81cfa429f3857a", + "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^6.4|^7.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "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": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v7.0.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": "2023-11-09T08:30:23+00:00" + }, + { + "name": "symfony/console", + "version": "v7.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/cdce5c684b2f920bb1343deecdfba356ffad83d5", + "reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "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/v7.0.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": "2023-12-01T15:10:06+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v2.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092", + "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v2.7.3" + }, + "time": "2015-05-15T13:33:16+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "71c053f3284a57d611e11bd7d7f1a76de8514a07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/71c053f3284a57d611e11bd7d7f1a76de8514a07", + "reference": "71c053f3284a57d611e11bd7d7f1a76de8514a07", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^3.3", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "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": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v7.0.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": "2023-11-15T15:38:56+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-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/v2.5.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": "2021-07-12T14:48:14+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "80b1258be1b84c12a345d0ec3881bbf2e5270cc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/80b1258be1b84c12a345d0ec3881bbf2e5270cc2", + "reference": "80b1258be1b84c12a345d0ec3881bbf2e5270cc2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "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 tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.0.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": "2023-10-20T16:35:23+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d76d2632cfc2206eecb5ad2b26cd5934082941b6", + "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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 tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.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": "2023-07-27T06:52:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-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\\EventDispatcher\\": "" + } + }, + "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 dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.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": "2021-07-12T14:48:14+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "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.4.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": "2023-07-26T17:27:13+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.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/v7.0.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": "2023-10-31T17:59:56+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "60ecfb67cd14b0a453d1f66c34c396325dfcad54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/60ecfb67cd14b0a453d1f66c34c396325dfcad54", + "reference": "60ecfb67cd14b0a453d1f66c34c396325dfcad54", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.2", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^6.4|^7.0" + }, + "conflict": { + "doctrine/persistence": "<1.3", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/asset": "<6.4", + "symfony/asset-mapper": "<6.4", + "symfony/clock": "<6.4", + "symfony/console": "<6.4", + "symfony/dom-crawler": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/lock": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/scheduler": "<6.4", + "symfony/security-core": "<6.4", + "symfony/security-csrf": "<6.4", + "symfony/serializer": "<6.4", + "symfony/stopwatch": "<6.4", + "symfony/translation": "<6.4", + "symfony/twig-bridge": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4", + "symfony/web-profiler-bundle": "<6.4", + "symfony/workflow": "<6.4" + }, + "require-dev": { + "doctrine/persistence": "^1.3|^2|^3", + "dragonmantank/cron-expression": "^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "seld/jsonlint": "^1.10", + "symfony/asset": "^6.4|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/mailer": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/notifier": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/scheduler": "^6.4|^7.0", + "symfony/security-bundle": "^6.4|^7.0", + "symfony/semaphore": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "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 a tight integration between Symfony components and the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/framework-bundle/tree/v7.0.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": "2023-11-26T17:09:17+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "47d72323200934694def5d57083899d774a2b110" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/47d72323200934694def5d57083899d774a2b110", + "reference": "47d72323200934694def5d57083899d774a2b110", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.0.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": "2023-11-07T15:10:37+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "cca4b041cd27960ca9fbde004673ca19aeb7c427" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cca4b041cd27960ca9fbde004673ca19aeb7c427", + "reference": "cca4b041cd27960ca9fbde004673ca19aeb7c427", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.0.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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 a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.0.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": "2023-11-29T10:55:46+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "5a0ff09429d34763a5569596b1793df1f07ac2d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/5a0ff09429d34763a5569596b1793df1f07ac2d0", + "reference": "5a0ff09429d34763a5569596b1793df1f07ac2d0", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "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": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.0.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": "2023-11-14T09:46:33+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "0a2fff95c1a10df97f571d67e76c7ae0f0d4f535" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/0a2fff95c1a10df97f571d67e76c7ae0f0d4f535", + "reference": "0a2fff95c1a10df97f571d67e76c7ae0f0d4f535", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "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": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.0.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": "2023-10-19T14:20:43+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "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 an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.4.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": "2023-08-08T10:16:24+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-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.23.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": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2", + "reference": "bcc0cd69185b8a5d8b4a5400c489ed3333bf9bb2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + } + }, + "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 Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.9.0" + }, + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "9332d285b58a16b144b3bf0bfd3b6334d9a43006" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/9332d285b58a16b144b3bf0bfd3b6334d9a43006", + "reference": "9332d285b58a16b144b3bf0bfd3b6334d9a43006", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "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/master" + }, + "time": "2015-11-04T20:28:58+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.15.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": "2020-03-09T19:04:49+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "b0235b9e98e224821e23018a9487764ad6dec859" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/b0235b9e98e224821e23018a9487764ad6dec859", + "reference": "b0235b9e98e224821e23018a9487764ad6dec859", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "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/master" + }, + "time": "2015-11-04T20:28:58+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-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.23.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": "2021-05-27T12:26:48+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "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.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/master" + }, + "time": "2018-09-21T13:07:52+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-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.23.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": "2021-07-28T13:41:28+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "e66119f3de95efc359483f810c4c3e6436279436" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", + "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "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 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.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": "2021-05-21T13:25:03+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "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 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.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": "2023-08-16T06:22:46+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "2318f7f470a892867f3de602e403d006b1b9c9aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/2318f7f470a892867f3de602e403d006b1b9c9aa", + "reference": "2318f7f470a892867f3de602e403d006b1b9c9aa", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/master" + }, + "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": "2020-03-23T13:44:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/13bdb1670c7f510494e04fcb2bfa29af63db9c0d", + "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "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/v7.0.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": "2023-11-20T16:43:42+00:00" + }, + { + "name": "symfony/property-access", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "75f6990ae8e8040dd587162f3f1863f755957129" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/75f6990ae8e8040dd587162f3f1863f755957129", + "reference": "75f6990ae8e8040dd587162f3f1863f755957129", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/property-info": "^5.4|^6.0|^7.0" + }, + "require-dev": { + "symfony/cache": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "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 functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v6.4.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": "2023-09-25T12:52:38+00:00" + }, + { + "name": "symfony/property-info", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "288be71bae2ebc88676f5d3a03d23f70b278fcc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/288be71bae2ebc88676f5d3a03d23f70b278fcc1", + "reference": "288be71bae2ebc88676f5d3a03d23f70b278fcc1", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/dependency-injection": "<5.4", + "symfony/serializer": "<6.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2", + "phpstan/phpdoc-parser": "^1.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v6.4.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": "2023-11-25T16:57:46+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "3c0a6ea372085754232b502146192c069ae2c5a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/3c0a6ea372085754232b502146192c069ae2c5a1", + "reference": "3c0a6ea372085754232b502146192c069ae2c5a1", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/http-message": "^1.0|^2.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-kernel": "<6.2" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "php-http/discovery": "^1.15", + "psr/log": "^1.1.4|^2|^3", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^6.2|^7.0", + "symfony/http-kernel": "^6.2|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v6.4.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": "2023-10-31T08:40:20+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "7426e03beb76f3637cc5a68303972666b9a91170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/7426e03beb76f3637cc5a68303972666b9a91170", + "reference": "7426e03beb76f3637cc5a68303972666b9a91170", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "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": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.0.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": "2023-11-29T08:40:23+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-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.4.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": "2023-12-26T14:02:43+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "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 a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.4.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": "2023-02-16T10:14:28+00:00" + }, + { + "name": "symfony/string", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/b45fcf399ea9c3af543a92edf7172ba21174d809", + "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809", + "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.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.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.4.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": "2023-11-28T20:41:49+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "ab5a14723f23159854bf91b41255cad23b929fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/ab5a14723f23159854bf91b41255cad23b929fab", + "reference": "ab5a14723f23159854bf91b41255cad23b929fab", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.13", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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 tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.0.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": "2023-11-29T08:40:23+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/d28150f0f44ce854e942b671fc2620a98aae1b1e", + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e", + "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.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": "2021-08-17T14:20:01+00:00" + }, + { + "name": "symfony/twig-bridge", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/twig-bridge.git", + "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", + "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/translation-contracts": "^2.5|^3", + "twig/twig": "^2.13|^3.0.4" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/console": "<5.4", + "symfony/form": "<6.3", + "symfony/http-foundation": "<5.4", + "symfony/http-kernel": "<6.4", + "symfony/mime": "<6.2", + "symfony/serializer": "<6.4", + "symfony/translation": "<5.4", + "symfony/workflow": "<5.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/asset-mapper": "^6.3|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.1|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/security-acl": "^2.8|^3.0", + "symfony/security-core": "^5.4|^6.0|^7.0", + "symfony/security-csrf": "^5.4|^6.0|^7.0", + "symfony/security-http": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^6.1|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0", + "symfony/workflow": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "twig/cssinliner-extra": "^2.12|^3", + "twig/inky-extra": "^2.12|^3", + "twig/markdown-extra": "^2.12|^3" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Twig\\": "" + }, + "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 integration for Twig with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.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": "2023-11-25T08:25:13+00:00" + }, + { + "name": "symfony/twig-bundle", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/twig-bundle.git", + "reference": "42c4a60f1b83894cd85a6b00533f8216c413ac11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/42c4a60f1b83894cd85a6b00533f8216c413ac11", + "reference": "42c4a60f1b83894cd85a6b00533f8216c413ac11", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "conflict": { + "symfony/framework-bundle": "<6.4", + "symfony/translation": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\TwigBundle\\": "" + }, + "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 a tight integration of Twig into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/twig-bundle/tree/v7.0.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": "2023-11-26T15:16:53+00:00" + }, + { + "name": "symfony/uid", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "9472fe6a4a2adcc9150106ebb9fde328828d312f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/9472fe6a4a2adcc9150106ebb9fde328828d312f", + "reference": "9472fe6a4a2adcc9150106ebb9fde328828d312f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v7.0.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": "2023-10-31T08:22:02+00:00" + }, + { + "name": "symfony/ux-twig-component", + "version": "v2.14.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-twig-component.git", + "reference": "b5f593295bd68485cedc59144d285db18ccfb776" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/b5f593295bd68485cedc59144d285db18ccfb776", + "reference": "b5f593295bd68485cedc59144d285db18ccfb776", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^2.2|^3.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "twig/twig": "^2.14.7|^3.0.4" + }, + "conflict": { + "symfony/config": "<5.4.0" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^6.0|^7.0", + "symfony/stimulus-bundle": "^2.9.1", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/webpack-encore-bundle": "^1.15" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "name": "symfony/ux", + "url": "https://github.com/symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\TwigComponent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Twig components for Symfony", + "homepage": "https://symfony.com", + "keywords": [ + "components", + "symfony-ux", + "twig" + ], + "support": { + "source": "https://github.com/symfony/ux-twig-component/tree/v2.14.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": "2024-01-30T15:40:36+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "cf0220fc7607476fd0d001ab3ed9e830d1fdda56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cf0220fc7607476fd0d001ab3ed9e830d1fdda56", + "reference": "cf0220fc7607476fd0d001ab3ed9e830d1fdda56", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "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 mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.0.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": "2023-11-27T12:39:18+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "d6081c0316f0f5921f2010d1766925005a82ea3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d6081c0316f0f5921f2010d1766925005a82ea3b", + "reference": "d6081c0316f0f5921f2010d1766925005a82ea3b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "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": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.4.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": "2023-11-28T20:41:49+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "0055b230c408428b9b5cde7c55659555be5c0278" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0055b230c408428b9b5cde7c55659555be5c0278", + "reference": "0055b230c408428b9b5cde7c55659555be5c0278", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.0.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": "2023-11-07T10:26:03+00:00" + }, + { + "name": "symplify/monorepo-builder", + "version": "11.2.0.72", + "source": { + "type": "git", + "url": "https://github.com/symplify/monorepo-builder.git", + "reference": "e252321339322af996177e360565cfcddb35c218" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/monorepo-builder/zipball/e252321339322af996177e360565cfcddb35c218", + "reference": "e252321339322af996177e360565cfcddb35c218", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "bin": [ + "bin/monorepo-builder" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.3-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Prefixed version of Not only Composer tools to build a Monorepo.", + "support": { + "issues": "https://github.com/symplify/monorepo-builder/issues", + "source": "https://github.com/symplify/monorepo-builder/tree/11.2.0.72" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2023-01-28T10:26:54+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/master" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.5", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/4348a3a06651827a27d989ad1d13efec6bb49b19", + "reference": "4348a3a06651827a27d989ad1d13efec6bb49b19", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.5" + }, + "time": "2022-09-12T13:28:28+00:00" + }, + { + "name": "twig/twig", + "version": "v3.0.4", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "582bdbdc173027ebfba3c93dc750a40b8f9ebc02" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/582bdbdc173027ebfba3c93dc750a40b8f9ebc02", + "reference": "582bdbdc173027ebfba3c93dc750a40b8f9ebc02", + "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" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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.0.4" + }, + "funding": [ + { + "url": "https://certification.symfony.com/", + "type": "custom" + }, + { + "url": "https://live.symfony.com/", + "type": "custom" + }, + { + "url": "https://symfony.com/cloud/", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2020-07-05T13:18:14+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-12-12T23:22:04+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/9bd89e83cecdf8c37b64909454249eaed98b2c89", + "reference": "9bd89e83cecdf8c37b64909454249eaed98b2c89", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-01-24T18:59:03+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "3371442b05531d8490d0b51b90b55e61948b0f10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/3371442b05531d8490d0b51b90b55e61948b0f10", + "reference": "3371442b05531d8490d0b51b90b55e61948b0f10", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Efficient assertions to validate the input/output of your methods.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.0.0" + }, + "time": "2015-05-12T12:40:29+00:00" + }, + { + "name": "zbateson/mail-mime-parser", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/zbateson/mail-mime-parser.git", + "reference": "706964d904798b8c22d63f62f0ec5f5bc84e30d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/706964d904798b8c22d63f62f0ec5f5bc84e30d9", + "reference": "706964d904798b8c22d63f62f0ec5f5bc84e30d9", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.0", + "php": ">=5.4", + "zbateson/mb-wrapper": "^1.0.1", + "zbateson/stream-decorators": "^1.0.4" + }, + "require-dev": { + "jms/serializer": "^1.1", + "mikey179/vfsstream": "^1.6.0", + "phing/phing": "^2.15.0", + "phpdocumentor/phpdocumentor": "^2.9.0", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5" + }, + "suggest": { + "ext-iconv": "For best support/performance", + "ext-mbstring": "For best support/performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\MailMimeParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + }, + { + "name": "Contributors", + "homepage": "https://github.com/zbateson/mail-mime-parser/graphs/contributors" + } + ], + "description": "MIME email message parser", + "homepage": "https://mail-mime-parser.org", + "keywords": [ + "MimeMailParser", + "email", + "mail", + "mailparse", + "mime", + "mimeparse", + "parser", + "php-imap" + ], + "support": { + "docs": "https://mail-mime-parser.org/#usage-guide", + "issues": "https://github.com/zbateson/mail-mime-parser/issues", + "source": "https://github.com/zbateson/mail-mime-parser" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2020-12-02T21:55:45+00:00" + }, + { + "name": "zbateson/mb-wrapper", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/zbateson/mb-wrapper.git", + "reference": "721b3dfbf7ab75fee5ac60a542d7923ffe59ef6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/721b3dfbf7ab75fee5ac60a542d7923ffe59ef6d", + "reference": "721b3dfbf7ab75fee5ac60a542d7923ffe59ef6d", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "symfony/polyfill-iconv": "^1.9", + "symfony/polyfill-mbstring": "^1.9" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5" + }, + "suggest": { + "ext-iconv": "For best support/performance", + "ext-mbstring": "For best support/performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\MbWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + } + ], + "description": "Wrapper for mbstring with fallback to iconv for encoding conversion and string manipulation", + "keywords": [ + "charset", + "encoding", + "http", + "iconv", + "mail", + "mb", + "mb_convert_encoding", + "mbstring", + "mime", + "multibyte", + "string" + ], + "support": { + "issues": "https://github.com/zbateson/mb-wrapper/issues", + "source": "https://github.com/zbateson/mb-wrapper/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2020-10-21T22:14:27+00:00" + }, + { + "name": "zbateson/stream-decorators", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/zbateson/stream-decorators.git", + "reference": "6f54738dfecc65e1d5bfb855035836748083a6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/6f54738dfecc65e1d5bfb855035836748083a6dd", + "reference": "6f54738dfecc65e1d5bfb855035836748083a6dd", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.0.0", + "php": ">=5.4", + "zbateson/mb-wrapper": "^1.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\StreamDecorators\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + } + ], + "description": "PHP psr7 stream decorators for mime message part streams", + "keywords": [ + "base64", + "charset", + "decorators", + "mail", + "mime", + "psr7", + "quoted-printable", + "stream", + "uuencode" + ], + "support": { + "issues": "https://github.com/zbateson/stream-decorators/issues", + "source": "https://github.com/zbateson/stream-decorators/tree/master" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2020-08-10T18:59:43+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": true, + "platform": { + "php": ">=8.2", + "ext-intl": "*" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/demo/laravel/.editorconfig b/demo/laravel/.editorconfig new file mode 100644 index 00000000..8f0de65c --- /dev/null +++ b/demo/laravel/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/demo/laravel/.env.example b/demo/laravel/.env.example new file mode 100644 index 00000000..7b49625a --- /dev/null +++ b/demo/laravel/.env.example @@ -0,0 +1,64 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_TIMEZONE=UTC +APP_URL=http://localhost + +APP_LOCALE=en +APP_FALLBACK_LOCALE=en +APP_FAKER_LOCALE=en_US + +APP_MAINTENANCE_DRIVER=file +APP_MAINTENANCE_STORE=database + +BCRYPT_ROUNDS=12 + +LOG_CHANNEL=stack +LOG_STACK=single +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=sqlite +# DB_HOST=127.0.0.1 +# DB_PORT=3306 +# DB_DATABASE=laravel +# DB_USERNAME=root +# DB_PASSWORD= + +SESSION_DRIVER=database +SESSION_LIFETIME=120 +SESSION_ENCRYPT=false +SESSION_PATH=/ +SESSION_DOMAIN=null + +BROADCAST_CONNECTION=log +FILESYSTEM_DISK=local +QUEUE_CONNECTION=database + +CACHE_STORE=database +CACHE_PREFIX= + +MEMCACHED_HOST=127.0.0.1 + +REDIS_CLIENT=phpredis +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=log +MAIL_HOST=127.0.0.1 +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +VITE_APP_NAME="${APP_NAME}" diff --git a/demo/laravel/.gitattributes b/demo/laravel/.gitattributes new file mode 100644 index 00000000..fcb21d39 --- /dev/null +++ b/demo/laravel/.gitattributes @@ -0,0 +1,11 @@ +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/demo/laravel/.gitignore b/demo/laravel/.gitignore new file mode 100644 index 00000000..7fe978f8 --- /dev/null +++ b/demo/laravel/.gitignore @@ -0,0 +1,19 @@ +/.phpunit.cache +/node_modules +/public/build +/public/hot +/public/storage +/storage/*.key +/vendor +.env +.env.backup +.env.production +.phpunit.result.cache +Homestead.json +Homestead.yaml +auth.json +npm-debug.log +yarn-error.log +/.fleet +/.idea +/.vscode diff --git a/demo/laravel/.php-version b/demo/laravel/.php-version new file mode 100644 index 00000000..2983cad0 --- /dev/null +++ b/demo/laravel/.php-version @@ -0,0 +1 @@ +8.2 diff --git a/demo/laravel/.valetrc b/demo/laravel/.valetrc new file mode 100644 index 00000000..a22f8c42 --- /dev/null +++ b/demo/laravel/.valetrc @@ -0,0 +1 @@ +php=php@8.2 diff --git a/demo/laravel/README.md b/demo/laravel/README.md new file mode 100644 index 00000000..1a4c26ba --- /dev/null +++ b/demo/laravel/README.md @@ -0,0 +1,66 @@ +

Laravel Logo

+ +

+Build Status +Total Downloads +Latest Stable Version +License +

+ +## About Laravel + +Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as: + +- [Simple, fast routing engine](https://laravel.com/docs/routing). +- [Powerful dependency injection container](https://laravel.com/docs/container). +- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. +- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent). +- Database agnostic [schema migrations](https://laravel.com/docs/migrations). +- [Robust background job processing](https://laravel.com/docs/queues). +- [Real-time event broadcasting](https://laravel.com/docs/broadcasting). + +Laravel is accessible, powerful, and provides tools required for large, robust applications. + +## Learning Laravel + +Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. + +You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch. + +If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library. + +## Laravel Sponsors + +We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com). + +### Premium Partners + +- **[Vehikl](https://vehikl.com/)** +- **[Tighten Co.](https://tighten.co)** +- **[WebReinvent](https://webreinvent.com/)** +- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)** +- **[64 Robots](https://64robots.com)** +- **[Curotec](https://www.curotec.com/services/technologies/laravel/)** +- **[Cyber-Duck](https://cyber-duck.co.uk)** +- **[DevSquad](https://devsquad.com/hire-laravel-developers)** +- **[Jump24](https://jump24.co.uk)** +- **[Redberry](https://redberry.international/laravel/)** +- **[Active Logic](https://activelogic.com)** +- **[byte5](https://byte5.de)** +- **[OP.GG](https://op.gg)** + +## Contributing + +Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). + +## Code of Conduct + +In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). + +## Security Vulnerabilities + +If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed. + +## License + +The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/demo/laravel/app/Http/Controllers/Controller.php b/demo/laravel/app/Http/Controllers/Controller.php new file mode 100644 index 00000000..8677cd5c --- /dev/null +++ b/demo/laravel/app/Http/Controllers/Controller.php @@ -0,0 +1,8 @@ + + */ + public function share(Request $request): array + { + return array_merge(parent::share($request), [ + // + ]); + } +} diff --git a/demo/laravel/app/Livewire/Counter.php b/demo/laravel/app/Livewire/Counter.php new file mode 100644 index 00000000..5ba34d52 --- /dev/null +++ b/demo/laravel/app/Livewire/Counter.php @@ -0,0 +1,29 @@ +success('increment'); + + $this->count++; + } + + public function decrement() + { + flash()->info('decrement'); + + $this->count--; + } + + public function render() + { + return view('livewire.counter'); + } +} diff --git a/demo/laravel/app/Livewire/Eventous.php b/demo/laravel/app/Livewire/Eventous.php new file mode 100644 index 00000000..66f3b776 --- /dev/null +++ b/demo/laravel/app/Livewire/Eventous.php @@ -0,0 +1,31 @@ + + + + HTML; + } + + public function delete() + { + sweetalert() + ->showDenyButton() + ->info('confirm or deny action'); + } + + #[On('sweetalert:confirmed')] + public function onSweetalertConfirmed(array $payload): void + { + toastr()->success('sweetalert was confirmed'); + } +} diff --git a/demo/laravel/app/Models/User.php b/demo/laravel/app/Models/User.php new file mode 100644 index 00000000..def621f4 --- /dev/null +++ b/demo/laravel/app/Models/User.php @@ -0,0 +1,47 @@ + + */ + protected $fillable = [ + 'name', + 'email', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'email_verified_at' => 'datetime', + 'password' => 'hashed', + ]; + } +} diff --git a/demo/laravel/app/Providers/AppServiceProvider.php b/demo/laravel/app/Providers/AppServiceProvider.php new file mode 100644 index 00000000..452e6b65 --- /dev/null +++ b/demo/laravel/app/Providers/AppServiceProvider.php @@ -0,0 +1,24 @@ +handleCommand(new ArgvInput); + +exit($status); diff --git a/demo/laravel/bootstrap/app.php b/demo/laravel/bootstrap/app.php new file mode 100644 index 00000000..58e985f8 --- /dev/null +++ b/demo/laravel/bootstrap/app.php @@ -0,0 +1,20 @@ +withRouting( + web: __DIR__.'/../routes/web.php', + commands: __DIR__.'/../routes/console.php', + health: '/up', + ) + ->withMiddleware(function (Middleware $middleware) { + $middleware->web(append: [ + \App\Http\Middleware\HandleInertiaRequests::class, + ]); + }) + ->withExceptions(function (Exceptions $exceptions) { + // + })->create(); diff --git a/demo/laravel/bootstrap/cache/.gitignore b/demo/laravel/bootstrap/cache/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/bootstrap/providers.php b/demo/laravel/bootstrap/providers.php new file mode 100644 index 00000000..38b258d1 --- /dev/null +++ b/demo/laravel/bootstrap/providers.php @@ -0,0 +1,5 @@ +=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "f41715465d65213d644d3141a6a93081be5d3549" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", + "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + }, + "time": "2022-10-27T11:44:00+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "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" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" + }, + "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%2Finflector", + "type": "tidelift" + } + ], + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "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": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "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%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.3", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2023-08-10T19:36:49+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.2" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2023-10-06T06:47:41+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2023-10-12T05:21:21+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:16:48+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:35:24+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:19:20+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2023-12-03T20:05:35+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2023-12-03T19:50:20+00:00" + }, + { + "name": "inertiajs/inertia-laravel", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/inertiajs/inertia-laravel.git", + "reference": "fcf3d6db1a259a55d8d18cf43fc971202c1f6b0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/fcf3d6db1a259a55d8d18cf43fc971202c1f6b0d", + "reference": "fcf3d6db1a259a55d8d18cf43fc971202c1f6b0d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.74|^9.0|^10.0|^11.0", + "php": "^7.3|~8.0.0|~8.1.0|~8.2.0|~8.3.0" + }, + "require-dev": { + "mockery/mockery": "^1.3.3", + "orchestra/testbench": "^6.4|^7.0|^8.0|^9.0", + "phpunit/phpunit": "^8.0|^9.5.8|^10.4", + "roave/security-advisories": "dev-master" + }, + "suggest": { + "ext-pcntl": "Recommended when running the Inertia SSR server via the `inertia:start-ssr` artisan command." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Inertia\\ServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "./helpers.php" + ], + "psr-4": { + "Inertia\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Reinink", + "email": "jonathan@reinink.ca", + "homepage": "https://reinink.ca" + } + ], + "description": "The Laravel adapter for Inertia.js.", + "keywords": [ + "inertia", + "laravel" + ], + "support": { + "issues": "https://github.com/inertiajs/inertia-laravel/issues", + "source": "https://github.com/inertiajs/inertia-laravel/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://github.com/reinink", + "type": "github" + } + ], + "time": "2024-03-09T00:30:58+00:00" + }, + { + "name": "laravel/framework", + "version": "v11.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "a1750156b671f37cba702380107e2d22161c31e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/a1750156b671f37cba702380107e2d22161c31e3", + "reference": "a1750156b671f37cba702380107e2d22161c31e3", + "shasum": "" + }, + "require": { + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.3.2", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.1.15", + "laravel/serializable-closure": "^1.3", + "league/commonmark": "^2.2.1", + "league/flysystem": "^3.8.0", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^2.72.2|^3.0", + "nunomaduro/termwind": "^2.0", + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^7.0", + "symfony/error-handler": "^7.0", + "symfony/finder": "^7.0", + "symfony/http-foundation": "^7.0", + "symfony/http-kernel": "^7.0", + "symfony/mailer": "^7.0", + "symfony/mime": "^7.0", + "symfony/polyfill-php83": "^1.28", + "symfony/process": "^7.0", + "symfony/routing": "^7.0", + "symfony/uid": "^7.0", + "symfony/var-dumper": "^7.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "mockery/mockery": "1.6.8", + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version", + "spatie/once": "*" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.235.5", + "ext-gmp": "*", + "fakerphp/faker": "^1.23", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-path-prefixing": "^3.3", + "league/flysystem-read-only": "^3.3", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.6", + "nyholm/psr7": "^1.2", + "orchestra/testbench-core": "^9.0.6", + "pda/pheanstalk": "^5.0", + "phpstan/phpstan": "^1.4.7", + "phpunit/phpunit": "^10.5|^11.0", + "predis/predis": "^2.0.2", + "resend/resend-php": "^0.10.0", + "symfony/cache": "^7.0", + "symfony/http-client": "^7.0", + "symfony/psr-http-message-bridge": "^7.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.235.5).", + "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.3).", + "league/flysystem-read-only": "Required to use read-only disks (^3.3)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.6).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5|^11.0).", + "predis/predis": "Required to use the predis connector (^2.0.2).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-04-02T14:01:33+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.1.17", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "8ee9f87f7f9eadcbe21e9e72cd4176b2f06cd5b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/8ee9f87f7f9eadcbe21e9e72cd4176b2f06cd5b5", + "reference": "8ee9f87f7f9eadcbe21e9e72cd4176b2f06cd5b5", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.17" + }, + "time": "2024-03-13T16:05:43+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.3.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "3dbf8a8e914634c48d389c1234552666b3d43754" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754", + "reference": "3dbf8a8e914634c48d389c1234552666b3d43754", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2023-11-08T14:08:06+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "reference": "502e0fe3f0415d06d5db1f83a472f0f3b754bafe", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.9.0" + }, + "time": "2024-01-04T16:10:04+00:00" + }, + { + "name": "league/commonmark", + "version": "2.4.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.3", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 || ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2024-02-02T11:59:32+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/flysystem", + "version": "3.26.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "072735c56cc0da00e10716dd90d5a7f7b40b36be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/072735c56cc0da00e10716dd90d5a7f7b40b36be", + "reference": "072735c56cc0da00e10716dd90d5a7f7b40b36be", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.26.0" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2024-03-25T11:49:53+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.25.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/61a6a90d6e999e4ddd9ce5adb356de0939060b92", + "reference": "61a6a90d6e999e4ddd9ce5adb356de0939060b92", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.25.1" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2024-03-15T19:58:44+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.15.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-01-28T23:22:08+00:00" + }, + { + "name": "livewire/livewire", + "version": "v3.4.10", + "source": { + "type": "git", + "url": "https://github.com/livewire/livewire.git", + "reference": "6f90e2d7f8e80a97a7406c22a0fbc61ca1256ed9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/livewire/livewire/zipball/6f90e2d7f8e80a97a7406c22a0fbc61ca1256ed9", + "reference": "6f90e2d7f8e80a97a7406c22a0fbc61ca1256ed9", + "shasum": "" + }, + "require": { + "illuminate/database": "^10.0|^11.0", + "illuminate/routing": "^10.0|^11.0", + "illuminate/support": "^10.0|^11.0", + "illuminate/validation": "^10.0|^11.0", + "league/mime-type-detection": "^1.9", + "php": "^8.1", + "symfony/console": "^6.0|^7.0", + "symfony/http-kernel": "^6.2|^7.0" + }, + "require-dev": { + "calebporzio/sushi": "^2.1", + "laravel/framework": "^10.0|^11.0", + "laravel/prompts": "^0.1.6", + "mockery/mockery": "^1.3.1", + "orchestra/testbench": "^8.21.0|^9.0", + "orchestra/testbench-dusk": "^8.24|^9.1", + "phpunit/phpunit": "^10.4", + "psy/psysh": "^0.11.22|^0.12" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Livewire\\LivewireServiceProvider" + ], + "aliases": { + "Livewire": "Livewire\\Livewire" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Livewire\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Caleb Porzio", + "email": "calebporzio@gmail.com" + } + ], + "description": "A front-end framework for Laravel.", + "support": { + "issues": "https://github.com/livewire/livewire/issues", + "source": "https://github.com/livewire/livewire/tree/v3.4.10" + }, + "funding": [ + { + "url": "https://github.com/livewire", + "type": "github" + } + ], + "time": "2024-04-02T14:22:50+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^10.1", + "predis/predis": "^1.1 || ^2", + "ruflin/elastica": "^7", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.5.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2023-10-27T15:32:31+00:00" + }, + { + "name": "nesbot/carbon", + "version": "3.2.3", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "4d599a6e2351d6b6bf21737accdfe1a4ce3fdbb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4d599a6e2351d6b6bf21737accdfe1a4ce3fdbb1", + "reference": "4d599a6e2351d6b6bf21737accdfe1a4ce3fdbb1", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "*", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3 || ^7.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.52.1", + "kylekatarnls/multi-tester": "^2.5.3", + "ondrejmirtes/better-reflection": "^6.25.0.4", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.10.65", + "phpunit/phpunit": "^10.5.15", + "squizlabs/php_codesniffer": "^3.9.0" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2024-03-30T18:22:00+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188", + "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.3" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.0" + }, + "time": "2023-12-11T11:54:22+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "shasum": "" + }, + "require": { + "php": ">=8.0 <8.4" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.4" + }, + "time": "2024-01-17T16:50:36+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.0.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + }, + "time": "2024-03-05T20:51:40+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/58c4c58cf23df7f498daeb97092e34f5259feb6a", + "reference": "58c4c58cf23df7f498daeb97092e34f5259feb6a", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.0.4" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^2.2.0", + "illuminate/console": "^11.0.0", + "laravel/pint": "^1.14.0", + "mockery/mockery": "^1.6.7", + "pestphp/pest": "^2.34.1", + "phpstan/phpstan": "^1.10.59", + "phpstan/phpstan-strict-rules": "^1.5.2", + "symfony/var-dumper": "^7.0.4", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2024-03-06T16:17:14+00:00" + }, + { + "name": "php-flasher/php-flasher", + "version": "2.x-dev", + "dist": { + "type": "path", + "url": "../..", + "reference": "48f5a7fcf6f5cf84382b6be56ed6bfc20dbee649" + }, + "require": { + "ext-intl": "*", + "php": ">=8.2" + }, + "require-dev": { + "illuminate/routing": "^11.0", + "illuminate/support": "^11.0", + "larastan/larastan": "^2.9.2", + "laravel/octane": "^2.3", + "livewire/livewire": "^3.3", + "mockery/mockery": "^1.6.10", + "orchestra/testbench": "^9.0.1", + "overtrue/phplint": "^9.1.2", + "php-cs-fixer/shim": "^3.52.1", + "phpstan/phpstan": "^1.10.63", + "phpstan/phpstan-mockery": "^1.1.2", + "phpstan/phpstan-symfony": "^1.3.9", + "phpunit/phpunit": "^10.5.13", + "psr/container": "^1.1|^2.0", + "rector/rector": "^1.0.3", + "rector/swiss-knife": "^0.2.2", + "symfony/config": "^7.0", + "symfony/console": "^7.0", + "symfony/dependency-injection": "^7.0", + "symfony/framework-bundle": "^7.0", + "symfony/http-kernel": "^7.0", + "symfony/translation": "^7.0", + "symfony/twig-bundle": "^7.0", + "symfony/ux-twig-component": "^2.14", + "symplify/monorepo-builder": "^11.2" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "laravel": { + "providers": [ + "Flasher\\Laravel\\FlasherServiceProvider", + "Flasher\\Noty\\Laravel\\FlasherNotyServiceProvider", + "Flasher\\Notyf\\Laravel\\FlasherNotyfServiceProvider", + "Flasher\\SweetAlert\\Laravel\\FlasherSweetAlertServiceProvider", + "Flasher\\Toastr\\Laravel\\FlasherToastrServiceProvider" + ], + "aliases": { + "Flasher": "Flasher\\Laravel\\Facade\\Flasher", + "Noty": "Flasher\\Noty\\Laravel\\Facade\\Noty", + "Notyf": "Flasher\\Notyf\\Laravel\\Facade\\Notyf", + "SweetAlert": "Flasher\\SweetAlert\\Laravel\\Facade\\SweetAlert", + "Toastr": "Flasher\\Toastr\\Laravel\\Facade\\Toastr" + } + } + }, + "autoload": { + "psr-4": { + "Flasher\\": "src/" + }, + "files": [ + "src/Prime/functions.php", + "src/Prime/helpers.php", + "src/Noty/Prime/functions.php", + "src/Noty/Prime/helpers.php", + "src/Notyf/Prime/functions.php", + "src/Notyf/Prime/helpers.php", + "src/SweetAlert/Prime/functions.php", + "src/SweetAlert/Prime/helpers.php", + "src/Toastr/Prime/functions.php", + "src/Toastr/Prime/helpers.php" + ] + }, + "autoload-dev": { + "psr-4": { + "Flasher\\Tests\\": "tests/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", + "role": "Developer" + } + ], + "description": "Elevate user engagement in Laravel and Symfony projects with PHPFlasher, a comprehensive flash messaging toolkit. This library facilitates streamlined user feedback management and supports a variety of popular notification styles including Noty, Notyf, SweetAlert, and Toastr. PHPFlasher is designed for ease of use, making it accessible to both beginners and experienced developers seeking to enhance the interactive elements of their web applications.", + "homepage": "https://php-flasher.io", + "keywords": [ + "customizable-alerts-php", + "flash-messages", + "interactive-web-notifications", + "laravel-notification", + "php-messaging-library", + "php-notification-system", + "php-user-interface", + "symfony-notification", + "user-engagement-php", + "user-feedback-tools", + "web-application-notifications" + ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, + "transport-options": { + "symlink": true, + "relative": true + } + }, + { + "name": "phpoption/phpoption", + "version": "1.9.2", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-11-12T21:59:55+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.10.66", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "94779c987e4ebd620025d9e5fdd23323903950bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/94779c987e4ebd620025d9e5fdd23323903950bd", + "reference": "94779c987e4ebd620025d9e5fdd23323903950bd", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2024-03-28T16:17:31+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1 || ^2.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^5.4@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "https://pimple.symfony.com", + "keywords": [ + "container", + "dependency injection" + ], + "support": { + "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" + }, + "time": "2021-10-28T11:13:42+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+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/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.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/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.12.3", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "b6b6cce7d3ee8fbf31843edce5e8f5a72eff4a73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/b6b6cce7d3ee8fbf31843edce5e8f5a72eff4a73", + "reference": "b6b6cce7d3ee8fbf31843edce5e8f5a72eff4a73", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.12.x-dev" + }, + "bamarni-bin": { + "bin-links": false, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.3" + }, + "time": "2024-04-02T15:57:53+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2022-12-31T21:50:55+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.7.5", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^8.5 || ^9", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.7.5" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2023-11-08T05:53:05+00:00" + }, + { + "name": "rector/rector", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "6e04d0eb087aef707fa0c5686d33d6ff61f4a555" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/6e04d0eb087aef707fa0c5686d33d6ff61f4a555", + "reference": "6e04d0eb087aef707fa0c5686d33d6ff61f4a555", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.10.57" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/1.0.4" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2024-04-05T09:01:07+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "483f76a82964a0431aa836b6ed0edde0c248e3ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/483f76a82964a0431aa836b6ed0edde0c248e3ab", + "reference": "483f76a82964a0431aa836b6ed0edde0c248e3ab", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "spatie/phpunit-snapshot-assertions": "^4.2", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/backtrace/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2023-06-28T12:59:17+00:00" + }, + { + "name": "spatie/laravel-ray", + "version": "1.36.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ray.git", + "reference": "f15936b5d308ae391ee67370a5628f0712537c34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ray/zipball/f15936b5d308ae391ee67370a5628f0712537c34", + "reference": "f15936b5d308ae391ee67370a5628f0712537c34", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/contracts": "^7.20|^8.19|^9.0|^10.0|^11.0", + "illuminate/database": "^7.20|^8.19|^9.0|^10.0|^11.0", + "illuminate/queue": "^7.20|^8.19|^9.0|^10.0|^11.0", + "illuminate/support": "^7.20|^8.19|^9.0|^10.0|^11.0", + "php": "^7.4|^8.0", + "rector/rector": "^0.19.2|^1.0", + "spatie/backtrace": "^1.0", + "spatie/ray": "^1.41.1", + "symfony/stopwatch": "4.2|^5.1|^6.0|^7.0", + "zbateson/mail-mime-parser": "^1.3.1|^2.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.3", + "laravel/framework": "^7.20|^8.19|^9.0|^10.0|^11.0", + "orchestra/testbench-core": "^5.0|^6.0|^7.0|^8.0|^9.0", + "pestphp/pest": "^1.22|^2.0", + "phpstan/phpstan": "^1.10.57", + "phpunit/phpunit": "^9.3|^10.1", + "spatie/pest-plugin-snapshots": "^1.1|^2.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.29.x-dev" + }, + "laravel": { + "providers": [ + "Spatie\\LaravelRay\\RayServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\LaravelRay\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily debug Laravel apps", + "homepage": "https://github.com/spatie/laravel-ray", + "keywords": [ + "laravel-ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-ray/issues", + "source": "https://github.com/spatie/laravel-ray/tree/1.36.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-03-29T09:10:11+00:00" + }, + { + "name": "spatie/macroable", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/ec2c320f932e730607aff8052c44183cf3ecb072", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/2.0.0" + }, + "time": "2021-03-26T22:39:02+00:00" + }, + { + "name": "spatie/ray", + "version": "1.41.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/ray.git", + "reference": "051a0facb1d2462fafef87ff77eb74d6f2d12944" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ray/zipball/051a0facb1d2462fafef87ff77eb74d6f2d12944", + "reference": "051a0facb1d2462fafef87ff77eb74d6f2d12944", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": "^7.3|^8.0", + "ramsey/uuid": "^3.0|^4.1", + "spatie/backtrace": "^1.1", + "spatie/macroable": "^1.0|^2.0", + "symfony/stopwatch": "^4.0|^5.1|^6.0|^7.0", + "symfony/var-dumper": "^4.2|^5.1|^6.0|^7.0" + }, + "require-dev": { + "illuminate/support": "6.x|^8.18|^9.0", + "nesbot/carbon": "^2.63", + "pestphp/pest": "^1.22", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.19.2", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2" + }, + "bin": [ + "bin/remove-ray.sh" + ], + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\Ray\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Debug with Ray to fix problems faster", + "homepage": "https://github.com/spatie/ray", + "keywords": [ + "ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/ray/issues", + "source": "https://github.com/spatie/ray/tree/1.41.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2024-01-25T10:15:50+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.0.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/8b9d08887353d627d5f6c3bf3373b398b49051c2", + "reference": "8b9d08887353d627d5f6c3bf3373b398b49051c2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "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": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.0.5" + }, + "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": "2024-03-02T12:46:12+00:00" + }, + { + "name": "symfony/console", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", + "reference": "fde915cd8e7eb99b3d531d3d5c09531429c3f9e5", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "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/v7.0.6" + }, + "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": "2024-04-01T11:04:53+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ec60a4edf94e63b0556b6a0888548bb400a3a3be", + "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "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/v7.0.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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-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.4.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": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/46a4cc138f799886d4bd70477c55c699d3e9dfc8", + "reference": "46a4cc138f799886d4bd70477c55c699d3e9dfc8", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "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 tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.0.6" + }, + "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": "2024-03-19T11:57:22+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e", + "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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 tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "4e64b49bf370ade88e567de29465762e316e4224" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/4e64b49bf370ade88e567de29465762e316e4224", + "reference": "4e64b49bf370ade88e567de29465762e316e4224", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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 dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.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": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.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/v7.0.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": "2023-10-31T17:59:56+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8789625dcf36e5fbf753014678a1e090f1bc759c", + "reference": "8789625dcf36e5fbf753014678a1e090f1bc759c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.0.6" + }, + "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": "2024-03-19T11:46:48+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "34c872391046d59af804af62d4573b829cfe4824" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/34c872391046d59af804af62d4573b829cfe4824", + "reference": "34c872391046d59af804af62d4573b829cfe4824", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.0.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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 a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.0.6" + }, + "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": "2024-04-03T06:12:25+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", + "reference": "eb0c3187c7ddfde12d8aa0e1fa5fb29e730a41e0", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "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": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.0.6" + }, + "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": "2024-03-28T09:20:36+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", + "reference": "99362408c9abdf8c7cadcf0529b6fc8b16f5ace2", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "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": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.0.6" + }, + "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": "2024-03-21T19:37:36+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "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.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f", + "reference": "cd4226d140ecd3d0f13d32ed0a4a095ffe871d2f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-iconv": "*" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + } + }, + "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 Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "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.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "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.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "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.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "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.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "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.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "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 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/3abdd21b0ceaa3000ee950097bc3cf9efc137853", + "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.29.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": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/process", + "version": "v7.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9", + "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "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/v7.0.4" + }, + "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": "2024-02-22T20:27:20+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/cded64e5bbf9f31786f1055fcc76718fdd77519c", + "reference": "cded64e5bbf9f31786f1055fcc76718fdd77519c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "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": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.0.6" + }, + "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": "2024-03-28T21:02:11+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "11bbf19a0fb7b36345861e85c5768844c552906e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e", + "reference": "11bbf19a0fb7b36345861e85c5768844c552906e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-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.4.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": "2023-12-19T21:51:00+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/983900d6fddf2b0cbaacacbbad07610854bd8112", + "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "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 a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.0.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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "symfony/string", + "version": "v7.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b", + "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "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.5" + }, + "require-dev": { + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.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/v7.0.4" + }, + "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": "2024-02-01T13:17:36+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/5b75e872f7d135d7abb4613809fadc8d9f3d30a0", + "reference": "5b75e872f7d135d7abb4613809fadc8d9f3d30a0", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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 tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.0.4" + }, + "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": "2024-02-22T20:27:20+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", + "reference": "43810bdb2ddb5400e5c5e778e27b210a0ca83b6b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "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 translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.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": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/uid", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/87cedaf3fabd7b733859d4d77aa4ca598259054b", + "reference": "87cedaf3fabd7b733859d4d77aa4ca598259054b", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v7.0.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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", + "reference": "66d13dc207d5dab6b4f4c2b5460efe1bea29dbfb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "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 mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.0.6" + }, + "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": "2024-03-19T11:57:22+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "v2.2.7", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb", + "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7" + }, + "time": "2023-12-08T13:03:43+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:43:29+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b56450eed252f6801410d810c8e1727224ae0743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-03-08T17:03:00+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "zbateson/mail-mime-parser", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/zbateson/mail-mime-parser.git", + "reference": "20b3e48eb799537683780bc8782fbbe9bc25934a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/mail-mime-parser/zipball/20b3e48eb799537683780bc8782fbbe9bc25934a", + "reference": "20b3e48eb799537683780bc8782fbbe9bc25934a", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.7.0|^2.0", + "php": ">=7.1", + "pimple/pimple": "^3.0", + "zbateson/mb-wrapper": "^1.0.1", + "zbateson/stream-decorators": "^1.0.6" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "*", + "mikey179/vfsstream": "^1.6.0", + "phpstan/phpstan": "*", + "phpunit/phpunit": "<10" + }, + "suggest": { + "ext-iconv": "For best support/performance", + "ext-mbstring": "For best support/performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\MailMimeParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + }, + { + "name": "Contributors", + "homepage": "https://github.com/zbateson/mail-mime-parser/graphs/contributors" + } + ], + "description": "MIME email message parser", + "homepage": "https://mail-mime-parser.org", + "keywords": [ + "MimeMailParser", + "email", + "mail", + "mailparse", + "mime", + "mimeparse", + "parser", + "php-imap" + ], + "support": { + "docs": "https://mail-mime-parser.org/#usage-guide", + "issues": "https://github.com/zbateson/mail-mime-parser/issues", + "source": "https://github.com/zbateson/mail-mime-parser" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2023-02-14T22:58:03+00:00" + }, + { + "name": "zbateson/mb-wrapper", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/zbateson/mb-wrapper.git", + "reference": "09a8b77eb94af3823a9a6623dcc94f8d988da67f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/mb-wrapper/zipball/09a8b77eb94af3823a9a6623dcc94f8d988da67f", + "reference": "09a8b77eb94af3823a9a6623dcc94f8d988da67f", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-iconv": "^1.9", + "symfony/polyfill-mbstring": "^1.9" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "<10.0" + }, + "suggest": { + "ext-iconv": "For best support/performance", + "ext-mbstring": "For best support/performance" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\MbWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + } + ], + "description": "Wrapper for mbstring with fallback to iconv for encoding conversion and string manipulation", + "keywords": [ + "charset", + "encoding", + "http", + "iconv", + "mail", + "mb", + "mb_convert_encoding", + "mbstring", + "mime", + "multibyte", + "string" + ], + "support": { + "issues": "https://github.com/zbateson/mb-wrapper/issues", + "source": "https://github.com/zbateson/mb-wrapper/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2024-03-18T04:31:04+00:00" + }, + { + "name": "zbateson/stream-decorators", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/zbateson/stream-decorators.git", + "reference": "783b034024fda8eafa19675fb2552f8654d3a3e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zbateson/stream-decorators/zipball/783b034024fda8eafa19675fb2552f8654d3a3e9", + "reference": "783b034024fda8eafa19675fb2552f8654d3a3e9", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.9 | ^2.0", + "php": ">=7.2", + "zbateson/mb-wrapper": "^1.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "<10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ZBateson\\StreamDecorators\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Zaahid Bateson" + } + ], + "description": "PHP psr7 stream decorators for mime message part streams", + "keywords": [ + "base64", + "charset", + "decorators", + "mail", + "mime", + "psr7", + "quoted-printable", + "stream", + "uuencode" + ], + "support": { + "issues": "https://github.com/zbateson/stream-decorators/issues", + "source": "https://github.com/zbateson/stream-decorators/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/zbateson", + "type": "github" + } + ], + "time": "2023-05-30T22:51:52+00:00" + } + ], + "packages-dev": [ + { + "name": "brianium/paratest", + "version": "v7.4.3", + "source": { + "type": "git", + "url": "https://github.com/paratestphp/paratest.git", + "reference": "64fcfd0e28a6b8078a19dbf9127be2ee645b92ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/64fcfd0e28a6b8078a19dbf9127be2ee645b92ec", + "reference": "64fcfd0e28a6b8078a19dbf9127be2ee645b92ec", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-simplexml": "*", + "fidry/cpu-core-counter": "^1.1.0", + "jean85/pretty-package-versions": "^2.0.5", + "php": "~8.2.0 || ~8.3.0", + "phpunit/php-code-coverage": "^10.1.11 || ^11.0.0", + "phpunit/php-file-iterator": "^4.1.0 || ^5.0.0", + "phpunit/php-timer": "^6.0.0 || ^7.0.0", + "phpunit/phpunit": "^10.5.9 || ^11.0.3", + "sebastian/environment": "^6.0.1 || ^7.0.0", + "symfony/console": "^6.4.3 || ^7.0.3", + "symfony/process": "^6.4.3 || ^7.0.3" + }, + "require-dev": { + "doctrine/coding-standard": "^12.0.0", + "ext-pcov": "*", + "ext-posix": "*", + "phpstan/phpstan": "^1.10.58", + "phpstan/phpstan-deprecation-rules": "^1.1.4", + "phpstan/phpstan-phpunit": "^1.3.15", + "phpstan/phpstan-strict-rules": "^1.5.2", + "squizlabs/php_codesniffer": "^3.9.0", + "symfony/filesystem": "^6.4.3 || ^7.0.3" + }, + "bin": [ + "bin/paratest", + "bin/paratest.bat", + "bin/paratest_for_phpstorm" + ], + "type": "library", + "autoload": { + "psr-4": { + "ParaTest\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Scaturro", + "email": "scaturrob@gmail.com", + "role": "Developer" + }, + { + "name": "Filippo Tessarotto", + "email": "zoeslam@gmail.com", + "role": "Developer" + } + ], + "description": "Parallel testing for PHP", + "homepage": "https://github.com/paratestphp/paratest", + "keywords": [ + "concurrent", + "parallel", + "phpunit", + "testing" + ], + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v7.4.3" + }, + "funding": [ + { + "url": "https://github.com/sponsors/Slamdunk", + "type": "github" + }, + { + "url": "https://paypal.me/filippotessarotto", + "type": "paypal" + } + ], + "time": "2024-02-20T07:24:02+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.23.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b", + "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1" + }, + "time": "2024-01-02T13:46:09+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-02-07T09:43:46+00:00" + }, + { + "name": "filp/whoops", + "version": "2.15.4", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546", + "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.15.4" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2023-11-03T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/f9fdd29ad8e6d024f52678b570e5593759b550b4", + "reference": "f9fdd29ad8e6d024f52678b570e5593759b550b4", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^7.5|^8.5|^9.4", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.6" + }, + "time": "2024-03-08T09:58:59+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.15.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "5f288b5e79938cc72f5c298d384e639de87507c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/5f288b5e79938cc72f5c298d384e639de87507c6", + "reference": "5f288b5e79938cc72f5c298d384e639de87507c6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.52.1", + "illuminate/view": "^10.48.4", + "larastan/larastan": "^2.9.2", + "laravel-zero/framework": "^10.3.0", + "mockery/mockery": "^1.6.11", + "nunomaduro/termwind": "^1.15.1", + "pestphp/pest": "^2.34.5" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2024-04-02T14:28:47+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.29.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "8be4a31150eab3b46af11a2e7b2c4632eefaad7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/8be4a31150eab3b46af11a2e7b2c4632eefaad7e", + "reference": "8be4a31150eab3b46af11a2e7b2c4632eefaad7e", + "shasum": "" + }, + "require": { + "illuminate/console": "^9.52.16|^10.0|^11.0", + "illuminate/contracts": "^9.52.16|^10.0|^11.0", + "illuminate/support": "^9.52.16|^10.0|^11.0", + "php": "^8.0", + "symfony/console": "^6.0|^7.0", + "symfony/yaml": "^6.0|^7.0" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0", + "phpstan/phpstan": "^1.10" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2024-03-20T20:09:31+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.11", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "81a161d0b135df89951abd52296adf97deb0723d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/81a161d0b135df89951abd52296adf97deb0723d", + "reference": "81a161d0b135df89951abd52296adf97deb0723d", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-03-21T18:34:15+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2023-03-08T13:26:56+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v8.1.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "13e5d538b95a744d85f447a321ce10adb28e9af9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/13e5d538b95a744d85f447a321ce10adb28e9af9", + "reference": "13e5d538b95a744d85f447a321ce10adb28e9af9", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.15.4", + "nunomaduro/termwind": "^2.0.1", + "php": "^8.2.0", + "symfony/console": "^7.0.4" + }, + "conflict": { + "laravel/framework": "<11.0.0 || >=12.0.0", + "phpunit/phpunit": "<10.5.1 || >=12.0.0" + }, + "require-dev": { + "larastan/larastan": "^2.9.2", + "laravel/framework": "^11.0.0", + "laravel/pint": "^1.14.0", + "laravel/sail": "^1.28.2", + "laravel/sanctum": "^4.0.0", + "laravel/tinker": "^2.9.0", + "orchestra/testbench-core": "^9.0.0", + "pestphp/pest": "^2.34.1 || ^3.0.0", + "sebastian/environment": "^6.0.1 || ^7.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2024-03-06T16:20:09+00:00" + }, + { + "name": "pestphp/pest", + "version": "v2.34.6", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest.git", + "reference": "680111fb1e7175a5010b73c115edef58ceef303e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest/zipball/680111fb1e7175a5010b73c115edef58ceef303e", + "reference": "680111fb1e7175a5010b73c115edef58ceef303e", + "shasum": "" + }, + "require": { + "brianium/paratest": "^7.3.1", + "nunomaduro/collision": "^7.10.0|^8.1.1", + "nunomaduro/termwind": "^1.15.1|^2.0.1", + "pestphp/pest-plugin": "^2.1.1", + "pestphp/pest-plugin-arch": "^2.7.0", + "php": "^8.1.0", + "phpunit/phpunit": "^10.5.16" + }, + "conflict": { + "phpunit/phpunit": ">10.5.16", + "sebastian/exporter": "<5.1.0", + "webmozart/assert": "<1.11.0" + }, + "require-dev": { + "pestphp/pest-dev-tools": "^2.16.0", + "pestphp/pest-plugin-type-coverage": "^2.8.1", + "symfony/process": "^6.4.0|^7.0.4" + }, + "bin": [ + "bin/pest" + ], + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Plugins\\Bail", + "Pest\\Plugins\\Cache", + "Pest\\Plugins\\Coverage", + "Pest\\Plugins\\Init", + "Pest\\Plugins\\Environment", + "Pest\\Plugins\\Help", + "Pest\\Plugins\\Memory", + "Pest\\Plugins\\Only", + "Pest\\Plugins\\Printer", + "Pest\\Plugins\\ProcessIsolation", + "Pest\\Plugins\\Profile", + "Pest\\Plugins\\Retry", + "Pest\\Plugins\\Snapshot", + "Pest\\Plugins\\Verbose", + "Pest\\Plugins\\Version", + "Pest\\Plugins\\Parallel" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php", + "src/Pest.php" + ], + "psr-4": { + "Pest\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "The elegant PHP Testing Framework.", + "keywords": [ + "framework", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/pestphp/pest/issues", + "source": "https://github.com/pestphp/pest/tree/v2.34.6" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-03-28T11:36:46+00:00" + }, + { + "name": "pestphp/pest-plugin", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin.git", + "reference": "e05d2859e08c2567ee38ce8b005d044e72648c0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e05d2859e08c2567ee38ce8b005d044e72648c0b", + "reference": "e05d2859e08c2567ee38ce8b005d044e72648c0b", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0.0", + "composer-runtime-api": "^2.2.2", + "php": "^8.1" + }, + "conflict": { + "pestphp/pest": "<2.2.3" + }, + "require-dev": { + "composer/composer": "^2.5.8", + "pestphp/pest": "^2.16.0", + "pestphp/pest-dev-tools": "^2.16.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Pest\\Plugin\\Manager" + }, + "autoload": { + "psr-4": { + "Pest\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest plugin manager", + "keywords": [ + "framework", + "manager", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin/tree/v2.1.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2023-08-22T08:40:06+00:00" + }, + { + "name": "pestphp/pest-plugin-arch", + "version": "v2.7.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-arch.git", + "reference": "d23b2d7498475354522c3818c42ef355dca3fcda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/d23b2d7498475354522c3818c42ef355dca3fcda", + "reference": "d23b2d7498475354522c3818c42ef355dca3fcda", + "shasum": "" + }, + "require": { + "nunomaduro/collision": "^7.10.0|^8.1.0", + "pestphp/pest-plugin": "^2.1.1", + "php": "^8.1", + "ta-tikoma/phpunit-architecture-test": "^0.8.4" + }, + "require-dev": { + "pestphp/pest": "^2.33.0", + "pestphp/pest-dev-tools": "^2.16.0" + }, + "type": "library", + "extra": { + "pest": { + "plugins": [ + "Pest\\Arch\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Arch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Arch plugin for Pest PHP.", + "keywords": [ + "arch", + "architecture", + "framework", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v2.7.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-01-26T09:46:42+00:00" + }, + { + "name": "pestphp/pest-plugin-laravel", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-laravel.git", + "reference": "2f6ea6233bb74ec65d969ecdea56bdbd3d1e2f0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/2f6ea6233bb74ec65d969ecdea56bdbd3d1e2f0e", + "reference": "2f6ea6233bb74ec65d969ecdea56bdbd3d1e2f0e", + "shasum": "" + }, + "require": { + "laravel/framework": "^10.44.0|^11.0", + "pestphp/pest": "^2.33.6", + "php": "^8.1.0" + }, + "require-dev": { + "laravel/dusk": "^7.12.3", + "orchestra/testbench": "^8.21.1|^9.0.0", + "pestphp/pest-dev-tools": "^2.16.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Pest\\Laravel\\PestServiceProvider" + ] + }, + "pest": { + "plugins": [ + "Pest\\Laravel\\Plugin" + ] + } + }, + "autoload": { + "files": [ + "src/Autoload.php" + ], + "psr-4": { + "Pest\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The Pest Laravel Plugin", + "keywords": [ + "framework", + "laravel", + "pest", + "php", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2024-02-17T10:04:08+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "153ae662783729388a584b4361f2545e4d841e3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" + }, + "time": "2024-02-23T11:10:43+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.28.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb", + "reference": "cd06d6b1a1b3c75b0b83f97577869fd85a3cd4fb", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.28.0" + }, + "time": "2024-04-03T18:51:33+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.14", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", + "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.14" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-12T15:33:41+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.16", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd", + "reference": "18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.5", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.1", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.16" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-03-28T10:08:10+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-14T13:18:12+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:15:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:17:12+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:05:40+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "spatie/flare-client-php", + "version": "1.4.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/flare-client-php.git", + "reference": "17082e780752d346c2db12ef5d6bee8e835e399c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/17082e780752d346c2db12ef5d6bee8e835e399c", + "reference": "17082e780752d346c2db12ef5d6bee8e835e399c", + "shasum": "" + }, + "require": { + "illuminate/pipeline": "^8.0|^9.0|^10.0|^11.0", + "php": "^8.0", + "spatie/backtrace": "^1.5.2", + "symfony/http-foundation": "^5.2|^6.0|^7.0", + "symfony/mime": "^5.2|^6.0|^7.0", + "symfony/process": "^5.2|^6.0|^7.0", + "symfony/var-dumper": "^5.2|^6.0|^7.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.5.0", + "pestphp/pest": "^1.20|^2.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/phpunit-snapshot-assertions": "^4.0|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.3.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\FlareClient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Send PHP errors to Flare", + "homepage": "https://github.com/spatie/flare-client-php", + "keywords": [ + "exception", + "flare", + "reporting", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/flare-client-php/issues", + "source": "https://github.com/spatie/flare-client-php/tree/1.4.4" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-01-31T14:18:45+00:00" + }, + { + "name": "spatie/ignition", + "version": "1.13.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/ignition.git", + "reference": "889bf1dfa59e161590f677728b47bf4a6893983b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ignition/zipball/889bf1dfa59e161590f677728b47bf4a6893983b", + "reference": "889bf1dfa59e161590f677728b47bf4a6893983b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": "^8.0", + "spatie/backtrace": "^1.5.3", + "spatie/flare-client-php": "^1.4.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "require-dev": { + "illuminate/cache": "^9.52|^10.0|^11.0", + "mockery/mockery": "^1.4", + "pestphp/pest": "^1.20|^2.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "psr/simple-cache-implementation": "*", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "vlucas/phpdotenv": "^5.5" + }, + "suggest": { + "openai-php/client": "Require get solutions from OpenAI", + "simple-cache-implementation": "To cache solutions from OpenAI" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\Ignition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for PHP applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/ignition/issues", + "source": "https://github.com/spatie/ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-03-29T14:03:47+00:00" + }, + { + "name": "spatie/laravel-ignition", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ignition.git", + "reference": "0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9", + "reference": "0c864b3cbd66ce67a2096c5f743e07ce8f1d6ab9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "illuminate/support": "^10.0|^11.0", + "php": "^8.1", + "spatie/flare-client-php": "^1.3.5", + "spatie/ignition": "^1.13", + "symfony/console": "^6.2.3|^7.0", + "symfony/var-dumper": "^6.2.3|^7.0" + }, + "require-dev": { + "livewire/livewire": "^2.11|^3.3.5", + "mockery/mockery": "^1.5.1", + "openai-php/client": "^0.8.1", + "orchestra/testbench": "^8.0|^9.0", + "pestphp/pest": "^2.30", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan-deprecation-rules": "^1.1.1", + "phpstan/phpstan-phpunit": "^1.3.3", + "vlucas/phpdotenv": "^5.5" + }, + "suggest": { + "openai-php/client": "Require get solutions from OpenAI", + "psr/simple-cache-implementation": "Needed to cache solutions from OpenAI" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelIgnition\\IgnitionServiceProvider" + ], + "aliases": { + "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\LaravelIgnition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for Laravel applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/laravel-ignition/issues", + "source": "https://github.com/spatie/laravel-ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-04-02T06:30:22+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "2d4fca631c00700597e9442a0b2451ce234513d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2d4fca631c00700597e9442a0b2451ce234513d3", + "reference": "2d4fca631c00700597e9442a0b2451ce234513d3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.0.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": "2024-01-23T15:02:46+00:00" + }, + { + "name": "ta-tikoma/phpunit-architecture-test", + "version": "0.8.4", + "source": { + "type": "git", + "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "reference": "89f0dea1cb0f0d5744d3ec1764a286af5e006636", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18.0 || ^5.0.0", + "php": "^8.1.0", + "phpdocumentor/reflection-docblock": "^5.3.0", + "phpunit/phpunit": "^10.5.5 || ^11.0.0", + "symfony/finder": "^6.4.0 || ^7.0.0" + }, + "require-dev": { + "laravel/pint": "^1.13.7", + "phpstan/phpstan": "^1.10.52" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPUnit\\Architecture\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ni Shi", + "email": "futik0ma011@gmail.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Methods for testing application architecture", + "keywords": [ + "architecture", + "phpunit", + "stucture", + "test", + "testing" + ], + "support": { + "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", + "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.4" + }, + "time": "2024-01-05T14:10:56+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "php-flasher/php-flasher": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.2" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/demo/laravel/config/app.php b/demo/laravel/config/app.php new file mode 100644 index 00000000..f4672673 --- /dev/null +++ b/demo/laravel/config/app.php @@ -0,0 +1,126 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | the application so that it's available within Artisan commands. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. The timezone + | is set to "UTC" by default as it is suitable for most use cases. + | + */ + + 'timezone' => env('APP_TIMEZONE', 'UTC'), + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by Laravel's translation / localization methods. This option can be + | set to any locale for which you plan to have translation strings. + | + */ + + 'locale' => env('APP_LOCALE', 'en'), + + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + + 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is utilized by Laravel's encryption services and should be set + | to a random, 32 character string to ensure that all encrypted values + | are secure. You should do this prior to deploying the application. + | + */ + + 'cipher' => 'AES-256-CBC', + + 'key' => env('APP_KEY'), + + 'previous_keys' => [ + ...array_filter( + explode(',', env('APP_PREVIOUS_KEYS', '')) + ), + ], + + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'database'), + ], + +]; diff --git a/demo/laravel/config/auth.php b/demo/laravel/config/auth.php new file mode 100644 index 00000000..0ba5d5d8 --- /dev/null +++ b/demo/laravel/config/auth.php @@ -0,0 +1,115 @@ + [ + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | which utilizes session storage plus the Eloquent user provider. + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | If you have multiple user tables or models you may configure multiple + | providers to represent the model / table. These providers may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => env('AUTH_MODEL', App\Models\User::class), + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | These configuration options specify the behavior of Laravel's password + | reset functionality, including the table utilized for token storage + | and the user provider that is invoked to actually retrieve users. + | + | The expiry time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | window expires and users are asked to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), + +]; diff --git a/demo/laravel/config/cache.php b/demo/laravel/config/cache.php new file mode 100644 index 00000000..38680919 --- /dev/null +++ b/demo/laravel/config/cache.php @@ -0,0 +1,107 @@ + env('CACHE_STORE', 'database'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "apc", "array", "database", "file", "memcached", + | "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'table' => env('DB_CACHE_TABLE', 'cache'), + 'connection' => env('DB_CACHE_CONNECTION'), + 'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'), + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_CACHE_CONNECTION', 'cache'), + 'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'), + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, and DynamoDB cache + | stores, there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + +]; diff --git a/demo/laravel/config/database.php b/demo/laravel/config/database.php new file mode 100644 index 00000000..f8e8dcb8 --- /dev/null +++ b/demo/laravel/config/database.php @@ -0,0 +1,170 @@ + env('DB_CONNECTION', 'sqlite'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Below are all of the database connections defined for your application. + | An example configuration is provided for each database system which + | is supported by Laravel. You're free to add / remove connections. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DB_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'mariadb' => [ + 'driver' => 'mariadb', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run on the database. + | + */ + + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => true, + ], + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as Memcached. You may define your connection settings here. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/demo/laravel/config/filesystems.php b/demo/laravel/config/filesystems.php new file mode 100644 index 00000000..44fe9c82 --- /dev/null +++ b/demo/laravel/config/filesystems.php @@ -0,0 +1,76 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Below you may configure as many filesystem disks as necessary, and you + | may even configure multiple disks for the same driver. Examples for + | most supported storage drivers are configured here for reference. + | + | Supported Drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + 'throw' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/demo/laravel/config/logging.php b/demo/laravel/config/logging.php new file mode 100644 index 00000000..d526b64d --- /dev/null +++ b/demo/laravel/config/logging.php @@ -0,0 +1,132 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => env('LOG_DEPRECATIONS_TRACE', false), + ], + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Laravel + | utilizes the Monolog PHP logging library, which includes a variety + | of powerful log handlers and formatters that you're free to use. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", "custom", "stack" + | + */ + + 'channels' => [ + + 'stack' => [ + 'driver' => 'stack', + 'channels' => explode(',', env('LOG_STACK', 'single')), + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => env('LOG_DAILY_DAYS', 14), + 'replace_placeholders' => true, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'), + 'emoji' => env('LOG_SLACK_EMOJI', ':boom:'), + 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER), + 'replace_placeholders' => true, + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + + ], + +]; diff --git a/demo/laravel/config/mail.php b/demo/laravel/config/mail.php new file mode 100644 index 00000000..a4a02fe4 --- /dev/null +++ b/demo/laravel/config/mail.php @@ -0,0 +1,103 @@ + env('MAIL_MAILER', 'log'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers that can be used + | when delivering an email. You may specify which one you're using for + | your mailers below. You may also add additional mailers if needed. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "log", "array", "failover", "roundrobin" + | + */ + + 'mailers' => [ + + 'smtp' => [ + 'transport' => 'smtp', + 'url' => env('MAIL_URL'), + 'host' => env('MAIL_HOST', '127.0.0.1'), + 'port' => env('MAIL_PORT', 2525), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN'), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'postmark' => [ + 'transport' => 'postmark', + // 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'), + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all emails sent by your application to be sent from + | the same address. Here you may specify a name and address that is + | used globally for all emails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + +]; diff --git a/demo/laravel/config/queue.php b/demo/laravel/config/queue.php new file mode 100644 index 00000000..116bd8d0 --- /dev/null +++ b/demo/laravel/config/queue.php @@ -0,0 +1,112 @@ + env('QUEUE_CONNECTION', 'database'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection options for every queue backend + | used by your application. An example configuration is provided for + | each backend supported by Laravel. You're also free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_QUEUE_CONNECTION'), + 'table' => env('DB_QUEUE_TABLE', 'jobs'), + 'queue' => env('DB_QUEUE', 'default'), + 'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90), + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'), + 'queue' => env('BEANSTALKD_QUEUE', 'default'), + 'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90), + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90), + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'job_batches', + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control how and where failed jobs are stored. Laravel ships with + | support for storing failed jobs in a simple file or in a database. + | + | Supported drivers: "database-uuids", "dynamodb", "file", "null" + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/demo/laravel/config/services.php b/demo/laravel/config/services.php new file mode 100644 index 00000000..6bb68f6a --- /dev/null +++ b/demo/laravel/config/services.php @@ -0,0 +1,34 @@ + [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'), + ], + ], + +]; diff --git a/demo/laravel/config/session.php b/demo/laravel/config/session.php new file mode 100644 index 00000000..0e22ee41 --- /dev/null +++ b/demo/laravel/config/session.php @@ -0,0 +1,218 @@ + env('SESSION_DRIVER', 'database'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to expire immediately when the browser is closed then you may + | indicate that via the expire_on_close configuration option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it's stored. All encryption is performed + | automatically by Laravel and you may use the session like normal. + | + */ + + 'encrypt' => env('SESSION_ENCRYPT', false), + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When utilizing the "file" session driver, the session files are placed + | on disk. The default storage location is defined here; however, you + | are free to provide another location where they should be stored. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table to + | be used to store sessions. Of course, a sensible default is defined + | for you; however, you're welcome to change this to another table. + | + */ + + 'table' => env('SESSION_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using one of the framework's cache driven session backends, you may + | define the cache store which should be used to store the session data + | between requests. This must match one of your defined cache stores. + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the session cookie that is created by + | the framework. Typically, you should not need to change this value + | since doing so does not grant a meaningful security improvement. + | + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application, but you're free to change this when necessary. + | + */ + + 'path' => env('SESSION_PATH', '/'), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | This value determines the domain and subdomains the session cookie is + | available to. By default, the cookie will be available to the root + | domain and all subdomains. Typically, this shouldn't be changed. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. It's unlikely you should disable this option. + | + */ + + 'http_only' => env('SESSION_HTTP_ONLY', true), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" to permit secure cross-site requests. + | + | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => env('SESSION_SAME_SITE', 'lax'), + + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + +]; diff --git a/demo/laravel/database/.gitignore b/demo/laravel/database/.gitignore new file mode 100644 index 00000000..9b19b93c --- /dev/null +++ b/demo/laravel/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/demo/laravel/database/factories/UserFactory.php b/demo/laravel/database/factories/UserFactory.php new file mode 100644 index 00000000..584104c9 --- /dev/null +++ b/demo/laravel/database/factories/UserFactory.php @@ -0,0 +1,44 @@ + + */ +class UserFactory extends Factory +{ + /** + * The current password being used by the factory. + */ + protected static ?string $password; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->name(), + 'email' => fake()->unique()->safeEmail(), + 'email_verified_at' => now(), + 'password' => static::$password ??= Hash::make('password'), + 'remember_token' => Str::random(10), + ]; + } + + /** + * Indicate that the model's email address should be unverified. + */ + public function unverified(): static + { + return $this->state(fn (array $attributes) => [ + 'email_verified_at' => null, + ]); + } +} diff --git a/demo/laravel/database/migrations/0001_01_01_000000_create_users_table.php b/demo/laravel/database/migrations/0001_01_01_000000_create_users_table.php new file mode 100644 index 00000000..05fb5d9e --- /dev/null +++ b/demo/laravel/database/migrations/0001_01_01_000000_create_users_table.php @@ -0,0 +1,49 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('users'); + Schema::dropIfExists('password_reset_tokens'); + Schema::dropIfExists('sessions'); + } +}; diff --git a/demo/laravel/database/migrations/0001_01_01_000001_create_cache_table.php b/demo/laravel/database/migrations/0001_01_01_000001_create_cache_table.php new file mode 100644 index 00000000..b9c106be --- /dev/null +++ b/demo/laravel/database/migrations/0001_01_01_000001_create_cache_table.php @@ -0,0 +1,35 @@ +string('key')->primary(); + $table->mediumText('value'); + $table->integer('expiration'); + }); + + Schema::create('cache_locks', function (Blueprint $table) { + $table->string('key')->primary(); + $table->string('owner'); + $table->integer('expiration'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cache'); + Schema::dropIfExists('cache_locks'); + } +}; diff --git a/demo/laravel/database/migrations/0001_01_01_000002_create_jobs_table.php b/demo/laravel/database/migrations/0001_01_01_000002_create_jobs_table.php new file mode 100644 index 00000000..425e7058 --- /dev/null +++ b/demo/laravel/database/migrations/0001_01_01_000002_create_jobs_table.php @@ -0,0 +1,57 @@ +id(); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + + Schema::create('job_batches', function (Blueprint $table) { + $table->string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->longText('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + + Schema::create('failed_jobs', function (Blueprint $table) { + $table->id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('jobs'); + Schema::dropIfExists('job_batches'); + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/demo/laravel/database/seeders/DatabaseSeeder.php b/demo/laravel/database/seeders/DatabaseSeeder.php new file mode 100644 index 00000000..d01a0ef2 --- /dev/null +++ b/demo/laravel/database/seeders/DatabaseSeeder.php @@ -0,0 +1,23 @@ +create(); + + User::factory()->create([ + 'name' => 'Test User', + 'email' => 'test@example.com', + ]); + } +} diff --git a/demo/laravel/package.json b/demo/laravel/package.json new file mode 100644 index 00000000..4e934caa --- /dev/null +++ b/demo/laravel/package.json @@ -0,0 +1,13 @@ +{ + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build" + }, + "devDependencies": { + "axios": "^1.6.4", + "laravel-vite-plugin": "^1.0", + "vite": "^5.0" + } +} diff --git a/demo/laravel/public/.htaccess b/demo/laravel/public/.htaccess new file mode 100644 index 00000000..3aec5e27 --- /dev/null +++ b/demo/laravel/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/src/Cli/Prime/Resources/bin/snoreToast/snoretoast-x86.exe b/demo/laravel/public/favicon.ico similarity index 100% rename from src/Cli/Prime/Resources/bin/snoreToast/snoretoast-x86.exe rename to demo/laravel/public/favicon.ico diff --git a/demo/laravel/public/index.php b/demo/laravel/public/index.php new file mode 100644 index 00000000..947d9896 --- /dev/null +++ b/demo/laravel/public/index.php @@ -0,0 +1,17 @@ +handleRequest(Request::capture()); diff --git a/demo/laravel/public/robots.txt b/demo/laravel/public/robots.txt new file mode 100644 index 00000000..eb053628 --- /dev/null +++ b/demo/laravel/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/src/Cli/Prime/Resources/bin/toaster/Microsoft.WindowsAPICodePack.Shell.dll b/demo/laravel/resources/css/app.css similarity index 100% rename from src/Cli/Prime/Resources/bin/toaster/Microsoft.WindowsAPICodePack.Shell.dll rename to demo/laravel/resources/css/app.css diff --git a/demo/laravel/resources/js/app.js b/demo/laravel/resources/js/app.js new file mode 100644 index 00000000..e59d6a0a --- /dev/null +++ b/demo/laravel/resources/js/app.js @@ -0,0 +1 @@ +import './bootstrap'; diff --git a/demo/laravel/resources/js/bootstrap.js b/demo/laravel/resources/js/bootstrap.js new file mode 100644 index 00000000..5f1390b0 --- /dev/null +++ b/demo/laravel/resources/js/bootstrap.js @@ -0,0 +1,4 @@ +import axios from 'axios'; +window.axios = axios; + +window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; diff --git a/demo/laravel/resources/views/components/layouts/app.blade.php b/demo/laravel/resources/views/components/layouts/app.blade.php new file mode 100644 index 00000000..4afe89e3 --- /dev/null +++ b/demo/laravel/resources/views/components/layouts/app.blade.php @@ -0,0 +1,22 @@ + + + + + + + {{ $title ?? 'Page Title' }} + + + + {{ $slot }} + + diff --git a/demo/laravel/resources/views/livewire/counter.blade.php b/demo/laravel/resources/views/livewire/counter.blade.php new file mode 100644 index 00000000..2107cc79 --- /dev/null +++ b/demo/laravel/resources/views/livewire/counter.blade.php @@ -0,0 +1,7 @@ +
+

{{ $count }}

+ + + + +
diff --git a/demo/laravel/resources/views/welcome.blade.php b/demo/laravel/resources/views/welcome.blade.php new file mode 100644 index 00000000..7d713adc --- /dev/null +++ b/demo/laravel/resources/views/welcome.blade.php @@ -0,0 +1,19 @@ + + + + + flash + + + + + diff --git a/demo/laravel/routes/console.php b/demo/laravel/routes/console.php new file mode 100644 index 00000000..eff2ed24 --- /dev/null +++ b/demo/laravel/routes/console.php @@ -0,0 +1,8 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote')->hourly(); diff --git a/demo/laravel/routes/web.php b/demo/laravel/routes/web.php new file mode 100644 index 00000000..ec124176 --- /dev/null +++ b/demo/laravel/routes/web.php @@ -0,0 +1,42 @@ +flash('success', 'Hello from default Symfony'); + + return << + + + + flash + + + + + + HTML; +})->name('app_home'); + +Route::get('/adapter/{adapter}', function (FlasherInterface $flasher, string $adapter) { + $factory = $flasher->create($adapter); + + $factory->success('Operation completed successfully.'); + $factory->info('Please note that some information has been updated.'); + $factory->warning('This action could have potential consequences.'); + $factory->error('An error occurred while processing your request.'); + + return view('welcome'); +})->name('app_adapter'); + +Route::get('/livewire/counter', \App\Livewire\Counter::class); +Route::get('/livewire/eventous', \App\Livewire\Eventous::class); diff --git a/demo/laravel/storage/app/.gitignore b/demo/laravel/storage/app/.gitignore new file mode 100644 index 00000000..8f4803c0 --- /dev/null +++ b/demo/laravel/storage/app/.gitignore @@ -0,0 +1,3 @@ +* +!public/ +!.gitignore diff --git a/demo/laravel/storage/app/public/.gitignore b/demo/laravel/storage/app/public/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/storage/app/public/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/storage/framework/.gitignore b/demo/laravel/storage/framework/.gitignore new file mode 100644 index 00000000..05c4471f --- /dev/null +++ b/demo/laravel/storage/framework/.gitignore @@ -0,0 +1,9 @@ +compiled.php +config.php +down +events.scanned.php +maintenance.php +routes.php +routes.scanned.php +schedule-* +services.json diff --git a/demo/laravel/storage/framework/cache/.gitignore b/demo/laravel/storage/framework/cache/.gitignore new file mode 100644 index 00000000..01e4a6cd --- /dev/null +++ b/demo/laravel/storage/framework/cache/.gitignore @@ -0,0 +1,3 @@ +* +!data/ +!.gitignore diff --git a/demo/laravel/storage/framework/cache/data/.gitignore b/demo/laravel/storage/framework/cache/data/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/storage/framework/cache/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/storage/framework/sessions/.gitignore b/demo/laravel/storage/framework/sessions/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/storage/framework/sessions/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/storage/framework/testing/.gitignore b/demo/laravel/storage/framework/testing/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/storage/framework/testing/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/storage/framework/views/.gitignore b/demo/laravel/storage/framework/views/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/storage/framework/views/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/storage/logs/.gitignore b/demo/laravel/storage/logs/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/demo/laravel/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/demo/laravel/tests/Feature/ExampleTest.php b/demo/laravel/tests/Feature/ExampleTest.php new file mode 100644 index 00000000..8b5843f4 --- /dev/null +++ b/demo/laravel/tests/Feature/ExampleTest.php @@ -0,0 +1,7 @@ +get('/'); + + $response->assertStatus(200); +}); diff --git a/demo/laravel/tests/Pest.php b/demo/laravel/tests/Pest.php new file mode 100644 index 00000000..50ab1e43 --- /dev/null +++ b/demo/laravel/tests/Pest.php @@ -0,0 +1,48 @@ +in('Feature'); + +/* +|-------------------------------------------------------------------------- +| Expectations +|-------------------------------------------------------------------------- +| +| When you're writing tests, you often need to check that values meet certain conditions. The +| "expect()" function gives you access to a set of "expectations" methods that you can use +| to assert different things. Of course, you may extend the Expectation API at any time. +| +*/ + +expect()->extend('toBeOne', function () { + return $this->toBe(1); +}); + +/* +|-------------------------------------------------------------------------- +| Functions +|-------------------------------------------------------------------------- +| +| While Pest is very powerful out-of-the-box, you may have some testing code specific to your +| project that you don't want to repeat in every file. Here you can also expose helpers as +| global functions to help you to reduce the number of lines of code in your test files. +| +*/ + +function something() +{ + // .. +} diff --git a/demo/laravel/tests/TestCase.php b/demo/laravel/tests/TestCase.php new file mode 100644 index 00000000..fe1ffc2f --- /dev/null +++ b/demo/laravel/tests/TestCase.php @@ -0,0 +1,10 @@ +toBeTrue(); +}); diff --git a/demo/laravel/vite.config.js b/demo/laravel/vite.config.js new file mode 100644 index 00000000..421b5695 --- /dev/null +++ b/demo/laravel/vite.config.js @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; + +export default defineConfig({ + plugins: [ + laravel({ + input: ['resources/css/app.css', 'resources/js/app.js'], + refresh: true, + }), + ], +}); diff --git a/demo/symfony b/demo/symfony new file mode 160000 index 00000000..edf662b9 --- /dev/null +++ b/demo/symfony @@ -0,0 +1 @@ +Subproject commit edf662b9de8edb1c8eb369fb65c52f30dfdefada diff --git a/docs/.ackrc b/docs/.ackrc new file mode 100644 index 00000000..82d091f2 --- /dev/null +++ b/docs/.ackrc @@ -0,0 +1,6 @@ +--ignore-dir=vendor +--ignore-dir=yoeunes +--ignore-dir=node_modules +--ignore-dir=.jekyll-cache +--ignore-dir=_site +--ignore-dir=dist diff --git a/docs/.editorconfig b/docs/.editorconfig new file mode 100644 index 00000000..b175ed51 --- /dev/null +++ b/docs/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 120 +tab_width = 4 diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..4bc70eaf --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,10 @@ +node_modules/ +vendor/ + +_site/ + +.jekyll-cache/ + +.idea/ + +/npm-debug.log diff --git a/docs/.ncurc b/docs/.ncurc new file mode 100644 index 00000000..858a9f5c --- /dev/null +++ b/docs/.ncurc @@ -0,0 +1,4 @@ +{ + "upgrade": false, + "target": "semver" +} diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 00000000..531b961e --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +php-flasher.io \ No newline at end of file diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 00000000..ca7c88a8 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,13 @@ +source 'https://rubygems.org' + +gem 'jekyll' +gem 'csv' +gem 'bigdecimal' + +group :jekyll_plugins do + gem 'jekyll-sitemap' + gem 'jekyll-redirect-from' + gem 'jekyll-seo-tag' +end + +gem "webrick", "~> 1.8" diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock new file mode 100644 index 00000000..3ad9d033 --- /dev/null +++ b/docs/Gemfile.lock @@ -0,0 +1,92 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.6) + public_suffix (>= 2.0.2, < 6.0) + bigdecimal (3.1.7) + colorator (1.1.0) + concurrent-ruby (1.2.3) + csv (3.3.0) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + eventmachine (1.2.7) + ffi (1.16.3) + forwardable-extended (2.6.0) + google-protobuf (4.26.1) + rake (>= 13) + google-protobuf (4.26.1-x86_64-linux) + rake (>= 13) + http_parser.rb (0.8.0) + i18n (1.14.4) + concurrent-ruby (~> 1.0) + jekyll (4.3.3) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (~> 1.0) + jekyll-sass-converter (>= 2.0, < 4.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.3, >= 2.3.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (>= 0.3.6, < 0.5) + pathutil (~> 0.9) + rouge (>= 3.0, < 5.0) + safe_yaml (~> 1.0) + terminal-table (>= 1.8, < 4.0) + webrick (~> 1.7) + jekyll-redirect-from (0.16.0) + jekyll (>= 3.3, < 5.0) + jekyll-sass-converter (3.0.0) + sass-embedded (~> 1.54) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-sitemap (1.4.0) + jekyll (>= 3.7, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.4.0) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (5.0.4) + rake (13.1.0) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + rexml (3.2.6) + rouge (4.2.1) + safe_yaml (1.0.5) + sass-embedded (1.72.0) + google-protobuf (>= 3.25, < 5.0) + rake (>= 13.0.0) + sass-embedded (1.72.0-x86_64-linux-gnu) + google-protobuf (>= 3.25, < 5.0) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.5.0) + webrick (1.8.1) + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + bigdecimal + csv + jekyll + jekyll-redirect-from + jekyll-seo-tag + jekyll-sitemap + webrick (~> 1.8) + +BUNDLED WITH + 2.5.6 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..cff51d38 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,7 @@ +# php-flasher.github.io + +```shell +npm install --force +npm run build +bundle exec jekyll serve --livereload +``` diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000..9990a232 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,58 @@ +url: https://php-flasher.io + +title: PHPFlasher + +logo: https://php-flasher.io/static/images/php-flasher-social-card.png + +author: + name: Younes ENNAJI + twitter: yoeunes + url: https://www.linkedin.com/in/younes--ennaji/ + picture: https://php-flasher.io/static/images/php-flasher-social-card.png + +image: + path: https://php-flasher.io/static/images/php-flasher-social-card.png + alt: PHPFlasher + +twitter: + username: phpflasher + image: https://php-flasher.io/static/images/php-flasher-social-card.png + card: summary_large_image + +social: + name: phpflasher + links: + - https://twitter.com/phpflasher + - https://github.com/php-flasher + - https://twitter.com/yoeunes + - https://github.com/yoeunes + - https://www.linkedin.com/in/younes--ennaji/ + +highlighter: none + +plugins: + - jekyll-sitemap + - jekyll-redirect-from + - jekyll-seo-tag + +defaults: + - scope: + path: "" + type: "pages" + values: + layout: "default" + title: + description: + image: https://php-flasher.io/static/images/php-flasher-social-card.png + published_at: "2019-12-01" + updated_at: "2024-03-29" + +exclude: + - "*.config.js" + - "package*.json" + - assets + - _data/manifest.json + - node_modules + - CNAME + - "Gemfile*" + - ".idea" diff --git a/docs/_data/.gitignore b/docs/_data/.gitignore new file mode 100644 index 00000000..92f6b368 --- /dev/null +++ b/docs/_data/.gitignore @@ -0,0 +1 @@ +dev.yml \ No newline at end of file diff --git a/docs/_data/README.md b/docs/_data/README.md new file mode 100644 index 00000000..aa43afed --- /dev/null +++ b/docs/_data/README.md @@ -0,0 +1,6 @@ +You can set the docs in "dev" mode by creating a `dev.yml` file in the +`docs/_data/` directory. It should contain the following contents: + +```yaml +dev_mode: true +``` diff --git a/docs/_data/manifest.json b/docs/_data/manifest.json new file mode 100644 index 00000000..24256386 --- /dev/null +++ b/docs/_data/manifest.json @@ -0,0 +1,21 @@ +{ + "dist/main.css": "/dist/main.c67fa9cf.css", + "dist/main.js": "/dist/main.7736601c.js", + "dist/455.3a7b4474.css": "/dist/455.3a7b4474.css", + "dist/455.17bc016b.js": "/dist/455.17bc016b.js", + "dist/411.29cd993e.css": "/dist/411.29cd993e.css", + "dist/411.42e6794f.js": "/dist/411.42e6794f.js", + "dist/641.c0be7378.css": "/dist/641.c0be7378.css", + "dist/641.f8750364.js": "/dist/641.f8750364.js", + "dist/160.554a2dcd.css": "/dist/160.554a2dcd.css", + "dist/160.264e6e64.js": "/dist/160.264e6e64.js", + "dist/265.396597b6.js": "/dist/265.396597b6.js", + "dist/371.9523a7ff.css": "/dist/371.9523a7ff.css", + "dist/371.324a7072.js": "/dist/371.324a7072.js", + "dist/735.11112420.css": "/dist/735.11112420.css", + "dist/735.3cd4e509.js": "/dist/735.3cd4e509.js", + "dist/243.699ba66f.css": "/dist/243.699ba66f.css", + "dist/243.991d9535.js": "/dist/243.991d9535.js", + "dist/107.6a2ea759.css": "/dist/107.6a2ea759.css", + "dist/107.12087179.js": "/dist/107.12087179.js" +} \ No newline at end of file diff --git a/docs/_data/menu.yml b/docs/_data/menu.yml new file mode 100644 index 00000000..6654f462 --- /dev/null +++ b/docs/_data/menu.yml @@ -0,0 +1,12 @@ + Getting Started: + Introduction: '/' + Symfony: '/symfony/' + Laravel: '/laravel/' + Livewire: '/livewire/' + Inertia: '/inertia/' + + libraries: + Notyf: '/library/notyf/' + Noty: '/library/noty/' + Toastr: '/library/toastr/' + Sweetalert: '/library/sweetalert/' diff --git a/docs/_data/messages.yaml b/docs/_data/messages.yaml new file mode 100644 index 00000000..83159e39 --- /dev/null +++ b/docs/_data/messages.yaml @@ -0,0 +1,283 @@ +types: + - success + - error + - warning + - info + +success: + - "Operation completed successfully." + - "Task completed successfully." + - "Your request was processed successfully." + - "The operation was successful." + - "Great success!" + - "The action was completed successfully." + - "Your submission has been received successfully." + - "The process was completed successfully." + - "The operation completed successfully." + - "Your account has been created!" + - "Your password has been reset." + - "Your payment was processed successfully." + - "Your profile has been updated." + - "Your item has been added to your cart." + - "Your order has been placed." + - "Your file has been uploaded." + - "Your request has been received." + - "Your reservation has been confirmed." + - "Your question has been submitted." + - "Your application has been received." + - "Your subscription has been activated." + - "Your account has been verified." + - "Your message has been sent." + - "Your feedback has been submitted." + - "Your password has been changed." + - "Your account has been linked." + - "Your email has been verified." + - "Your address has been updated." + - "Your payment has been accepted." + - "Your account has been unlinked." + - "Your subscription has been cancelled." + - "Your account has been deactivated." + - "Your form has been submitted." + - "Your product has been shipped." + - "Your feedback has been received." + - "Your information has been saved." + - "Your password has been set." + - "Your account has been reactivated." + - "Your message has been received." + - "Your account has been terminated." + - "Your order has been shipped." + - "Your account has been suspended." + - "Your contact has been added." + - "Your donation has been received." + - "Your review has been posted." + - "Your report has been generated." + - "Your device has been registered." + - "Your account has been unlocked." + - "Your review has been submitted." + - "Your account has been de-registered." + - "Your contact has been removed." + - "Your account has been locked." + - "Your account has been reinstated." + - "Your account has been un-suspended." + - "Your account has been reactivated." + - "Your account has been restored." + - "Your account has been re-activated." + - "Your account has been un-terminated." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + - "Your account has been restored." + - "Your account has been re-verified." + - "Your account has been re-activated." + +error: + - "Error!" + - "An error occurred." + - "There was a problem processing your request." + - "Something went wrong." + - "The operation failed." + - "Sorry, something went wrong." + - "Oops, something went wrong." + - "An error has occurred." + - "We’re sorry, but an error occurred." + - "An unexpected error occurred." + - "An error occurred while creating your account." + - "There was a problem resetting your password." + - "There was an issue processing your payment." + - "There was a problem updating your profile." + - "There was an issue adding your item to the cart." + - "There was a problem placing your order." + - "There was an issue uploading your file." + - "There was a problem receiving your request." + - "There was an issue confirming your reservation." + - "There was a problem submitting your question." + - "There was an issue receiving your application." + - "There was a problem activating your subscription." + - "There was an issue verifying your account." + - "There was a problem sending your message." + - "There was an issue submitting your feedback." + - "There was a problem changing your password." + - "There was an issue linking your account." + - "There was a problem verifying your email." + - "There was an issue updating your address." + - "There was a problem accepting your payment." + - "There was an issue un-linking your account." + - "There was a problem cancelling your subscription." + - "There was an issue deactivating your account." + - "There was a problem submitting your form." + - "There was an issue shipping your product." + - "There was a problem receiving your feedback." + - "There was an issue saving your information." + - "There was a problem setting your password." + - "There was an issue reactivating your account." + - "There was a problem receiving your message." + - "There was an issue terminating your account." + - "There was a problem shipping your order." + - "There was an issue suspending your account." + - "There was a problem adding your contact." + - "There was an issue receiving your donation." + - "There was a problem posting your review." + - "There was an issue generating your report." + - "There was a problem registering your device." + - "There was an issue unlocking your account." + - "There was a problem submitting your review." + - "There was an issue de-registering your account." + - "There was a problem removing your contact." + - "There was an issue locking your account." + - "There was a problem reinstating your account." + - "There was an issue un-suspending your account." + - "There was a problem reactivating your account." + - "There was an issue restoring your account." + - "There was a problem re-activating your account." + - "There was an issue un-terminating your account." + - "There was a problem re-verifying your account." + - "There was an issue re-activating your account." + - "There was a problem restoring your account." + - "There was an issue re-verifying your account." + - "There was a problem re-activating your account." + - "There was an issue restoring your account." + - "There was a problem re-verifying your account." + - "There was an issue re-activating your account." + - "There was a problem restoring your account." + - "There was an issue re-verifying your account." + - "There was a problem re-activating your account." + - "There was an issue restoring your account." + +warning: + - "Warning: This cannot be undone." + - "Caution: May have unintended consequences." + - "Exercise caution when performing this action." + - "This may have unintended consequences. Proceed with caution." + - "Warning: This may be irreversible." + - "Caution: May have unintended results." + - "Warning: Proceed with caution." + - "Your account may have been compromised." + - "Your password may be at risk." + - "Your payment may not have been processed." + - "Your profile may not have been updated." + - "Your item may not have been added to the cart." + - "Your order may not have been placed." + - "Your file may not have been uploaded." + - "Your request may not have been received." + - "Your reservation may not have been confirmed." + - "Your question may not have been submitted." + - "Your application may not have been received." + - "Your subscription may not have been activated." + - "Your account may not have been verified." + - "Your message may not have been sent." + - "Your feedback may not have been submitted." + - "Your password may not have been changed." + - "Your account may not have been linked." + - "Your email may not have been verified." + - "Your address may not have been updated." + - "Your payment may not have been accepted." + - "Your account may not have been unlinked." + - "Your subscription may not have been cancelled." + - "Your account may not have been deactivated." + - "Your form may not have been submitted." + - "Your product may not have been shipped." + - "Your feedback may not have been received." + - "Your information may not have been saved." + - "Your password may not have been set." + - "Your account may not have been reactivated." + - "Your message may not have been received." + - "Your account may not have been terminated." + - "Your order may not have been shipped." + - "Your account may not have been suspended." + - "Your contact may not have been added." + - "Your donation may not have been received." + - "Your review may not have been posted." + - "Your report may not have been generated." + - "Your device may not have been registered." + - "Your account may not have been unlocked." + - "Your review may not have been submitted." + - "Your account may not have been de-registered." + - "Your contact may not have been removed." + - "Your account may not have been locked." + - "Your account may not have been reinstated." + - "Your account may not have been un-suspended." + - "Your account may not have been reactivated." + - "Your account may not have been restored." + - "Your account may not have been re-activated." + - "Your account may not have been un-terminated." + - "Your account may not have been re-verified." + - "Your account may not have been re-activated." + - "Your account may not have been restored." + - "Your account may not have been re-verified." + - "Your account may not have been re-activated." + - "Your account may not have been restored." + - "Your account may not have been re-verified." + - "Your account may not have been re-activated." + +info: + - "Heads up: This may take a while." + - "This may take some time. Please be patient." + - "This may take a while. Do not refresh the page." + - "Heads up: This may take a while. Be patient." + - "This may take some time. Do not refresh the page." + - "Your account has been created, but requires verification." + - "Your password has been reset and a new one has been sent to your email." + - "Your payment has been processed, but may take a few days to reflect on your account." + - "Your profile has been updated, but some changes may require verification." + - "Your item has been added to your cart, but may not be reserved until checkout." + - "Your order has been placed and is being processed." + - "Your file has been uploaded and is being processed." + - "Your request has been received and is being processed." + - "Your reservation has been confirmed and a confirmation email has been sent." + - "Your question has been submitted and is being reviewed." + - "Your application has been received and is being reviewed." + - "Your subscription has been activated and a confirmation email has been sent." + - "Your account has been verified and is now active." + - "Your message has been sent and a confirmation email has been sent." + - "Your feedback has been submitted and is being reviewed." + - "Your password has been changed and a confirmation email has been sent." + - "Your account has been linked and a confirmation email has been sent." + - "Your email has been verified and a confirmation email has been sent." + - "Your address has been updated and a confirmation email has been sent." + - "Your payment has been accepted and a confirmation email has been sent." + - "Your account has been unlinked and a confirmation email has been sent." + - "Your subscription has been cancelled and a confirmation email has been sent." + - "Your account has been deactivated and a confirmation email has been sent." + - "Your form has been submitted and is being processed." + - "Your product has been shipped and a tracking number has been sent to your email." + - "Your feedback has been received and is being reviewed." + - "Your information has been saved and a confirmation email has been sent." + - "Your password has been set and a confirmation email has been sent." + - "Your account has been reactivated and a confirmation email has been sent." + - "Your message has been received and is being processed." + - "Your account has been terminated and a confirmation email has been sent." + - "Your order has been shipped and a tracking number has been sent to your email." + - "Your account has been suspended and a confirmation email has been sent." + - "Your contact has been added and a confirmation email has been sent." + - "Your donation has been received and a confirmation email has been sent." + - "Your review has been posted and is being reviewed." + - "Your report has been generated and a confirmation email has been sent." + - "Your device has been registered and a confirmation email has been sent." + - "Your account has been unlocked and a confirmation email has been sent." + - "Your review has been submitted and is being reviewed." + - "Your account has been de-registered and a confirmation email has been sent." + - "Your contact has been removed and a confirmation email has been sent." + - "Your account has been locked and a confirmation email has been sent." + - "Your account has been reinstated and a confirmation email has been sent." + - "Your account has been un-suspended and a confirmation email has been sent." + - "Your account has been reactivated and a confirmation email has been sent." diff --git a/docs/_data/project.yml b/docs/_data/project.yml new file mode 100644 index 00000000..0786592c --- /dev/null +++ b/docs/_data/project.yml @@ -0,0 +1,5 @@ +version: "2.x" + +title: "Easily add flash messages to your #Laravel or #Symfony projects with PHPFlasher - a powerful, easy-to-use package for improved user engagement & experience" + +description: "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution." diff --git a/docs/_includes/_installation.md b/docs/_includes/_installation.md new file mode 100644 index 00000000..4d65757e --- /dev/null +++ b/docs/_includes/_installation.md @@ -0,0 +1,36 @@ +## Installation + +{% PHPFlasher %} is modular and consists of multiple libraries, +allowing users to install and use only the specific components they need for their project. + +{% PHPFlasher %} can be installed using composer : + +{% if 'laravel' == framework %} + +** Laravel**: +```shell +composer require php-flasher/flasher-laravel +``` + +{% else %} + +** Symfony**: +```shell +{{ framework }} +composer require php-flasher/flasher-symfony +``` + +{% endif %} + +--- + +{% PHPFlasher %} includes a default notification style , but users can also install additional adapters to customize the appearance of notifications within their projects such as : + +* **[Toastr](/library/toastr/)** +* **[Noty](/library/noty/)** +* **[Notyf](/library/notyf/)** +* **[Sweet Alert](/library/sweetalert/)** + +--- + +{% include _usage.md %} diff --git a/docs/_includes/_usage.md b/docs/_includes/_usage.md new file mode 100644 index 00000000..58a7a7b5 --- /dev/null +++ b/docs/_includes/_usage.md @@ -0,0 +1,366 @@ +## Usage + +To display a notification message, you can either use the `flash()` helper method or obtain an instance of `flasher` from the service container. +Then, before returning a view or redirecting, call the `success()` method and pass in the desired message to be displayed. + +{% assign id = '#/ PHPFlasher' %} +{% assign type = 'success' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +class BookController +{ + public function saveBook() + { + // ... + + flash('{{ message }}'); + + flash()->success('{{ site.data.messages["success"] | sample }}'); + + // ... redirect or render the view + } + + /** + * if you prefer to use dependency injection + */ + public function register(FlasherInterface $flasher) + { + // ... + + $flasher->success('{{ site.data.messages["success"] | sample }}'); + + // ... redirect or render the view + } +} +``` + +
+ +It's important to choose a message that is clear and concise, and that accurately reflects the outcome of the operation.
+In this case, `"Book has been created successfully!"` is already a good message, +but you may want to tailor it to fit the specific context and language of your application. + +> Using this package is actually pretty easy. Adding notifications to your application actually require only one line of code. + +{% assign id = '#/ usage success' %} +{% assign type = 'success' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ usage error' %} +{% assign type = 'error' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ usage warning' %} +{% assign type = 'warning' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ usage info' %} +{% assign type = 'info' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +--- + +These four methods `success()`, `error()`, `warning()`, `info()` are simply convenience shortcuts for the `flash()` method, +allowing you to specify the `type` and `message` in a single method call rather than having to pass both as separate arguments to the `flash()` method. + +```php +flash()->flash(string $type, string $message, string $title = null, array $options = []) +``` + +{% assign id = '#/ usage flash' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->flash('{{ type }}', '{{ message }}'); +``` + +| param | description | +|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `$type` | Notification type : success, error, warning, info ....etc | +| `$message` | The body of the message you want to deliver to your user. This may contain HTML. If you add links, be sure to add the appropriate classes for the framework you are using. | +| `$title` | The notification title, Can also include HTML | +| `$options` | Custom options for javascript libraries (toastr, noty, notyf ...etc) | | + + +--- + +## Modifiers + +

options

+ +You can specify **custom options** for the flash messages when using a JavaScript library like `toastr`, `noty`, or `notyf`.

+The `options()` method allows you to set multiple options at once by passing an array of `key-value` pairs, +while the `option()` method allows you to set a single option by specifying its name and value as separate arguments.

+The optional `$merge` argument for the `options()` method can be used to specify whether the new options should be merged with any existing options, +or whether they should overwrite them. + +```php +flash()->options(array $options, bool $merge = true); +``` + +> Refer to the documentation for your chosen JavaScript library to see which options are available and how they should be formatted. + +{% assign id = '#/ usage options' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeout": 3000, "position": "top-center"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->options([ + 'timeout' => 3000, // 3 seconds + 'position' => 'top-center', + ]) + ->{{ type }}('{{ message }}'); +``` + +| param | description | +|------------|--------------------------------------------------------------------------------------| +| `$options` | Custom options to be passed to the javascript libraries (toastr, noty, notyf ...etc) | +| `$merge` | Merge options if you call the options method multiple times | + +--- + +

option

+ +Set a single option by specifying its name and value as separate arguments. + +```php +flash()->option(string $option, mixed $value); +``` + +{% assign id = '#/ usage option' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeout": 3000, "position": "bottom-right"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->option('position', 'bottom-right') + ->option('timeout', 3000) + ->{{ type }}('{{ message }}'); +``` + +| param | description | +|-----------|--------------| +| `$option` | Option key | +| `$value` | Option value | + +--- + +

priority

+ +Sets the priority of a flash message, the highest priority will be displayed first. + +```php +flash()->priority(int $priority); +``` + +{% assign id = '#/ usage priority' %} +{% assign successMessage = site.data.messages['success'] | sample | prepend: 'Priority 3 → ' %} +{% assign errorMessage = site.data.messages['error'] | sample | prepend: 'Priority 1 → ' %} +{% assign warningMessage = site.data.messages['warning'] | sample | prepend: 'Priority 4 → ' %} +{% assign infoMessage = site.data.messages['info'] | sample | prepend: 'Priority 2 → ' %} + + + +```php +{{ id }} + +flash() + ->priority(3) + ->success('{{ successMessage }}'); + +flash() + ->priority(1) + ->error('{{ errorMessage }}'); + +flash() + ->priority(4) + ->warning('{{ warningMessage }}'); + +flash() + ->priority(2) + ->info('{{ infoMessage }}'); +``` + +| param | description | +|-------------|--------------------------------------------------------------------------------------------| +| `$priority` | The priority of the notification, the higher the priority, the sooner it will be displayed | + +--- + +

hops

+ +This method sets the number of requests that the flash message should persist for. By default, flash messages are only displayed for a single request and are then discarded. By setting the number of hops, the flash message will be persisted for multiple requests. + +As an example, with a multi-page form, you may want to store messages until all pages have been filled. + +{% assign id = '#/ usage hops' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +flash()->hops(int $hops); +``` + +```php +flash() + ->hops(2) + ->{{ type }}('{{ message }}'); +``` + +| param | description | +|---------|---------------------------------------------------------------| +| `$hops` | indicate how many requests the flash message will persist for | + +--- + +

translate

+ +This method sets the `locale` to be used for the translation of the flash message. If a non-null value is provided, +the flash message will be translated into the specified language. If null is provided, the **default** `locale` will be used. + +```php +flash()->translate(string $locale = null); +``` + +{% assign id = '#/ usage translate' %} +{% assign type = 'success' %} +{% assign message = 'تمت العملية بنجاح.' %} +{% assign title = 'تهانينا' %} +{% assign options = '{"rtl": true, "position": "top-right"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->translate('ar') + ->{{ type }}('Your request was processed successfully.', 'Congratulations!'); +``` + +{% assign id = '#/ usage translate with position' %} +{% assign type = 'success' %} +{% assign message = 'تمت العملية بنجاح.' %} +{% assign title = 'تهانينا' %} +{% assign options = '{"rtl": true, "position": "top-left"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->translate('ar') + ->option('position', 'top-left') + ->{{ type }}('Your request was processed successfully.', 'Congratulations!'); +``` + +| param | description | +|-----------|------------------------------------------------------------------------------| +| `$locale` | The locale to be used for the translation, or null to use the default locale | + +It is **important** to note that the `translate()` method only sets the locale to be used for the translation of the flash message. +It does not actually perform the translation itself. + +In order to translate the flash message, you will need to provide the appropriate translation keys in your translation files. + +{% if page.framework == 'laravel' %} + +In the above example, to translate the flash message into `Arabic`, you will need to add the following keys to the `resources/lang/ar/messages.php` file: + +```php +return [ + 'Your request was processed successfully.' => 'تمت العملية بنجاح.', + 'Congratulations!' => 'تهانينا', +]; +``` + +{% elsif page.framework == 'symfony' %} + +In the above example, to translate the flash message into `Arabic`, you will need to add the following keys to the `translations/messages.ar.yaml` file: + +```yaml +Your request was processed successfully.: 'تمت العملية بنجاح.' +Congratulations!: 'تهانينا' +``` + +{% endif %} + diff --git a/docs/_includes/example.html b/docs/_includes/example.html new file mode 100644 index 00000000..d1e9e4e3 --- /dev/null +++ b/docs/_includes/example.html @@ -0,0 +1,15 @@ +{% assign defaultId = 'PHPFlasher' %} +{% assign defaultHandler = 'flasher' %} +{% assign defaultType = site.data.messages.types | sample %} +{% assign defaultMessage = site.data.messages[type] | sample %} +{% assign defaultOptions = '{}' %} + + diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html new file mode 100644 index 00000000..2ee16065 --- /dev/null +++ b/docs/_includes/footer.html @@ -0,0 +1,8 @@ +
+
+ Younes +

+ PHPFlasher is a project by Younes ENNAJI. +

+
+
diff --git a/docs/_includes/head.html b/docs/_includes/head.html new file mode 100644 index 00000000..64acbeb4 --- /dev/null +++ b/docs/_includes/head.html @@ -0,0 +1,65 @@ + + + + +{% if page.title %}{{ page.title }} | {% endif %}PHPFlasher + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% unless site.data.dev.dev_mode %} + + + +{% endunless %} diff --git a/docs/_includes/homepage-links.html b/docs/_includes/homepage-links.html new file mode 100644 index 00000000..d01d0d13 --- /dev/null +++ b/docs/_includes/homepage-links.html @@ -0,0 +1,31 @@ +

+ Docs + GitHub + Twitter +

+ +

+ + Author + + + Source + + + GitHub release + + + License + + + Packagist + + + PHP Version + + +

diff --git a/docs/_includes/prev-next.html b/docs/_includes/prev-next.html new file mode 100644 index 00000000..a3f8bf5f --- /dev/null +++ b/docs/_includes/prev-next.html @@ -0,0 +1,11 @@ + diff --git a/docs/_includes/size-helper.html b/docs/_includes/size-helper.html new file mode 100644 index 00000000..0817399f --- /dev/null +++ b/docs/_includes/size-helper.html @@ -0,0 +1,9 @@ +{% if site.data.dev.dev_mode %} +
+ < sm + + + + +
+{% endif %} diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 00000000..fed3dfcc --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,81 @@ + + + + {% include head.html %} + + + {% include size-helper.html %} + + {% if site.data.dev.dev_mode %} +
+ {% endif %} + + + +
+ +
+ + +
+

+ If you find PHPFlasher useful, + we would greatly appreciate your support in the form of a star rating ⭐ + on GitHub + or by sharing the project on Twitter click here. + Your feedback helps us keep the package up-to-date and well-maintained. Thank you +

+
+ +
+ + {{ content }} + + +
+ +
+ + {% include footer.html %} + + diff --git a/docs/_plugins/php_flasher_tag.rb b/docs/_plugins/php_flasher_tag.rb new file mode 100644 index 00000000..e7454508 --- /dev/null +++ b/docs/_plugins/php_flasher_tag.rb @@ -0,0 +1,9 @@ +module Jekyll + class PHPFlasherTag < Liquid::Tag + def render(context) + 'PHPFlasher' + end + end +end + +Liquid::Template.register_tag('PHPFlasher', Jekyll::PHPFlasherTag) diff --git a/docs/assets/controllers.json b/docs/assets/controllers.json new file mode 100644 index 00000000..a1c6e90c --- /dev/null +++ b/docs/assets/controllers.json @@ -0,0 +1,4 @@ +{ + "controllers": [], + "entrypoints": [] +} diff --git a/docs/assets/js/controllers/anchor_controller.js b/docs/assets/js/controllers/anchor_controller.js new file mode 100644 index 00000000..5a546318 --- /dev/null +++ b/docs/assets/js/controllers/anchor_controller.js @@ -0,0 +1,94 @@ +import { Controller } from '@hotwired/stimulus' + +export default class extends Controller { + connect() { + const container = document.querySelector('#anchor-navigation') + + createAnchorNavigation() + highlightCurrentAnchor() + stickyHeight() + + const links = document.querySelectorAll('a.anchor, #anchor-navigation ul li a') + links.forEach((anchor) => { + anchor.addEventListener('click', (event) => { + event.preventDefault() + + window.location.hash = anchor.hash + highlightCurrentAnchor(anchor.hash) + }) + }) + + function createAnchorNavigation() { + const ul = document.querySelector('#anchor-navigation ul') + const anchors = document.querySelectorAll('#main-article h3, #main-article h2, #main-article a.anchor') + + if (anchors.length === 0) { + container.remove() + return + } + + container.classList.add('lg:block') + + anchors.forEach((anchor) => { + const parent = anchor.parentElement + parent.classList.add('px-6', 'rounded') + + anchor.classList.add('leading-loose') + + const link = document.createElement('a') + link.href = anchor.tagName === 'A' ? anchor.hash : `#${anchor.getAttribute('id')}` + link.innerHTML = anchor.tagName === 'A' ? anchor.textContent : `${anchor.textContent}` + link.classList.add('leading-loose', 'text-md', 'inline-block', 'w-full', 'text-indigo-500') + + const li = document.createElement('li') + li.classList.add('px-6', 'rounded', 'w-full') + if (anchor.tagName === 'A') { + li.classList.remove('px-6') + li.classList.add('px-12') + } + + li.appendChild(link) + + ul.appendChild(li) + }) + } + + function highlightCurrentAnchor(hash) { + if (typeof hash === 'undefined') { + hash = window.location.hash + } + + const links = document.querySelectorAll('a.anchor, #anchor-navigation ul li a') + links.forEach((link) => { + const parent = link.parentElement + link.classList.remove('text-gray-900') + link.classList.add('text-indigo-500') + parent.classList.remove('bg-indigo-500') + + if (hash === link.hash) { + link.classList.remove('text-indigo-500') + link.classList.add('text-white') + + parent.classList.add('bg-indigo-500') + } + }) + } + + function stickyHeight() { + const article = document.querySelector('#main-article') + const elements = document.querySelectorAll('.sticky') + + elements.forEach((element) => { + if (element.offsetHeight <= window.innerHeight || article.clientHeight <= element.offsetHeight) { + return + } + + const div = document.createElement('div') + div.classList.add('h-screen', 'overflow-y-auto') + div.innerHTML = element.innerHTML + + element.innerHTML = div.outerHTML + }) + } + } +} diff --git a/docs/assets/js/controllers/clipboard.pcss b/docs/assets/js/controllers/clipboard.pcss new file mode 100644 index 00000000..8261e4af --- /dev/null +++ b/docs/assets/js/controllers/clipboard.pcss @@ -0,0 +1,28 @@ +pre.copyable { + position: relative; +} + +pre.copyable .copy { + //display: none; + position: absolute; + right: 1.5rem; + top: 0.85rem; +} + +pre.copyable:hover .copy { + display: block; +} + +pre.copyable .copy i { + font-size: 1.5rem; +} + +pre.copyable .copy:active { + transform: translateY(3px); +} + +@media (max-width: 768px) { + pre.copyable:hover .copy { + display: none; + } +} diff --git a/docs/assets/js/controllers/clipboard_controller.js b/docs/assets/js/controllers/clipboard_controller.js new file mode 100644 index 00000000..8f7f4303 --- /dev/null +++ b/docs/assets/js/controllers/clipboard_controller.js @@ -0,0 +1,41 @@ +import { Controller } from '@hotwired/stimulus' + +import './clipboard.pcss' + +export default class extends Controller { + connect() { + const codeBlocks = document.querySelectorAll('pre > code') + + codeBlocks.forEach((codeBlock) => { + const button = document.createElement('button') + button.classList.add('copy', 'text-indigo-500') + button.type = 'button' + button.ariaLabel = button.title = 'Copy code to clipboard' + + const icon = '' + button.innerHTML = icon + + const parent = codeBlock.parentElement + parent.classList.add('copyable') + + parent.append(button) + + button.addEventListener('click', () => { + let code = codeBlock.textContent.trim() + if (code.startsWith('#')) { + const parts = code.split('\n') + parts.shift() + code = parts.join('\n') + } + + window.navigator.clipboard.writeText(code) + + button.innerHTML = '' + + setTimeout(() => { + button.innerHTML = icon + }, 1000) + }) + }) + } +} diff --git a/docs/assets/js/controllers/flasher_controller.js b/docs/assets/js/controllers/flasher_controller.js new file mode 100644 index 00000000..59d7ddf6 --- /dev/null +++ b/docs/assets/js/controllers/flasher_controller.js @@ -0,0 +1,10 @@ +import { Controller } from '@hotwired/stimulus' +import { showNotificationsForHandler } from '../show_notifications' + +import '@flasher/flasher/dist/flasher.min.css' + +export default class extends Controller { + connect() { + showNotificationsForHandler('flasher') + } +} diff --git a/docs/assets/js/controllers/navigation.pcss b/docs/assets/js/controllers/navigation.pcss new file mode 100644 index 00000000..779fd77b --- /dev/null +++ b/docs/assets/js/controllers/navigation.pcss @@ -0,0 +1,15 @@ +.menu-closed\:shown { + @apply hidden; +} + +.menu-closed .menu-closed\:shown { + @apply inline; +} + +.menu-closed .menu-closed\:hidden { + @apply hidden; +} + +#main-navigation li a.text-white i { + color: #fff; +} diff --git a/docs/assets/js/controllers/navigation_controller.js b/docs/assets/js/controllers/navigation_controller.js new file mode 100644 index 00000000..cad00d72 --- /dev/null +++ b/docs/assets/js/controllers/navigation_controller.js @@ -0,0 +1,26 @@ +import { Controller } from '@hotwired/stimulus' + +import './navigation.pcss' + +export default class extends Controller { + connect() { + const menuBtn = document.getElementById('menu-toggle') + const navigation = document.getElementById('main-navigation') + const article = document.getElementById('main-article') + + function toggleClassName(el, className) { + if (el.classList.contains(className)) { + el.classList.remove(className) + } else { + el.classList.add(className) + } + } + + menuBtn.addEventListener('click', (e) => { + e.preventDefault() + toggleClassName(menuBtn, 'menu-closed') + toggleClassName(navigation, 'hidden') + toggleClassName(article, 'hidden') + }) + } +} diff --git a/docs/assets/js/controllers/noty_controller.js b/docs/assets/js/controllers/noty_controller.js new file mode 100644 index 00000000..f71d30a3 --- /dev/null +++ b/docs/assets/js/controllers/noty_controller.js @@ -0,0 +1,11 @@ +import { Controller } from '@hotwired/stimulus' +import { showNotificationsForHandler } from '../show_notifications' + +import 'noty/lib/noty.css' +import 'noty/lib/themes/mint.css' + +export default class extends Controller { + connect() { + showNotificationsForHandler('noty') + } +} diff --git a/docs/assets/js/controllers/notyf_controller.js b/docs/assets/js/controllers/notyf_controller.js new file mode 100644 index 00000000..54858530 --- /dev/null +++ b/docs/assets/js/controllers/notyf_controller.js @@ -0,0 +1,10 @@ +import { Controller } from '@hotwired/stimulus' +import { showNotificationsForHandler } from '../show_notifications' + +import '@flasher/flasher-notyf/dist/flasher-notyf.min.css' + +export default class extends Controller { + connect() { + showNotificationsForHandler('notyf') + } +} diff --git a/docs/assets/js/controllers/prev-next_controller.js b/docs/assets/js/controllers/prev-next_controller.js new file mode 100644 index 00000000..aa803adb --- /dev/null +++ b/docs/assets/js/controllers/prev-next_controller.js @@ -0,0 +1,46 @@ +import { Controller } from '@hotwired/stimulus' + +export default class extends Controller { + connect() { + const prevNext = document.querySelectorAll('.prev-next') + const navigation = document.getElementById('main-navigation') + const navigationLinks = navigation.querySelectorAll('a') + + let previous + let next + let active + + function renderPreviousNext(which, originalLink) { + const links = document.querySelectorAll(which) + + links.forEach((link) => { + const label = link.querySelector('span') + label.innerHTML = originalLink.innerHTML.replace(/\d+\. /, '').replace(/<(\S*?)[^>]*>.*?<\/\1>|<.*?\/>/, '') + link.href = originalLink.href + link.classList.remove('hidden') + link.classList.remove('sm:hidden') + }) + } + + navigationLinks.forEach((link) => { + if (next !== undefined || link.href.includes('/docs/') === false) { + return + } + if (link.classList.contains('text-white')) { + active = link + } else if (active === undefined) { + previous = link + } else if (next === undefined) { + next = link + } + }) + + if (active !== undefined) { + prevNext.forEach((p) => { + p.classList.remove('hidden') + }) + previous && renderPreviousNext('.link-previous', previous) + next && renderPreviousNext('.link-next', next) + } + } +} diff --git a/docs/assets/js/controllers/ray_controller.js b/docs/assets/js/controllers/ray_controller.js new file mode 100644 index 00000000..5dcf4055 --- /dev/null +++ b/docs/assets/js/controllers/ray_controller.js @@ -0,0 +1,9 @@ +import { Controller } from '@hotwired/stimulus' + +import { ray } from 'node-ray/web' + +export default class extends Controller { + initialize() { + window.ray = ray + } +} diff --git a/docs/assets/js/controllers/sweetalert_controller.js b/docs/assets/js/controllers/sweetalert_controller.js new file mode 100644 index 00000000..338f7a37 --- /dev/null +++ b/docs/assets/js/controllers/sweetalert_controller.js @@ -0,0 +1,10 @@ +import { Controller } from '@hotwired/stimulus' +import { showNotificationsForHandler } from '../show_notifications' + +import 'sweetalert2/dist/sweetalert2.min.css' + +export default class extends Controller { + connect() { + showNotificationsForHandler('sweetalert') + } +} diff --git a/docs/assets/js/controllers/toastr_controller.js b/docs/assets/js/controllers/toastr_controller.js new file mode 100644 index 00000000..516c778f --- /dev/null +++ b/docs/assets/js/controllers/toastr_controller.js @@ -0,0 +1,10 @@ +import { Controller } from '@hotwired/stimulus' +import { showNotificationsForHandler } from '../show_notifications' + +import 'toastr/build/toastr.min.css' + +export default class extends Controller { + connect() { + showNotificationsForHandler('toastr') + } +} diff --git a/docs/assets/js/controllers/tryit.pcss b/docs/assets/js/controllers/tryit.pcss new file mode 100644 index 00000000..2f9c665f --- /dev/null +++ b/docs/assets/js/controllers/tryit.pcss @@ -0,0 +1,40 @@ +pre.tryable { + position: relative; +} + +pre.tryable .tryit { + position: absolute; + right: 4rem; + top: 0.85rem; +} + +pre.tryable:hover .tryit { + display: inline-block; +} + +pre.tryable .tryit i { + font-size: 1.5rem; +} + +pre.tryable .tryit:active { + transform: translateY(3px); +} + +@media (max-width: 768px) { + pre.tryable:hover .tryit { + display: none; + } +} + +pre.tryable .spin { + animation: spin 1s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/docs/assets/js/controllers/tryit_controller.js b/docs/assets/js/controllers/tryit_controller.js new file mode 100644 index 00000000..d21daeae --- /dev/null +++ b/docs/assets/js/controllers/tryit_controller.js @@ -0,0 +1,87 @@ +import { Controller } from '@hotwired/stimulus' + +import './tryit.pcss' + +import flasher from '@flasher/flasher' +import '@flasher/flasher-toastr' +import '@flasher/flasher-noty' +import '@flasher/flasher-notyf' +import '@flasher/flasher-sweetalert' + +window.flasher = flasher + +export default class extends Controller { + connect() { + this.initializeCodeBlocks() + } + + initializeCodeBlocks() { + document.querySelectorAll('pre > code').forEach((codeBlock) => { + if (codeBlock.textContent.trim().startsWith('#/')) { + this.addTryItButtonToCodeBlock(codeBlock) + } + }) + } + + addTryItButtonToCodeBlock(codeBlock) { + const button = document.createElement('button') + button.className = 'tryit text-indigo-500' + button.type = 'button' + button.ariaLabel = button.title = 'Try it!' + button.innerHTML = '' + codeBlock.parentElement.classList.add('tryable') + codeBlock.parentElement.append(button) + + button.addEventListener('click', () => this.handleTryItButtonClick(button, codeBlock.textContent.trim())) + } + + handleTryItButtonClick(button, code) { + button.innerHTML = '' + const themes = this.defineThemes() + const example = code.split('\n')[0].trim() + + try { + if (example === '#/ flasher darkMode') { + this.toggleDarkMode(example) + } else if (example in themes) { + this.applyTheme(example, themes) + } else if (Array.isArray(window.messages[example])) { + window.messages[example].forEach(this.flash.bind(this)) + } else { + this.flash(window.messages[example]) + } + } catch (error) { + console.error(error) + } finally { + setTimeout(() => (button.innerHTML = ''), 500) + } + } + + toggleDarkMode(example) { + document.documentElement.classList.add('dark') + this.flash(window.messages[example]) + setTimeout(() => document.documentElement.classList.remove('dark'), 5000) + } + + applyTheme(example, themes) { + import(`noty/lib/themes/${themes[example]}`).then(() => { + window.messages[example].forEach(this.flash.bind(this)) + }) + } + + defineThemes() { + return { + '#/ noty theme sunset': 'sunset.css', + '#/ noty theme relax': 'relax.css', + '#/ noty theme light': 'light.css', + '#/ noty theme metroui': 'metroui.css', + } + } + + flash({ handler, type, message, title, options }) { + const factory = flasher.use(handler) + if (factory) { + factory.flash(type, message, title, options) + } + } +} diff --git a/docs/assets/js/main.js b/docs/assets/js/main.js new file mode 100644 index 00000000..a5c57c44 --- /dev/null +++ b/docs/assets/js/main.js @@ -0,0 +1,3 @@ +import './stimulus' + +import './main.pcss' diff --git a/docs/assets/js/main.pcss b/docs/assets/js/main.pcss new file mode 100644 index 00000000..a3c1f3c3 --- /dev/null +++ b/docs/assets/js/main.pcss @@ -0,0 +1,132 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +hr { + @apply border-b border-t border-indigo-100 mt-10 mb-8 opacity-75 w-1/2 mx-auto; + border-bottom-color: #fff; +} + +body { + @apply text-gray-600; + font-size: 15px; + font-weight: 400; + font-stretch: 100%; + -webkit-font-smoothing: antialiased; + font-smoothing: antialiased; +} + +h1, +h2, +h3 { + font-weight: normal; + @apply font-semibold my-6; +} + +img { + @apply inline; + vertical-align: initial; +} + +a { + @apply text-indigo-600; +} + +p, +ul { + @apply mb-4; +} + +pre { + @apply relative py-2 px-4 rounded; +} + +:focus { + outline: none; +} + +.focus\:placeholder-none:focus::placeholder { + opacity: 0; +} + +article h1 { + @apply text-indigo-600 text-4xl leading-tight; +} + +article h2 { + @apply text-indigo-600 text-2xl; +} + +article h3 { + @apply text-indigo-600 text-xl mt-6; +} + +article table { + @apply table-auto text-left p-4 bg-white mb-4 shadow-md; + width: calc(100% + 2rem); + border-spacing: 0; + border-collapse: collapse; +} + +article table thead { + @apply min-w-full; +} + +article p, +article table { + @apply mb-6 max-w-full relative p-0 break-normal; +} + +article table td { + @apply border-t border-gray-900; +} + +article table td { + vertical-align: top; + @apply border-t border-indigo-200; +} + +article table th, +article table td { + @apply px-4 py-2; +} + +article table th { + @apply bg-indigo-800 text-white font-bold; +} + +article blockquote { + @apply p-4 bg-white border-l-8 border-indigo-800 mb-4 shadow; +} + +article ul, +article ol { + @apply mb-6 pl-6; +} + +article ul { + list-style: disc; +} + +article ol { + list-style: decimal; +} + +article blockquote :last-child { + @apply mb-0; +} + +.overflow-x-auto::-webkit-scrollbar, +.overflow-y-auto::-webkit-scrollbar { + display: none; +} + +.overflow-x-auto, +.overflow-y-auto { + -ms-overflow-style: none; + scrollbar-width: none; +} + +code { + @apply text-indigo-500; +} diff --git a/docs/assets/js/show_notifications.js b/docs/assets/js/show_notifications.js new file mode 100644 index 00000000..c895a537 --- /dev/null +++ b/docs/assets/js/show_notifications.js @@ -0,0 +1,28 @@ +import flasher from '@flasher/flasher' + +function showNotifications(notifications) { + if (notifications.length === 0) { + return + } + + setTimeout(() => { + notifications[0]() + showNotifications(notifications.slice(1)) + }, 1500) +} + +export function showNotificationsForHandler(handler, options = {}) { + const factory = flasher.use(handler) + + factory.info('Welcome back', 'Info', options) + + if (['sweetalert'].includes(handler)) { + return + } + + showNotifications([ + () => factory.error('Oops! Something went wrong!', 'Error', options), + () => factory.warning('Are you sure you want to proceed ?', 'Warning', options), + () => factory.success('Data has been saved successfully!', 'Success', options), + ]) +} diff --git a/docs/assets/js/stimulus.js b/docs/assets/js/stimulus.js new file mode 100644 index 00000000..3cdfa4d1 --- /dev/null +++ b/docs/assets/js/stimulus.js @@ -0,0 +1,4 @@ +import { startStimulusApp } from '@symfony/stimulus-bridge' + +// Registers Stimulus controllers from controllers.json and in the controllers/ directory +export const app = startStimulusApp(require.context('@symfony/stimulus-bridge/lazy-controller-loader!./controllers', true, /\.[jt]sx?$/)) diff --git a/docs/dist/107.12087179.js b/docs/dist/107.12087179.js new file mode 100644 index 00000000..4faff6c3 --- /dev/null +++ b/docs/dist/107.12087179.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[107],{107:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/107.6a2ea759.css b/docs/dist/107.6a2ea759.css new file mode 100644 index 00000000..23ef64db --- /dev/null +++ b/docs/dist/107.6a2ea759.css @@ -0,0 +1 @@ +.noty_theme__sunset.noty_bar{border-radius:2px;margin:4px 0;overflow:hidden;position:relative}.noty_theme__sunset.noty_bar .noty_body{font-size:14px;padding:10px;text-shadow:1px 1px 1px rgba(0,0,0,.1)}.noty_theme__sunset.noty_bar .noty_buttons{padding:10px}.noty_theme__sunset.noty_type__alert,.noty_theme__sunset.noty_type__notification{background-color:#073b4c;color:#fff}.noty_theme__sunset.noty_type__alert .noty_progressbar,.noty_theme__sunset.noty_type__notification .noty_progressbar{background-color:#fff}.noty_theme__sunset.noty_type__warning{background-color:#ffd166;color:#fff}.noty_theme__sunset.noty_type__error{background-color:#ef476f;color:#fff}.noty_theme__sunset.noty_type__error .noty_progressbar{opacity:.4}.noty_theme__sunset.noty_type__info,.noty_theme__sunset.noty_type__information{background-color:#118ab2;color:#fff}.noty_theme__sunset.noty_type__info .noty_progressbar,.noty_theme__sunset.noty_type__information .noty_progressbar{opacity:.6}.noty_theme__sunset.noty_type__success{background-color:#06d6a0;color:#fff} \ No newline at end of file diff --git a/docs/dist/160.264e6e64.js b/docs/dist/160.264e6e64.js new file mode 100644 index 00000000..8b0ae4d0 --- /dev/null +++ b/docs/dist/160.264e6e64.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[160],{779:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/160.554a2dcd.css b/docs/dist/160.554a2dcd.css new file mode 100644 index 00000000..192aec06 --- /dev/null +++ b/docs/dist/160.554a2dcd.css @@ -0,0 +1 @@ +.noty_theme__metroui.noty_bar{box-shadow:0 0 5px 0 rgba(0,0,0,.298);margin:4px 0;overflow:hidden;position:relative}.noty_theme__metroui.noty_bar .noty_progressbar{background-color:#000;bottom:0;filter:alpha(opacity=20);height:3px;left:0;opacity:.2;position:absolute;width:100%}.noty_theme__metroui.noty_bar .noty_body{font-size:14px;padding:1.25em}.noty_theme__metroui.noty_bar .noty_buttons{padding:0 10px .5em}.noty_theme__metroui.noty_type__alert,.noty_theme__metroui.noty_type__notification{background-color:#fff;color:#1d1d1d}.noty_theme__metroui.noty_type__warning{background-color:#fa6800;color:#fff}.noty_theme__metroui.noty_type__error{background-color:#ce352c;color:#fff}.noty_theme__metroui.noty_type__info,.noty_theme__metroui.noty_type__information{background-color:#1ba1e2;color:#fff}.noty_theme__metroui.noty_type__success{background-color:#60a917;color:#fff} \ No newline at end of file diff --git a/docs/dist/243.699ba66f.css b/docs/dist/243.699ba66f.css new file mode 100644 index 00000000..d335091f --- /dev/null +++ b/docs/dist/243.699ba66f.css @@ -0,0 +1 @@ +.noty_theme__semanticui.noty_bar{border:1px solid transparent;border-radius:.28571429rem;box-shadow:inset 0 0 0 1px rgba(34,36,38,.22),0 0 0 0 transparent;font-size:1em;margin:4px 0;overflow:hidden;position:relative}.noty_theme__semanticui.noty_bar .noty_body{line-height:1.4285em;padding:1em 1.5em}.noty_theme__semanticui.noty_bar .noty_buttons{padding:10px}.noty_theme__semanticui.noty_type__alert,.noty_theme__semanticui.noty_type__notification{background-color:#f8f8f9;color:rgba(0,0,0,.87)}.noty_theme__semanticui.noty_type__warning{background-color:#fffaf3;box-shadow:inset 0 0 0 1px #c9ba9b,0 0 0 0 transparent;color:#573a08}.noty_theme__semanticui.noty_type__error{background-color:#fff6f6;box-shadow:inset 0 0 0 1px #e0b4b4,0 0 0 0 transparent;color:#9f3a38}.noty_theme__semanticui.noty_type__info,.noty_theme__semanticui.noty_type__information{background-color:#f8ffff;box-shadow:inset 0 0 0 1px #a9d5de,0 0 0 0 transparent;color:#276f86}.noty_theme__semanticui.noty_type__success{background-color:#fcfff5;box-shadow:inset 0 0 0 1px #a3c293,0 0 0 0 transparent;color:#2c662d} \ No newline at end of file diff --git a/docs/dist/243.991d9535.js b/docs/dist/243.991d9535.js new file mode 100644 index 00000000..72e886d7 --- /dev/null +++ b/docs/dist/243.991d9535.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[243],{243:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/265.396597b6.js b/docs/dist/265.396597b6.js new file mode 100644 index 00000000..4b2be5c5 --- /dev/null +++ b/docs/dist/265.396597b6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[265],{265:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/371.324a7072.js b/docs/dist/371.324a7072.js new file mode 100644 index 00000000..95123f4f --- /dev/null +++ b/docs/dist/371.324a7072.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[371],{371:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/371.9523a7ff.css b/docs/dist/371.9523a7ff.css new file mode 100644 index 00000000..764ce57e --- /dev/null +++ b/docs/dist/371.9523a7ff.css @@ -0,0 +1 @@ +.noty_theme__nest.noty_bar{border-radius:2px;box-shadow:5px 4px 10px 0 rgba(0,0,0,.098);margin:0 0 15px;overflow:hidden;position:relative}.noty_theme__nest.noty_bar .noty_body{font-size:14px;padding:10px;text-shadow:1px 1px 1px rgba(0,0,0,.1)}.noty_theme__nest.noty_bar .noty_buttons{padding:10px}.noty_layout .noty_theme__nest.noty_bar{z-index:5}.noty_layout .noty_theme__nest.noty_bar:nth-child(2){margin-left:4px;margin-right:-4px;margin-top:4px;position:absolute;top:0;width:100%;z-index:4}.noty_layout .noty_theme__nest.noty_bar:nth-child(3){margin-left:8px;margin-right:-8px;margin-top:8px;position:absolute;top:0;width:100%;z-index:3}.noty_layout .noty_theme__nest.noty_bar:nth-child(4){margin-left:12px;margin-right:-12px;margin-top:12px;position:absolute;top:0;width:100%;z-index:2}.noty_layout .noty_theme__nest.noty_bar:nth-child(5){margin-left:16px;margin-right:-16px;margin-top:16px;position:absolute;top:0;width:100%;z-index:1}.noty_layout .noty_theme__nest.noty_bar:nth-child(n+6){margin-left:20px;margin-right:-20px;margin-top:20px;position:absolute;top:0;width:100%;z-index:-1}#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(2),#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(2){margin-left:-4px;margin-right:4px;margin-top:4px}#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(3),#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(3){margin-left:-8px;margin-right:8px;margin-top:8px}#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(4),#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(4){margin-left:-12px;margin-right:12px;margin-top:12px}#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(5),#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(5){margin-left:-16px;margin-right:16px;margin-top:16px}#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(n+6),#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(n+6){margin-left:-20px;margin-right:20px;margin-top:20px}.noty_theme__nest.noty_type__alert,.noty_theme__nest.noty_type__notification{background-color:#073b4c;color:#fff}.noty_theme__nest.noty_type__alert .noty_progressbar,.noty_theme__nest.noty_type__notification .noty_progressbar{background-color:#fff}.noty_theme__nest.noty_type__warning{background-color:#ffd166;color:#fff}.noty_theme__nest.noty_type__error{background-color:#ef476f;color:#fff}.noty_theme__nest.noty_type__error .noty_progressbar{opacity:.4}.noty_theme__nest.noty_type__info,.noty_theme__nest.noty_type__information{background-color:#118ab2;color:#fff}.noty_theme__nest.noty_type__info .noty_progressbar,.noty_theme__nest.noty_type__information .noty_progressbar{opacity:.6}.noty_theme__nest.noty_type__success{background-color:#06d6a0;color:#fff} \ No newline at end of file diff --git a/docs/dist/411.29cd993e.css b/docs/dist/411.29cd993e.css new file mode 100644 index 00000000..91a69b2e --- /dev/null +++ b/docs/dist/411.29cd993e.css @@ -0,0 +1 @@ +.noty_theme__bootstrap-v4.noty_bar{border:1px solid transparent;border-radius:.25rem;margin:4px 0;overflow:hidden;position:relative}.noty_theme__bootstrap-v4.noty_bar .noty_body{padding:.75rem 1.25rem}.noty_theme__bootstrap-v4.noty_bar .noty_buttons{padding:10px}.noty_theme__bootstrap-v4.noty_bar .noty_close_button{background:transparent;color:#000;filter:alpha(opacity=20);font-size:1.5rem;font-weight:700;line-height:1;opacity:.5;text-shadow:0 1px 0 #fff}.noty_theme__bootstrap-v4.noty_bar .noty_close_button:hover{background:transparent;cursor:pointer;filter:alpha(opacity=50);opacity:.75;text-decoration:none}.noty_theme__bootstrap-v4.noty_type__alert,.noty_theme__bootstrap-v4.noty_type__notification{background-color:#fff;color:inherit}.noty_theme__bootstrap-v4.noty_type__warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.noty_theme__bootstrap-v4.noty_type__error{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.noty_theme__bootstrap-v4.noty_type__info,.noty_theme__bootstrap-v4.noty_type__information{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.noty_theme__bootstrap-v4.noty_type__success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d} \ No newline at end of file diff --git a/docs/dist/411.42e6794f.js b/docs/dist/411.42e6794f.js new file mode 100644 index 00000000..30fbf9c0 --- /dev/null +++ b/docs/dist/411.42e6794f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[411],{792:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/455.17bc016b.js b/docs/dist/455.17bc016b.js new file mode 100644 index 00000000..ccd9a758 --- /dev/null +++ b/docs/dist/455.17bc016b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[455],{455:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/455.3a7b4474.css b/docs/dist/455.3a7b4474.css new file mode 100644 index 00000000..e95d3d91 --- /dev/null +++ b/docs/dist/455.3a7b4474.css @@ -0,0 +1 @@ +.noty_theme__bootstrap-v3.noty_bar{border:1px solid transparent;border-radius:4px;margin:4px 0;overflow:hidden;position:relative}.noty_theme__bootstrap-v3.noty_bar .noty_body{padding:15px}.noty_theme__bootstrap-v3.noty_bar .noty_buttons{padding:10px}.noty_theme__bootstrap-v3.noty_bar .noty_close_button{background:transparent;color:#000;filter:alpha(opacity=20);font-size:21px;font-weight:700;line-height:1;opacity:.2;text-shadow:0 1px 0 #fff}.noty_theme__bootstrap-v3.noty_bar .noty_close_button:hover{background:transparent;cursor:pointer;filter:alpha(opacity=50);opacity:.5;text-decoration:none}.noty_theme__bootstrap-v3.noty_type__alert,.noty_theme__bootstrap-v3.noty_type__notification{background-color:#fff;color:inherit}.noty_theme__bootstrap-v3.noty_type__warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.noty_theme__bootstrap-v3.noty_type__error{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.noty_theme__bootstrap-v3.noty_type__info,.noty_theme__bootstrap-v3.noty_type__information{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.noty_theme__bootstrap-v3.noty_type__success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d} \ No newline at end of file diff --git a/docs/dist/641.c0be7378.css b/docs/dist/641.c0be7378.css new file mode 100644 index 00000000..e7d59857 --- /dev/null +++ b/docs/dist/641.c0be7378.css @@ -0,0 +1 @@ +.noty_theme__light.noty_bar{border-radius:2px;margin:4px 0;overflow:hidden;position:relative}.noty_theme__light.noty_bar .noty_body{padding:10px}.noty_theme__light.noty_bar .noty_buttons{border-top:1px solid #e7e7e7;padding:5px 10px}.noty_theme__light.noty_type__alert,.noty_theme__light.noty_type__notification{background-color:#fff;border:1px solid #dedede;color:#444}.noty_theme__light.noty_type__warning{background-color:#ffeaa8;border:1px solid #ffc237;color:#826200}.noty_theme__light.noty_type__warning .noty_buttons{border-color:#dfaa30}.noty_theme__light.noty_type__error{background-color:#ed7000;border:1px solid #e25353;color:#fff}.noty_theme__light.noty_type__error .noty_buttons{border-color:darkred}.noty_theme__light.noty_type__info,.noty_theme__light.noty_type__information{background-color:#78c5e7;border:1px solid #3badd6;color:#fff}.noty_theme__light.noty_type__info .noty_buttons,.noty_theme__light.noty_type__information .noty_buttons{border-color:#0b90c4}.noty_theme__light.noty_type__success{background-color:#57c880;border:1px solid #7cdd77;color:#006400}.noty_theme__light.noty_type__success .noty_buttons{border-color:#50c24e} \ No newline at end of file diff --git a/docs/dist/641.f8750364.js b/docs/dist/641.f8750364.js new file mode 100644 index 00000000..3b0f437a --- /dev/null +++ b/docs/dist/641.f8750364.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[641],{641:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/735.11112420.css b/docs/dist/735.11112420.css new file mode 100644 index 00000000..363b5789 --- /dev/null +++ b/docs/dist/735.11112420.css @@ -0,0 +1 @@ +.noty_theme__relax.noty_bar{border-radius:2px;margin:4px 0;overflow:hidden;position:relative}.noty_theme__relax.noty_bar .noty_body{padding:10px}.noty_theme__relax.noty_bar .noty_buttons{border-top:1px solid #e7e7e7;padding:5px 10px}.noty_theme__relax.noty_type__alert,.noty_theme__relax.noty_type__notification{background-color:#fff;border:1px solid #dedede;color:#444}.noty_theme__relax.noty_type__warning{background-color:#ffeaa8;border:1px solid #ffc237;color:#826200}.noty_theme__relax.noty_type__warning .noty_buttons{border-color:#dfaa30}.noty_theme__relax.noty_type__error{background-color:#ff8181;border:1px solid #e25353;color:#fff}.noty_theme__relax.noty_type__error .noty_buttons{border-color:darkred}.noty_theme__relax.noty_type__info,.noty_theme__relax.noty_type__information{background-color:#78c5e7;border:1px solid #3badd6;color:#fff}.noty_theme__relax.noty_type__info .noty_buttons,.noty_theme__relax.noty_type__information .noty_buttons{border-color:#0b90c4}.noty_theme__relax.noty_type__success{background-color:#bcf5bc;border:1px solid #7cdd77;color:#006400}.noty_theme__relax.noty_type__success .noty_buttons{border-color:#50c24e} \ No newline at end of file diff --git a/docs/dist/735.3cd4e509.js b/docs/dist/735.3cd4e509.js new file mode 100644 index 00000000..ea1fe3e5 --- /dev/null +++ b/docs/dist/735.3cd4e509.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_flasher_docs=self.webpackChunk_flasher_docs||[]).push([[735],{735:function(s,e,c){c.r(e)}}]); \ No newline at end of file diff --git a/docs/dist/entrypoints.json b/docs/dist/entrypoints.json new file mode 100644 index 00000000..87512bfe --- /dev/null +++ b/docs/dist/entrypoints.json @@ -0,0 +1,12 @@ +{ + "entrypoints": { + "main": { + "css": [ + "/dist/main.c67fa9cf.css" + ], + "js": [ + "/dist/main.7736601c.js" + ] + } + } +} \ No newline at end of file diff --git a/docs/dist/main.7736601c.js b/docs/dist/main.7736601c.js new file mode 100644 index 00000000..0666ec13 --- /dev/null +++ b/docs/dist/main.7736601c.js @@ -0,0 +1,2 @@ +/*! For license information please see main.7736601c.js.LICENSE.txt */ +!function(){var e,t,n={498:function(e,t,n){var r={"./anchor_controller.js":835,"./clipboard_controller.js":374,"./flasher_controller.js":447,"./navigation_controller.js":162,"./noty_controller.js":880,"./notyf_controller.js":326,"./prev-next_controller.js":995,"./ray_controller.js":234,"./sweetalert_controller.js":242,"./toastr_controller.js":921,"./tryit_controller.js":759};function o(e){var t=i(e);return n(t)}function i(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=i,e.exports=o,o.id=498},891:function(e,t,n){"use strict";n.d(t,{lg:function(){return Q},xI:function(){return ce}});class r{constructor(e,t,n){this.eventTarget=e,this.eventName=t,this.eventOptions=n,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort(((e,t)=>{const n=e.index,r=t.index;return nr?1:0}))}}class o{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach((e=>e.connect())))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach((e=>e.disconnect())))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce(((e,t)=>e.concat(Array.from(t.values()))),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,n={}){this.application.handleError(e,`Error ${t}`,n)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:n,eventOptions:r}=e,o=this.fetchEventListenerMapForEventTarget(t),i=this.cacheKey(n,r);o.delete(i),0==o.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:n,eventOptions:r}=e;return this.fetchEventListener(t,n,r)}fetchEventListener(e,t,n){const r=this.fetchEventListenerMapForEventTarget(e),o=this.cacheKey(t,n);let i=r.get(o);return i||(i=this.createEventListener(e,t,n),r.set(o,i)),i}createEventListener(e,t,n){const o=new r(e,t,n);return this.started&&o.connect(),o}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const n=[e];return Object.keys(t).sort().forEach((e=>{n.push(`${t[e]?"":"!"}${e}`)})),n.join(":")}}const i={stop({event:e,value:t}){return t&&e.stopPropagation(),!0},prevent({event:e,value:t}){return t&&e.preventDefault(),!0},self({event:e,value:t,element:n}){return!t||n===e.target}},s=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function a(e){return"window"==e?window:"document"==e?document:void 0}function l(e){return e.replace(/(?:[_-])([a-z0-9])/g,((e,t)=>t.toUpperCase()))}function c(e){return l(e.replace(/--/g,"-").replace(/__/g,"_"))}function u(e){return e.charAt(0).toUpperCase()+e.slice(1)}function d(e){return e.replace(/([A-Z])/g,((e,t)=>`-${t.toLowerCase()}`))}function h(e){return null!=e}function p(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const f=["meta","ctrl","alt","shift"];class m{constructor(e,t,n,r){this.element=e,this.index=t,this.eventTarget=n.eventTarget||e,this.eventName=n.eventName||function(e){const t=e.tagName.toLowerCase();if(t in g)return g[t](e)}(e)||v("missing event name"),this.eventOptions=n.eventOptions||{},this.identifier=n.identifier||v("missing identifier"),this.methodName=n.methodName||v("missing method name"),this.keyFilter=n.keyFilter||"",this.schema=r}static forToken(e,t){return new this(e.element,e.index,function(e){const t=e.trim().match(s)||[];let n=t[2],r=t[3];return r&&!["keydown","keyup","keypress"].includes(n)&&(n+=`.${r}`,r=""),{eventTarget:a(t[4]),eventName:n,eventOptions:t[7]?(o=t[7],o.split(":").reduce(((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)})),{})):{},identifier:t[5],methodName:t[6],keyFilter:t[1]||r};var o}(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"",t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return!1;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return!0;const n=t.filter((e=>!f.includes(e)))[0];return!!n&&(p(this.keyMappings,n)||v(`contains unknown key filter: ${this.keyFilter}`),this.keyMappings[n].toLowerCase()!==e.key.toLowerCase())}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return!1;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={},t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:n,value:r}of Array.from(this.element.attributes)){const o=n.match(t),i=o&&o[1];i&&(e[l(i)]=y(r))}return e}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[n,r,o,i]=f.map((e=>t.includes(e)));return e.metaKey!==n||e.ctrlKey!==r||e.altKey!==o||e.shiftKey!==i}}const g={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function v(e){throw new Error(e)}function y(e){try{return JSON.parse(e)}catch(t){return e}}class w{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action,{actionDescriptorFilters:n}=this.context.application,{controller:r}=this.context;let o=!0;for(const[i,s]of Object.entries(this.eventOptions))if(i in n){const a=n[i];o=o&&a({name:i,value:s,event:e,element:t,controller:r})}return o}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:n}=e;try{this.method.call(this.controller,e),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:n,action:this.methodName})}catch(t){const{identifier:n,controller:r,element:o,index:i}=this,s={identifier:n,controller:r,element:o,index:i,event:e};this.context.handleError(t,`invoking action "${this.action}"`,s)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&(!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element))))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class b{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const n of this.matchElementsInTree(e))t.call(this,n)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class x{constructor(e,t,n){this.attributeName=t,this.delegate=n,this.elementObserver=new b(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],n=Array.from(e.querySelectorAll(this.selector));return t.concat(n)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function C(e,t,n){O(e,t).add(n)}function E(e,t,n){O(e,t).delete(n),function(e,t){const n=e.get(t);null!=n&&0==n.size&&e.delete(t)}(e,t)}function O(e,t){let n=e.get(t);return n||(n=new Set,e.set(t,n)),n}class A{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e.concat(Array.from(t))),[])}get size(){return Array.from(this.valuesByKey.values()).reduce(((e,t)=>e+t.size),0)}add(e,t){C(this.valuesByKey,e,t)}delete(e,t){E(this.valuesByKey,e,t)}has(e,t){const n=this.valuesByKey.get(e);return null!=n&&n.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some((t=>t.has(e)))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter((([t,n])=>n.has(e))).map((([e,t])=>e))}}class k{constructor(e,t,n,r){this._selector=t,this.details=r,this.elementObserver=new b(e,this),this.delegate=n,this.matchesByElement=new A}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e,this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const n=e.matches(t);return this.delegate.selectorMatchElement?n&&this.delegate.selectorMatchElement(e,this.details):n}return!1}matchElementsInTree(e){const{selector:t}=this;if(t){const n=this.matchElement(e)?[e]:[],r=Array.from(e.querySelectorAll(t)).filter((e=>this.matchElement(e)));return n.concat(r)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const n of t)this.selectorUnmatched(e,n)}elementAttributeChanged(e,t){const{selector:n}=this;if(n){const t=this.matchElement(e),r=this.matchesByElement.has(n,e);t&&!r?this.selectorMatched(e,n):!t&&r&&this.selectorUnmatched(e,n)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details),this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details),this.matchesByElement.delete(t,e)}}class S{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver((e=>this.processMutations(e)))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const n=this.delegate.getStringMapKeyForAttribute(e);if(null!=n){this.stringMap.has(e)||this.stringMapKeyAdded(n,e);const r=this.element.getAttribute(e);if(this.stringMap.get(e)!=r&&this.stringMapValueChanged(r,n,t),null==r){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(n,e,t)}else this.stringMap.set(e,r)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,n){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,n)}stringMapKeyRemoved(e,t,n){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,n)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map((e=>e.name))}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class T{constructor(e,t,n){this.attributeObserver=new x(e,t,this),this.delegate=n,this.tokensByElement=new A}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,n]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(n)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach((e=>this.tokenMatched(e)))}tokensUnmatched(e){e.forEach((e=>this.tokenUnmatched(e)))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),n=this.readTokensForElement(e),r=function(e,t){const n=Math.max(e.length,t.length);return Array.from({length:n},((n,r)=>[e[r],t[r]]))}(t,n).findIndex((([e,t])=>{return r=t,!((n=e)&&r&&n.index==r.index&&n.content==r.content);var n,r}));return-1==r?[[],[]]:[t.slice(r),n.slice(r)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,n){return e.trim().split(/\s+/).filter((e=>e.length)).map(((e,r)=>({element:t,attributeName:n,content:e,index:r})))}(e.getAttribute(t)||"",e,t)}}class _{constructor(e,t,n){this.tokenListObserver=new T(e,t,this),this.delegate=n,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:n}=this.fetchParseResultForToken(e);n&&(this.fetchValuesByTokenForElement(t).set(e,n),this.delegate.elementMatchedValue(t,n))}tokenUnmatched(e){const{element:t}=e,{value:n}=this.fetchParseResultForToken(e);n&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,n))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class N{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new _(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new w(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach((e=>this.delegate.bindingDisconnected(e,!0))),this.bindingsByAction.clear()}parseValueForToken(e){const t=m.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class j{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new S(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const n=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,n.writer(this.receiver[e]),n.writer(n.defaultValue))}stringMapValueChanged(e,t,n){const r=this.valueDescriptorNameMap[t];null!==e&&(null===n&&(n=r.writer(r.defaultValue)),this.invokeChangedCallback(t,e,n))}stringMapKeyRemoved(e,t,n){const r=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,r.writer(this.receiver[e]),n):this.invokeChangedCallback(e,r.writer(r.defaultValue),n)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:n,writer:r}of this.valueDescriptors)null==n||this.controller.data.has(e)||this.invokeChangedCallback(t,r(n),void 0)}invokeChangedCallback(e,t,n){const r=`${e}Changed`,o=this.receiver[r];if("function"==typeof o){const r=this.valueDescriptorNameMap[e];try{const e=r.reader(t);let i=n;n&&(i=r.reader(n)),o.call(this.receiver,e,i)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${r.name}" - ${e.message}`),e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map((t=>e[t]))}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach((t=>{const n=this.valueDescriptorMap[t];e[n.name]=n})),e}hasValue(e){const t=`has${u(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class P{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new A}start(){this.tokenListObserver||(this.tokenListObserver=new T(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var n;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(n=this.tokenListObserver)||void 0===n||n.pause((()=>this.delegate.targetConnected(e,t))))}disconnectTarget(e,t){var n;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(n=this.tokenListObserver)||void 0===n||n.pause((()=>this.delegate.targetDisconnected(e,t))))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function L(e,t){const n=D(e);return Array.from(n.reduce(((e,n)=>(function(e,t){const n=e[t];return Array.isArray(n)?n:[]}(n,t).forEach((t=>e.add(t))),e)),new Set))}function M(e,t){return D(e).reduce(((e,n)=>(e.push(...function(e,t){const n=e[t];return n?Object.keys(n).map((e=>[e,n[e]])):[]}(n,t)),e)),[])}function D(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class R{constructor(e,t){this.started=!1,this.context=e,this.delegate=t,this.outletsByName=new A,this.outletElementsByName=new A,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){this.started||(this.outletDefinitions.forEach((e=>{this.setupSelectorObserverForOutlet(e),this.setupAttributeObserverForOutlet(e)})),this.started=!0,this.dependentContexts.forEach((e=>e.refresh())))}refresh(){this.selectorObserverMap.forEach((e=>e.refresh())),this.attributeObserverMap.forEach((e=>e.refresh()))}stop(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}stopSelectorObservers(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach((e=>e.stop())),this.selectorObserverMap.clear())}stopAttributeObservers(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach((e=>e.stop())),this.attributeObserverMap.clear())}selectorMatched(e,t,{outletName:n}){const r=this.getOutlet(e,n);r&&this.connectOutlet(r,e,n)}selectorUnmatched(e,t,{outletName:n}){const r=this.getOutletFromMap(e,n);r&&this.disconnectOutlet(r,e,n)}selectorMatchElement(e,{outletName:t}){const n=this.selector(t),r=this.hasOutlet(e,t),o=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!n&&(r&&o&&e.matches(n))}elementMatchedAttribute(e,t){const n=this.getOutletNameFromOutletAttributeName(t);n&&this.updateSelectorObserverForOutlet(n)}elementAttributeValueChanged(e,t){const n=this.getOutletNameFromOutletAttributeName(t);n&&this.updateSelectorObserverForOutlet(n)}elementUnmatchedAttribute(e,t){const n=this.getOutletNameFromOutletAttributeName(t);n&&this.updateSelectorObserverForOutlet(n)}connectOutlet(e,t,n){var r;this.outletElementsByName.has(n,t)||(this.outletsByName.add(n,e),this.outletElementsByName.add(n,t),null===(r=this.selectorObserverMap.get(n))||void 0===r||r.pause((()=>this.delegate.outletConnected(e,t,n))))}disconnectOutlet(e,t,n){var r;this.outletElementsByName.has(n,t)&&(this.outletsByName.delete(n,e),this.outletElementsByName.delete(n,t),null===(r=this.selectorObserverMap.get(n))||void 0===r||r.pause((()=>this.delegate.outletDisconnected(e,t,n))))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const n of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(n,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e),n=new k(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,n),n.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e),n=new x(this.scope.element,t,this);this.attributeObserverMap.set(e,n),n.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find((t=>this.attributeNameForOutletName(t)===e))}get outletDependencies(){const e=new A;return this.router.modules.forEach((t=>{L(t.definition.controllerConstructor,"outlets").forEach((n=>e.add(n,t.identifier)))})),e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter((t=>e.includes(t.identifier)))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find((t=>t.element===e))}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class B{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:n,controller:r,element:o}=this;t=Object.assign({identifier:n,controller:r,element:o},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new N(this,this.dispatcher),this.valueObserver=new j(this,this.controller),this.targetObserver=new P(this,this),this.outletObserver=new R(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,n={}){const{identifier:r,controller:o,element:i}=this;n=Object.assign({identifier:r,controller:o,element:i},n),this.application.handleError(e,`Error ${t}`,n)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,n){this.invokeControllerMethod(`${c(n)}OutletConnected`,e,t)}outletDisconnected(e,t,n){this.invokeControllerMethod(`${c(n)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const n=this.controller;"function"==typeof n[e]&&n[e](...t)}}function F(e){return function(e,t){const n=I(e),r=function(e,t){return q(t).reduce(((n,r)=>{const o=function(e,t,n){const r=Object.getOwnPropertyDescriptor(e,n);if(!r||!("value"in r)){const e=Object.getOwnPropertyDescriptor(t,n).value;return r&&(e.get=r.get||e.get,e.set=r.set||e.set),e}}(e,t,r);return o&&Object.assign(n,{[r]:o}),n}),{})}(e.prototype,t);return Object.defineProperties(n.prototype,r),n}(e,function(e){const t=L(e,"blessings");return t.reduce(((t,n)=>{const r=n(e);for(const e in r){const n=t[e]||{};t[e]=Object.assign(n,r[e])}return t}),{})}(e))}const q="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,I=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e((function(){this.a.call(this)}));t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class H{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:F(e.controllerConstructor)}}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new B(this,e),this.contextsByScope.set(e,t)),t}}class ${constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){const t=this.data.get(this.getDataKey(e))||"";return t.match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class U{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const n=this.getAttributeNameForKey(e);return this.element.setAttribute(n,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${d(e)}`}}class z{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,n){let r=this.warnedKeysByObject.get(e);r||(r=new Set,this.warnedKeysByObject.set(e,r)),r.has(t)||(r.add(t),this.logger.warn(n,e))}}function V(e,t){return`[${e}~="${t}"]`}class W{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)]),[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return V(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map((t=>this.deprecate(t,e)))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return V(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:n}=this,r=this.schema.targetAttribute,o=this.schema.targetAttributeForScope(n);this.guide.warn(e,`target:${t}`,`Please replace ${r}="${n}.${t}" with ${o}="${t}". The ${r} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class K{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce(((e,t)=>e||this.findOutlet(t)),void 0)}findAll(...e){return e.reduce(((e,t)=>[...e,...this.findAllOutlets(t)]),[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){return this.scope.queryElements(e).filter((n=>this.matchesElement(n,e,t)))[0]}findAllElements(e,t){return this.scope.queryElements(e).filter((n=>this.matchesElement(n,e,t)))}matchesElement(e,t,n){const r=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&r.split(" ").includes(n)}}class G{constructor(e,t,n,r){this.targets=new W(this),this.classes=new $(this),this.data=new U(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=n,this.guide=new z(r),this.outlets=new K(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return V(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new G(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class J{constructor(e,t,n){this.element=e,this.schema=t,this.delegate=n,this.valueListObserver=new _(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:n}=e;return this.parseValueForElementAndIdentifier(t,n)}parseValueForElementAndIdentifier(e,t){const n=this.fetchScopesByIdentifierForElement(e);let r=n.get(t);return r||(r=this.delegate.createScopeForElementAndIdentifier(e,t),n.set(t,r)),r}elementMatchedValue(e,t){const n=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,n),1==n&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const n=this.scopeReferenceCounts.get(t);n&&(this.scopeReferenceCounts.set(t,n-1),1==n&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class X{constructor(e){this.application=e,this.scopeObserver=new J(this.element,this.schema,this),this.scopesByIdentifier=new A,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce(((e,t)=>e.concat(t.contexts)),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new H(this.application,e);this.connectModule(t);const n=e.controllerConstructor.afterLoad;n&&n.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const n=this.modulesByIdentifier.get(t);if(n)return n.contexts.find((t=>t.element==e))}proposeToConnectScopeForElementAndIdentifier(e,t){const n=this.scopeObserver.parseValueForElementAndIdentifier(e,t);n?this.scopeObserver.elementMatchedValue(n.element,n):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,n){this.application.handleError(e,t,n)}createScopeForElementAndIdentifier(e,t){return new G(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e);this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.connectContextForScope(t)))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier);this.scopesByIdentifier.getValuesForKey(e.identifier).forEach((t=>e.disconnectContextForScope(t)))}}const Y={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},Z("abcdefghijklmnopqrstuvwxyz".split("").map((e=>[e,e])))),Z("0123456789".split("").map((e=>[e,e]))))};function Z(e){return e.reduce(((e,[t,n])=>Object.assign(Object.assign({},e),{[t]:n})),{})}class Q{constructor(e=document.documentElement,t=Y){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,n={})=>{this.debug&&this.logFormattedMessage(e,t,n)},this.element=e,this.schema=t,this.dispatcher=new o(this),this.router=new X(this),this.actionDescriptorFilters=Object.assign({},i)}static start(e,t){const n=new this(e,t);return n.start(),n}async start(){await new Promise((e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",(()=>e())):e()})),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)}))}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach((e=>this.router.unloadIdentifier(e)))}get controllers(){return this.router.contexts.map((e=>e.controller))}getControllerForElementAndIdentifier(e,t){const n=this.router.getContextForElementAndIdentifier(e,t);return n?n.controller:null}handleError(e,t,n){var r;this.logger.error("%s\n\n%o\n\n%o",t,e,n),null===(r=window.onerror)||void 0===r||r.call(window,t,"",0,0,e)}logFormattedMessage(e,t,n={}){n=Object.assign({application:this},n),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},n)),this.logger.groupEnd()}}function ee(e,t,n){return e.application.getControllerForElementAndIdentifier(t,n)}function te(e,t,n){let r=ee(e,t,n);return r||(e.application.router.proposeToConnectScopeForElementAndIdentifier(t,n),r=ee(e,t,n),r||void 0)}function ne([e,t],n){return function(e){const{token:t,typeDefinition:n}=e,r=`${d(t)}-value`,o=function(e){const{controller:t,token:n,typeDefinition:r}=e,o={controller:t,token:n,typeObject:r},i=function(e){const{controller:t,token:n,typeObject:r}=e,o=h(r.type),i=h(r.default),s=o&&i,a=o&&!i,l=!o&&i,c=re(r.type),u=oe(e.typeObject.default);if(a)return c;if(l)return u;if(c!==u){throw new Error(`The specified default value for the Stimulus Value "${t?`${t}.${n}`:n}" must match the defined type "${c}". The provided default value of "${r.default}" is of type "${u}".`)}if(s)return c}(o),s=oe(r),a=re(r),l=i||s||a;if(l)return l;const c=t?`${t}.${r}`:n;throw new Error(`Unknown value type "${c}" for "${n}" value`)}(e);return{type:o,key:r,name:l(r),get defaultValue(){return function(e){const t=re(e);if(t)return ie[t];const n=p(e,"default"),r=p(e,"type"),o=e;if(n)return o.default;if(r){const{type:e}=o,t=re(e);if(t)return ie[t]}return e}(n)},get hasCustomDefaultValue(){return void 0!==oe(n)},reader:se[o],writer:ae[o]||ae.default}}({controller:n,token:e,typeDefinition:t})}function re(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function oe(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const ie={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},se={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${oe(t)}"`);return t},boolean(e){return!("0"==e||"false"==String(e).toLowerCase())},number(e){return Number(e.replace(/_/g,""))},object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${oe(t)}"`);return t},string(e){return e}},ae={default:function(e){return`${e}`},array:le,object:le};function le(e){return JSON.stringify(e)}class ce{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:n={},prefix:r=this.identifier,bubbles:o=!0,cancelable:i=!0}={}){const s=new CustomEvent(r?`${r}:${e}`:e,{detail:n,bubbles:o,cancelable:i});return t.dispatchEvent(s),s}}ce.blessings=[function(e){return L(e,"classes").reduce(((e,t)=>{return Object.assign(e,{[`${n=t}Class`]:{get(){const{classes:e}=this;if(e.has(n))return e.get(n);{const t=e.getAttributeName(n);throw new Error(`Missing attribute "${t}"`)}}},[`${n}Classes`]:{get(){return this.classes.getAll(n)}},[`has${u(n)}Class`]:{get(){return this.classes.has(n)}}});var n}),{})},function(e){return L(e,"targets").reduce(((e,t)=>{return Object.assign(e,{[`${n=t}Target`]:{get(){const e=this.targets.find(n);if(e)return e;throw new Error(`Missing target element "${n}" for "${this.identifier}" controller`)}},[`${n}Targets`]:{get(){return this.targets.findAll(n)}},[`has${u(n)}Target`]:{get(){return this.targets.has(n)}}});var n}),{})},function(e){const t=M(e,"values"),n={valueDescriptorMap:{get(){return t.reduce(((e,t)=>{const n=ne(t,this.identifier),r=this.data.getAttributeNameForKey(n.key);return Object.assign(e,{[r]:n})}),{})}}};return t.reduce(((e,t)=>Object.assign(e,function(e,t){const n=ne(e,t),{key:r,name:o,reader:i,writer:s}=n;return{[o]:{get(){const e=this.data.get(r);return null!==e?i(e):n.defaultValue},set(e){void 0===e?this.data.delete(r):this.data.set(r,s(e))}},[`has${u(o)}`]:{get(){return this.data.has(r)||n.hasCustomDefaultValue}}}}(t))),n)},function(e){return L(e,"outlets").reduce(((e,t)=>Object.assign(e,function(e){const t=c(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e),n=this.outlets.getSelectorForOutletName(e);if(t){const n=te(this,t,e);if(n)return n;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${n}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map((t=>{const n=te(this,t,e);if(n)return n;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)})).filter((e=>e)):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e),n=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${n}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${u(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t))),{})}],ce.targets=[],ce.outlets=[],ce.values={}},353:function(e,t,n){"use strict";e=n.nmd(e);const r=(e=0)=>t=>`[${38+e};5;${t}m`,o=(e=0)=>(t,n,r)=>`[${38+e};2;${t};${n};${r}m`;Object.defineProperty(e,"exports",{enumerable:!0,get:function(){const e=new Map,t={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};t.color.gray=t.color.blackBright,t.bgColor.bgGray=t.bgColor.bgBlackBright,t.color.grey=t.color.blackBright,t.bgColor.bgGrey=t.bgColor.bgBlackBright;for(const[n,r]of Object.entries(t)){for(const[n,o]of Object.entries(r))t[n]={open:`[${o[0]}m`,close:`[${o[1]}m`},r[n]=t[n],e.set(o[0],o[1]);Object.defineProperty(t,n,{value:r,enumerable:!1})}return Object.defineProperty(t,"codes",{value:e,enumerable:!1}),t.color.close="",t.bgColor.close="",t.color.ansi256=r(),t.color.ansi16m=o(),t.bgColor.ansi256=r(10),t.bgColor.ansi16m=o(10),Object.defineProperties(t,{rgbToAnsi256:{value:(e,t,n)=>e===t&&t===n?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(n/255*5),enumerable:!1},hexToRgb:{value:e=>{const t=/(?[a-f\d]{6}|[a-f\d]{3})/i.exec(e.toString(16));if(!t)return[0,0,0];let{colorString:n}=t.groups;3===n.length&&(n=n.split("").map((e=>e+e)).join(""));const r=Number.parseInt(n,16);return[r>>16&255,r>>8&255,255&r]},enumerable:!1},hexToAnsi256:{value:e=>t.rgbToAnsi256(...t.hexToRgb(e)),enumerable:!1}}),t}})},835:function(e,t,n){"use strict";n.r(t);var r=n(891);t.default=class extends r.xI{connect(){const e=document.querySelector("#anchor-navigation");!function(){const t=document.querySelector("#anchor-navigation ul"),n=document.querySelectorAll("#main-article h3, #main-article h2, #main-article a.anchor");if(0===n.length)return void e.remove();e.classList.add("lg:block"),n.forEach((e=>{e.parentElement.classList.add("px-6","rounded"),e.classList.add("leading-loose");const n=document.createElement("a");n.href="A"===e.tagName?e.hash:`#${e.getAttribute("id")}`,n.innerHTML="A"===e.tagName?e.textContent:`${e.textContent}`,n.classList.add("leading-loose","text-md","inline-block","w-full","text-indigo-500");const r=document.createElement("li");r.classList.add("px-6","rounded","w-full"),"A"===e.tagName&&(r.classList.remove("px-6"),r.classList.add("px-12")),r.appendChild(n),t.appendChild(r)}))}(),t(),function(){const e=document.querySelector("#main-article");document.querySelectorAll(".sticky").forEach((t=>{if(t.offsetHeight<=window.innerHeight||e.clientHeight<=t.offsetHeight)return;const n=document.createElement("div");n.classList.add("h-screen","overflow-y-auto"),n.innerHTML=t.innerHTML,t.innerHTML=n.outerHTML}))}();function t(e){void 0===e&&(e=window.location.hash);document.querySelectorAll("a.anchor, #anchor-navigation ul li a").forEach((t=>{const n=t.parentElement;t.classList.remove("text-gray-900"),t.classList.add("text-indigo-500"),n.classList.remove("bg-indigo-500"),e===t.hash&&(t.classList.remove("text-indigo-500"),t.classList.add("text-white"),n.classList.add("bg-indigo-500"))}))}document.querySelectorAll("a.anchor, #anchor-navigation ul li a").forEach((e=>{e.addEventListener("click",(n=>{n.preventDefault(),window.location.hash=e.hash,t(e.hash)}))}))}}},374:function(e,t,n){"use strict";n.r(t);var r=n(891);t.default=class extends r.xI{connect(){document.querySelectorAll("pre > code").forEach((e=>{const t=document.createElement("button");t.classList.add("copy","text-indigo-500"),t.type="button",t.ariaLabel=t.title="Copy code to clipboard";const n='';t.innerHTML=n;const r=e.parentElement;r.classList.add("copyable"),r.append(t),t.addEventListener("click",(()=>{let r=e.textContent.trim();if(r.startsWith("#")){const e=r.split("\n");e.shift(),r=e.join("\n")}window.navigator.clipboard.writeText(r),t.innerHTML='',setTimeout((()=>{t.innerHTML=n}),1e3)}))}))}}},447:function(e,t,n){"use strict";n.r(t);var r=n(891),o=n(61);t.default=class extends r.xI{connect(){(0,o.b)("flasher")}}},162:function(e,t,n){"use strict";n.r(t);var r=n(891);t.default=class extends r.xI{connect(){const e=document.getElementById("menu-toggle"),t=document.getElementById("main-navigation"),n=document.getElementById("main-article");function r(e,t){e.classList.contains(t)?e.classList.remove(t):e.classList.add(t)}e.addEventListener("click",(o=>{o.preventDefault(),r(e,"menu-closed"),r(t,"hidden"),r(n,"hidden")}))}}},880:function(e,t,n){"use strict";n.r(t);var r=n(891),o=n(61);t.default=class extends r.xI{connect(){(0,o.b)("noty")}}},326:function(e,t,n){"use strict";n.r(t);var r=n(891),o=n(61);t.default=class extends r.xI{connect(){(0,o.b)("notyf")}}},995:function(e,t,n){"use strict";n.r(t);var r=n(891);t.default=class extends r.xI{connect(){const e=document.querySelectorAll(".prev-next");let t,n,r;function o(e,t){document.querySelectorAll(e).forEach((e=>{e.querySelector("span").innerHTML=t.innerHTML.replace(/\d+\. /,"").replace(/<(\S*?)[^>]*>.*?<\/\1>|<.*?\/>/,""),e.href=t.href,e.classList.remove("hidden"),e.classList.remove("sm:hidden")}))}document.getElementById("main-navigation").querySelectorAll("a").forEach((e=>{void 0===n&&!1!==e.href.includes("/docs/")&&(e.classList.contains("text-white")?r=e:void 0===r?t=e:void 0===n&&(n=e))})),void 0!==r&&(e.forEach((e=>{e.classList.remove("hidden")})),t&&o(".link-previous",t),n&&o(".link-next",n))}}},234:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return Pr}});var r={};n.r(r),n.d(r,{hasBrowserEnv:function(){return oe},hasStandardBrowserEnv:function(){return ie},hasStandardBrowserWebWorkerEnv:function(){return ae}});var o=n(891);function i(e,t){return function(){return e.apply(t,arguments)}}const{toString:s}=Object.prototype,{getPrototypeOf:a}=Object,l=(c=Object.create(null),e=>{const t=s.call(e);return c[t]||(c[t]=t.slice(8,-1).toLowerCase())});var c;const u=e=>(e=e.toLowerCase(),t=>l(t)===e),d=e=>t=>typeof t===e,{isArray:h}=Array,p=d("undefined");const f=u("ArrayBuffer");const m=d("string"),g=d("function"),v=d("number"),y=e=>null!==e&&"object"==typeof e,w=e=>{if("object"!==l(e))return!1;const t=a(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},b=u("Date"),x=u("File"),C=u("Blob"),E=u("FileList"),O=u("URLSearchParams");function A(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),h(e))for(r=0,o=e.length;r0;)if(r=n[o],t===r.toLowerCase())return r;return null}const S="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,T=e=>!p(e)&&e!==S;const _=(N="undefined"!=typeof Uint8Array&&a(Uint8Array),e=>N&&e instanceof N);var N;const j=u("HTMLFormElement"),P=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),L=u("RegExp"),M=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};A(n,((n,o)=>{let i;!1!==(i=t(n,o,e))&&(r[o]=i||n)})),Object.defineProperties(e,r)},D="abcdefghijklmnopqrstuvwxyz",R="0123456789",B={DIGIT:R,ALPHA:D,ALPHA_DIGIT:D+D.toUpperCase()+R};const F=u("AsyncFunction");var q={isArray:h,isArrayBuffer:f,isBuffer:function(e){return null!==e&&!p(e)&&null!==e.constructor&&!p(e.constructor)&&g(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||g(e.append)&&("formdata"===(t=l(e))||"object"===t&&g(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&f(e.buffer),t},isString:m,isNumber:v,isBoolean:e=>!0===e||!1===e,isObject:y,isPlainObject:w,isUndefined:p,isDate:b,isFile:x,isBlob:C,isRegExp:L,isFunction:g,isStream:e=>y(e)&&g(e.pipe),isURLSearchParams:O,isTypedArray:_,isFileList:E,forEach:A,merge:function e(){const{caseless:t}=T(this)&&this||{},n={},r=(r,o)=>{const i=t&&k(n,o)||o;w(n[i])&&w(r)?n[i]=e(n[i],r):w(r)?n[i]=e({},r):h(r)?n[i]=r.slice():n[i]=r};for(let e=0,t=arguments.length;e(A(t,((t,r)=>{n&&g(t)?e[r]=i(t,n):e[r]=t}),{allOwnKeys:r}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,r)=>{let o,i,s;const l={};if(t=t||{},null==e)return t;do{for(o=Object.getOwnPropertyNames(e),i=o.length;i-- >0;)s=o[i],r&&!r(s,e,t)||l[s]||(t[s]=e[s],l[s]=!0);e=!1!==n&&a(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:l,kindOfTest:u,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(h(e))return e;let t=e.length;if(!v(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=n.next())&&!r.done;){const n=r.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:j,hasOwnProperty:P,hasOwnProp:P,reduceDescriptors:M,freezeMethods:e=>{M(e,((t,n)=>{if(g(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=e[n];g(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach((e=>{n[e]=!0}))};return h(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>(e=+e,Number.isFinite(e)?e:t),findKey:k,global:S,isContextDefined:T,ALPHABET:B,generateString:(e=16,t=B.ALPHA_DIGIT)=>{let n="";const{length:r}=t;for(;e--;)n+=t[Math.random()*r|0];return n},isSpecCompliantForm:function(e){return!!(e&&g(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:e=>{const t=new Array(10),n=(e,r)=>{if(y(e)){if(t.indexOf(e)>=0)return;if(!("toJSON"in e)){t[r]=e;const o=h(e)?[]:{};return A(e,((e,t)=>{const i=n(e,r+1);!p(i)&&(o[t]=i)})),t[r]=void 0,o}}return e};return n(e,0)},isAsyncFn:F,isThenable:e=>e&&(y(e)||g(e))&&g(e.then)&&g(e.catch)};function I(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o)}q.inherits(I,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:q.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const H=I.prototype,$={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{$[e]={value:e}})),Object.defineProperties(I,$),Object.defineProperty(H,"isAxiosError",{value:!0}),I.from=(e,t,n,r,o,i)=>{const s=Object.create(H);return q.toFlatObject(e,s,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e)),I.call(s,e.message,t,n,r,o),s.cause=e,s.name=e.name,i&&Object.assign(s,i),s};var U=I;function z(e){return q.isPlainObject(e)||q.isArray(e)}function V(e){return q.endsWith(e,"[]")?e.slice(0,-2):e}function W(e,t,n){return e?e.concat(t).map((function(e,t){return e=V(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}const K=q.toFlatObject(q,{},null,(function(e){return/^is[A-Z]/.test(e)}));var G=function(e,t,n){if(!q.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const r=(n=q.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!q.isUndefined(t[e])}))).metaTokens,o=n.visitor||c,i=n.dots,s=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&q.isSpecCompliantForm(t);if(!q.isFunction(o))throw new TypeError("visitor must be a function");function l(e){if(null===e)return"";if(q.isDate(e))return e.toISOString();if(!a&&q.isBlob(e))throw new U("Blob is not supported. Use a Buffer instead.");return q.isArrayBuffer(e)||q.isTypedArray(e)?a&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function c(e,n,o){let a=e;if(e&&!o&&"object"==typeof e)if(q.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(q.isArray(e)&&function(e){return q.isArray(e)&&!e.some(z)}(e)||(q.isFileList(e)||q.endsWith(n,"[]"))&&(a=q.toArray(e)))return n=V(n),a.forEach((function(e,r){!q.isUndefined(e)&&null!==e&&t.append(!0===s?W([n],r,i):null===s?n:n+"[]",l(e))})),!1;return!!z(e)||(t.append(W(o,n,i),l(e)),!1)}const u=[],d=Object.assign(K,{defaultVisitor:c,convertValue:l,isVisitable:z});if(!q.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!q.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+r.join("."));u.push(n),q.forEach(n,(function(n,i){!0===(!(q.isUndefined(n)||null===n)&&o.call(t,n,q.isString(i)?i.trim():i,r,d))&&e(n,r?r.concat(i):[i])})),u.pop()}}(e),t};function J(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function X(e,t){this._pairs=[],e&&G(e,this,t)}const Y=X.prototype;Y.append=function(e,t){this._pairs.push([e,t])},Y.toString=function(e){const t=e?function(t){return e.call(this,t,J)}:J;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};var Z=X;function Q(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function ee(e,t,n){if(!t)return e;const r=n&&n.encode||Q,o=n&&n.serialize;let i;if(i=o?o(t,n):q.isURLSearchParams(t)?t.toString():new Z(t,n).toString(r),i){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}var te=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){q.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},ne={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},re={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:Z,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]};const oe="undefined"!=typeof window&&"undefined"!=typeof document,ie=(se="undefined"!=typeof navigator&&navigator.product,oe&&["ReactNative","NativeScript","NS"].indexOf(se)<0);var se;const ae="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts;var le={...r,...re};var ce=function(e){function t(e,n,r,o){let i=e[o++];if("__proto__"===i)return!0;const s=Number.isFinite(+i),a=o>=e.length;if(i=!i&&q.isArray(r)?r.length:i,a)return q.hasOwnProp(r,i)?r[i]=[r[i],n]:r[i]=n,!s;r[i]&&q.isObject(r[i])||(r[i]=[]);return t(e,n,r[i],o)&&q.isArray(r[i])&&(r[i]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let i;for(r=0;r{t(function(e){return q.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),r,n,0)})),n}return null};const ue={transitional:ne,adapter:["xhr","http"],transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=q.isObject(e);o&&q.isHTMLForm(e)&&(e=new FormData(e));if(q.isFormData(e))return r?JSON.stringify(ce(e)):e;if(q.isArrayBuffer(e)||q.isBuffer(e)||q.isStream(e)||q.isFile(e)||q.isBlob(e))return e;if(q.isArrayBufferView(e))return e.buffer;if(q.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let i;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return G(e,new le.classes.URLSearchParams,Object.assign({visitor:function(e,t,n,r){return le.isNode&&q.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((i=q.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return G(i?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e,t,n){if(q.isString(e))try{return(t||JSON.parse)(e),q.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(n||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||ue.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(e&&q.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e)}catch(e){if(n){if("SyntaxError"===e.name)throw U.from(e,U.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:le.classes.FormData,Blob:le.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};q.forEach(["delete","get","head","post","put","patch"],(e=>{ue.headers[e]={}}));var de=ue;const he=q.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]);const pe=Symbol("internals");function fe(e){return e&&String(e).trim().toLowerCase()}function me(e){return!1===e||null==e?e:q.isArray(e)?e.map(me):String(e)}function ge(e,t,n,r,o){return q.isFunction(r)?r.call(this,t,n):(o&&(t=n),q.isString(t)?q.isString(r)?-1!==t.indexOf(r):q.isRegExp(r)?r.test(t):void 0:void 0)}class ve{constructor(e){e&&this.set(e)}set(e,t,n){const r=this;function o(e,t,n){const o=fe(t);if(!o)throw new Error("header name must be a non-empty string");const i=q.findKey(r,o);(!i||void 0===r[i]||!0===n||void 0===n&&!1!==r[i])&&(r[i||t]=me(e))}const i=(e,t)=>q.forEach(e,((e,n)=>o(e,n,t)));return q.isPlainObject(e)||e instanceof this.constructor?i(e,t):q.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim())?i((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach((function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&he[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)})),t})(e),t):null!=e&&o(t,e,n),this}get(e,t){if(e=fe(e)){const n=q.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(q.isFunction(t))return t.call(this,e,n);if(q.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=fe(e)){const n=q.findKey(this,e);return!(!n||void 0===this[n]||t&&!ge(0,this[n],n,t))}return!1}delete(e,t){const n=this;let r=!1;function o(e){if(e=fe(e)){const o=q.findKey(n,e);!o||t&&!ge(0,n[o],o,t)||(delete n[o],r=!0)}}return q.isArray(e)?e.forEach(o):o(e),r}clear(e){const t=Object.keys(this);let n=t.length,r=!1;for(;n--;){const o=t[n];e&&!ge(0,this[o],o,e,!0)||(delete this[o],r=!0)}return r}normalize(e){const t=this,n={};return q.forEach(this,((r,o)=>{const i=q.findKey(n,o);if(i)return t[i]=me(r),void delete t[o];const s=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(o):String(o).trim();s!==o&&delete t[o],t[s]=me(r),n[s]=!0})),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return q.forEach(this,((n,r)=>{null!=n&&!1!==n&&(t[r]=e&&q.isArray(n)?n.join(", "):n)})),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([e,t])=>e+": "+t)).join("\n")}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach((e=>n.set(e))),n}static accessor(e){const t=(this[pe]=this[pe]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=fe(e);t[r]||(!function(e,t){const n=q.toCamelCase(" "+t);["get","set","has"].forEach((r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})}))}(n,e),t[r]=!0)}return q.isArray(e)?e.forEach(r):r(e),this}}ve.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),q.reduceDescriptors(ve.prototype,(({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}})),q.freezeMethods(ve);var ye=ve;function we(e,t){const n=this||de,r=t||n,o=ye.from(r.headers);let i=r.data;return q.forEach(e,(function(e){i=e.call(n,i,o.normalize(),t?t.status:void 0)})),o.normalize(),i}function be(e){return!(!e||!e.__CANCEL__)}function xe(e,t,n){U.call(this,null==e?"canceled":e,U.ERR_CANCELED,t,n),this.name="CanceledError"}q.inherits(xe,U,{__CANCEL__:!0});var Ce=xe;var Ee=le.hasStandardBrowserEnv?{write(e,t,n,r,o,i){const s=[e+"="+encodeURIComponent(t)];q.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),q.isString(r)&&s.push("path="+r),q.isString(o)&&s.push("domain="+o),!0===i&&s.push("secure"),document.cookie=s.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function Oe(e,t){return e&&!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}var Ae=le.hasStandardBrowserEnv?function(){const e=/(msie|trident)/i.test(navigator.userAgent),t=document.createElement("a");let n;function r(n){let r=n;return e&&(t.setAttribute("href",r),r=t.href),t.setAttribute("href",r),{href:t.href,protocol:t.protocol?t.protocol.replace(/:$/,""):"",host:t.host,search:t.search?t.search.replace(/^\?/,""):"",hash:t.hash?t.hash.replace(/^#/,""):"",hostname:t.hostname,port:t.port,pathname:"/"===t.pathname.charAt(0)?t.pathname:"/"+t.pathname}}return n=r(window.location.href),function(e){const t=q.isString(e)?r(e):e;return t.protocol===n.protocol&&t.host===n.host}}():function(){return!0};var ke=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,i=0,s=0;return t=void 0!==t?t:1e3,function(a){const l=Date.now(),c=r[s];o||(o=l),n[i]=a,r[i]=l;let u=s,d=0;for(;u!==i;)d+=n[u++],u%=e;if(i=(i+1)%e,i===s&&(s=(s+1)%e),l-o{const i=o.loaded,s=o.lengthComputable?o.total:void 0,a=i-n,l=r(a);n=i;const c={loaded:i,total:s,progress:s?i/s:void 0,bytes:a,rate:l||void 0,estimated:l&&s&&i<=s?(s-i)/l:void 0,event:o};c[t?"download":"upload"]=!0,e(c)}}const Te={http:null,xhr:"undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,n){let r=e.data;const o=ye.from(e.headers).normalize();let i,s,{responseType:a,withXSRFToken:l}=e;function c(){e.cancelToken&&e.cancelToken.unsubscribe(i),e.signal&&e.signal.removeEventListener("abort",i)}if(q.isFormData(r))if(le.hasStandardBrowserEnv||le.hasStandardBrowserWebWorkerEnv)o.setContentType(!1);else if(!1!==(s=o.getContentType())){const[e,...t]=s?s.split(";").map((e=>e.trim())).filter(Boolean):[];o.setContentType([e||"multipart/form-data",...t].join("; "))}let u=new XMLHttpRequest;if(e.auth){const t=e.auth.username||"",n=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";o.set("Authorization","Basic "+btoa(t+":"+n))}const d=Oe(e.baseURL,e.url);function h(){if(!u)return;const r=ye.from("getAllResponseHeaders"in u&&u.getAllResponseHeaders());!function(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new U("Request failed with status code "+n.status,[U.ERR_BAD_REQUEST,U.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}((function(e){t(e),c()}),(function(e){n(e),c()}),{data:a&&"text"!==a&&"json"!==a?u.response:u.responseText,status:u.status,statusText:u.statusText,headers:r,config:e,request:u}),u=null}if(u.open(e.method.toUpperCase(),ee(d,e.params,e.paramsSerializer),!0),u.timeout=e.timeout,"onloadend"in u?u.onloadend=h:u.onreadystatechange=function(){u&&4===u.readyState&&(0!==u.status||u.responseURL&&0===u.responseURL.indexOf("file:"))&&setTimeout(h)},u.onabort=function(){u&&(n(new U("Request aborted",U.ECONNABORTED,e,u)),u=null)},u.onerror=function(){n(new U("Network Error",U.ERR_NETWORK,e,u)),u=null},u.ontimeout=function(){let t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const r=e.transitional||ne;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(new U(t,r.clarifyTimeoutError?U.ETIMEDOUT:U.ECONNABORTED,e,u)),u=null},le.hasStandardBrowserEnv&&(l&&q.isFunction(l)&&(l=l(e)),l||!1!==l&&Ae(d))){const t=e.xsrfHeaderName&&e.xsrfCookieName&&Ee.read(e.xsrfCookieName);t&&o.set(e.xsrfHeaderName,t)}void 0===r&&o.setContentType(null),"setRequestHeader"in u&&q.forEach(o.toJSON(),(function(e,t){u.setRequestHeader(t,e)})),q.isUndefined(e.withCredentials)||(u.withCredentials=!!e.withCredentials),a&&"json"!==a&&(u.responseType=e.responseType),"function"==typeof e.onDownloadProgress&&u.addEventListener("progress",Se(e.onDownloadProgress,!0)),"function"==typeof e.onUploadProgress&&u.upload&&u.upload.addEventListener("progress",Se(e.onUploadProgress)),(e.cancelToken||e.signal)&&(i=t=>{u&&(n(!t||t.type?new Ce(null,e,u):t),u.abort(),u=null)},e.cancelToken&&e.cancelToken.subscribe(i),e.signal&&(e.signal.aborted?i():e.signal.addEventListener("abort",i)));const p=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(d);p&&-1===le.protocols.indexOf(p)?n(new U("Unsupported protocol "+p+":",U.ERR_BAD_REQUEST,e)):u.send(r||null)}))}};q.forEach(Te,((e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));const _e=e=>`- ${e}`,Ne=e=>q.isFunction(e)||null===e||!1===e;var je=e=>{e=q.isArray(e)?e:[e];const{length:t}=e;let n,r;const o={};for(let i=0;i`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build")));let n=t?e.length>1?"since :\n"+e.map(_e).join("\n"):" "+_e(e[0]):"as no adapter specified";throw new U("There is no suitable adapter to dispatch the request "+n,"ERR_NOT_SUPPORT")}return r};function Pe(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Ce(null,e)}function Le(e){Pe(e),e.headers=ye.from(e.headers),e.data=we.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1);return je(e.adapter||de.adapter)(e).then((function(t){return Pe(e),t.data=we.call(e,e.transformResponse,t),t.headers=ye.from(t.headers),t}),(function(t){return be(t)||(Pe(e),t&&t.response&&(t.response.data=we.call(e,e.transformResponse,t.response),t.response.headers=ye.from(t.response.headers))),Promise.reject(t)}))}const Me=e=>e instanceof ye?{...e}:e;function De(e,t){t=t||{};const n={};function r(e,t,n){return q.isPlainObject(e)&&q.isPlainObject(t)?q.merge.call({caseless:n},e,t):q.isPlainObject(t)?q.merge({},t):q.isArray(t)?t.slice():t}function o(e,t,n){return q.isUndefined(t)?q.isUndefined(e)?void 0:r(void 0,e,n):r(e,t,n)}function i(e,t){if(!q.isUndefined(t))return r(void 0,t)}function s(e,t){return q.isUndefined(t)?q.isUndefined(e)?void 0:r(void 0,e):r(void 0,t)}function a(n,o,i){return i in t?r(n,o):i in e?r(void 0,n):void 0}const l={url:i,method:i,data:i,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(e,t)=>o(Me(e),Me(t),!0)};return q.forEach(Object.keys(Object.assign({},e,t)),(function(r){const i=l[r]||o,s=i(e[r],t[r],r);q.isUndefined(s)&&i!==a||(n[r]=s)})),n}const Re="1.6.8",Be={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{Be[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const Fe={};Be.transitional=function(e,t,n){function r(e,t){return"[Axios v1.6.8] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,i)=>{if(!1===e)throw new U(r(o," has been removed"+(t?" in "+t:"")),U.ERR_DEPRECATED);return t&&!Fe[o]&&(Fe[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,i)}};var qe={assertOptions:function(e,t,n){if("object"!=typeof e)throw new U("options must be an object",U.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const i=r[o],s=t[i];if(s){const t=e[i],n=void 0===t||s(t,i,e);if(!0!==n)throw new U("option "+i+" must be "+n,U.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new U("Unknown option "+i,U.ERR_BAD_OPTION)}},validators:Be};const Ie=qe.validators;class He{constructor(e){this.defaults=e,this.interceptors={request:new te,response:new te}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t;Error.captureStackTrace?Error.captureStackTrace(t={}):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=De(this.defaults,t);const{transitional:n,paramsSerializer:r,headers:o}=t;void 0!==n&&qe.assertOptions(n,{silentJSONParsing:Ie.transitional(Ie.boolean),forcedJSONParsing:Ie.transitional(Ie.boolean),clarifyTimeoutError:Ie.transitional(Ie.boolean)},!1),null!=r&&(q.isFunction(r)?t.paramsSerializer={serialize:r}:qe.assertOptions(r,{encode:Ie.function,serialize:Ie.function},!0)),t.method=(t.method||this.defaults.method||"get").toLowerCase();let i=o&&q.merge(o.common,o[t.method]);o&&q.forEach(["delete","get","head","post","put","patch","common"],(e=>{delete o[e]})),t.headers=ye.concat(i,o);const s=[];let a=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,s.unshift(e.fulfilled,e.rejected))}));const l=[];let c;this.interceptors.response.forEach((function(e){l.push(e.fulfilled,e.rejected)}));let u,d=0;if(!a){const e=[Le.bind(this),void 0];for(e.unshift.apply(e,s),e.push.apply(e,l),u=e.length,c=Promise.resolve(t);d{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const r=new Promise((e=>{n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e((function(e,r,o){n.reason||(n.reason=new Ce(e,r,o),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}static source(){let e;return{token:new Ue((function(t){e=t})),cancel:e}}}var ze=Ue;const Ve={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ve).forEach((([e,t])=>{Ve[t]=e}));var We=Ve;const Ke=function e(t){const n=new $e(t),r=i($e.prototype.request,n);return q.extend(r,$e.prototype,n,{allOwnKeys:!0}),q.extend(r,n,null,{allOwnKeys:!0}),r.create=function(n){return e(De(t,n))},r}(de);Ke.Axios=$e,Ke.CanceledError=Ce,Ke.CancelToken=ze,Ke.isCancel=be,Ke.VERSION=Re,Ke.toFormData=G,Ke.AxiosError=U,Ke.Cancel=Ke.CanceledError,Ke.all=function(e){return Promise.all(e)},Ke.spread=function(e){return function(t){return e.apply(null,t)}},Ke.isAxiosError=function(e){return q.isObject(e)&&!0===e.isAxiosError},Ke.mergeConfig=De,Ke.AxiosHeaders=ye,Ke.formToJSON=e=>ce(q.isHTMLForm(e)?new FormData(e):e),Ke.getAdapter=je,Ke.HttpStatusCode=We,Ke.default=Ke;var Ge=Ke,Je=(n(499),n(353)),Xe=Object.defineProperty,Ye=(e,t)=>Xe(e,"name",{value:t,configurable:!0}),Ze=Ye((e=>{const t=Object.keys(e).sort();return Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(e).forEach((n=>{Object.getOwnPropertyDescriptor(e,n).enumerable&&t.push(n)})),t}),"getKeysOfEnumerableProperties");function Qe(e,t,n,r,o,i,s=": "){let a="",l=e.next();if(!l.done){a+=t.spacingOuter;const c=n+t.indent;for(;!l.done;){a+=c+i(l.value[0],t,c,r,o)+s+i(l.value[1],t,c,r,o),l=e.next(),l.done?t.min||(a+=","):a+=","+t.spacingInner}a+=t.spacingOuter+n}return a}function et(e,t,n,r,o,i){let s="",a=e.next();if(!a.done){s+=t.spacingOuter;const l=n+t.indent;for(;!a.done;)s+=l+i(a.value,t,l,r,o),a=e.next(),a.done?t.min||(s+=","):s+=","+t.spacingInner;s+=t.spacingOuter+n}return s}function tt(e,t,n,r,o,i){let s="";if(e.length){s+=t.spacingOuter;const a=n+t.indent;for(let n=0;n/g,">")}Ye(rt,"escapeHTML");function ot(e){return 3===e.nodeType}function it(e){return 8===e.nodeType}function st(e){return 11===e.nodeType}Ye(ot,"nodeIsText"),Ye(it,"nodeIsComment"),Ye(st,"nodeIsFragment");var at=Object.prototype.toString,lt=Date.prototype.toISOString,ct=Error.prototype.toString,ut=RegExp.prototype.toString,dt=Ye((e=>"function"==typeof e.constructor&&e.constructor.name||"Object"),"getConstructorName"),ht=Ye((e=>"undefined"!=typeof window&&e===window),"isWindow"),pt=/^Symbol\((.*)\)(.*)$/,ft=/\n/gi,mt=class extends Error{constructor(e,t){super(e),this.stack=t,this.name=this.constructor.name}};function gt(e){return"[object Array]"===e||"[object ArrayBuffer]"===e||"[object DataView]"===e||"[object Float32Array]"===e||"[object Float64Array]"===e||"[object Int8Array]"===e||"[object Int16Array]"===e||"[object Int32Array]"===e||"[object Uint8Array]"===e||"[object Uint8ClampedArray]"===e||"[object Uint16Array]"===e||"[object Uint32Array]"===e}function vt(e){return Object.is(e,-0)?"-0":String(e)}function yt(e){return String(`${e}n`)}function wt(e,t){return t?"[Function "+(e.name||"anonymous")+"]":"[Function]"}function bt(e){return String(e).replace(pt,"Symbol($1)")}function xt(e){return"["+ct.call(e)+"]"}function Ct(e,t,n,r){if(!0===e||!1===e)return""+e;if(void 0===e)return"undefined";if(null===e)return"null";const o=typeof e;if("number"===o)return vt(e);if("bigint"===o)return yt(e);if("string"===o)return r?'"'+e.replace(/"|\\/g,"\\$&")+'"':'"'+e+'"';if("function"===o)return wt(e,t);if("symbol"===o)return bt(e);const i=at.call(e);return"[object WeakMap]"===i?"WeakMap {}":"[object WeakSet]"===i?"WeakSet {}":"[object Function]"===i||"[object GeneratorFunction]"===i?wt(e,t):"[object Symbol]"===i?bt(e):"[object Date]"===i?isNaN(+e)?"Date { NaN }":lt.call(e):"[object Error]"===i?xt(e):"[object RegExp]"===i?n?ut.call(e).replace(/[\\^$*+?.()|[\]{}]/g,"\\$&"):ut.call(e):e instanceof Error?xt(e):null}function Et(e,t,n,r,o,i){if(-1!==o.indexOf(e))return"[Circular]";(o=o.slice()).push(e);const s=++r>t.maxDepth,a=t.min;if(t.callToJSON&&!s&&e.toJSON&&"function"==typeof e.toJSON&&!i)return St(e.toJSON(),t,n,r,o,!0);const l=at.call(e);return"[object Arguments]"===l?s?"[Arguments]":(a?"":"Arguments ")+"["+tt(e,t,n,r,o,St)+"]":gt(l)?s?"["+e.constructor.name+"]":(a?"":e.constructor.name+" ")+"["+tt(e,t,n,r,o,St)+"]":"[object Map]"===l?s?"[Map]":"Map {"+Qe(e.entries(),t,n,r,o,St," => ")+"}":"[object Set]"===l?s?"[Set]":"Set {"+et(e.values(),t,n,r,o,St)+"}":s||ht(e)?"["+dt(e)+"]":(a?"":dt(e)+" ")+"{"+nt(e,t,n,r,o,St)+"}"}function Ot(e){return null!=e.serialize}function At(e,t,n,r,o,i){let s;try{s=Ot(e)?e.serialize(t,n,r,o,i,St):e.print(t,(e=>St(e,n,r,o,i)),(e=>{const t=r+n.indent;return t+e.replace(ft,"\n"+t)}),{edgeSpacing:n.spacingOuter,min:n.min,spacing:n.spacingInner},n.colors)}catch(e){throw new mt(e.message,e.stack)}if("string"!=typeof s)throw new Error(`pretty-format: Plugin must return type "string" but instead returned "${typeof s}".`);return s}function kt(e,t){for(let n=0;n{if(!Nt.hasOwnProperty(e))throw new Error(`pretty-format: Unknown option "${e}".`)})),e.min&&void 0!==e.indent&&0!==e.indent)throw new Error('pretty-format: Options "min" and "indent" cannot be used together.');if(void 0!==e.theme){if(null===e.theme)throw new Error('pretty-format: Option "theme" must not be null.');if("object"!=typeof e.theme)throw new Error(`pretty-format: Option "theme" must be of type "object" but instead received "${typeof e.theme}".`)}}Ye(jt,"validateOptions");var Pt=Ye((e=>_t.reduce(((t,n)=>{const r=e.theme&&void 0!==e.theme[n]?e.theme[n]:Tt[n],o=r&&Je[r];if(!o||"string"!=typeof o.close||"string"!=typeof o.open)throw new Error(`pretty-format: Option "theme" has a key "${n}" whose value "${r}" is undefined in ansi-styles.`);return t[n]=o,t}),Object.create(null))),"getColorsHighlight"),Lt=Ye((()=>_t.reduce(((e,t)=>(e[t]={close:"",open:""},e)),Object.create(null))),"getColorsEmpty"),Mt=Ye((e=>e&&void 0!==e.printFunctionName?e.printFunctionName:Nt.printFunctionName),"getPrintFunctionName"),Dt=Ye((e=>e&&void 0!==e.escapeRegex?e.escapeRegex:Nt.escapeRegex),"getEscapeRegex"),Rt=Ye((e=>e&&void 0!==e.escapeString?e.escapeString:Nt.escapeString),"getEscapeString"),Bt=Ye((e=>({callToJSON:e&&void 0!==e.callToJSON?e.callToJSON:Nt.callToJSON,colors:e&&e.highlight?Pt(e):Lt(),escapeRegex:Dt(e),escapeString:Rt(e),indent:e&&e.min?"":Ft(e&&void 0!==e.indent?e.indent:Nt.indent),maxDepth:e&&void 0!==e.maxDepth?e.maxDepth:Nt.maxDepth,min:e&&void 0!==e.min?e.min:Nt.min,plugins:e&&void 0!==e.plugins?e.plugins:Nt.plugins,printFunctionName:Mt(e),spacingInner:e&&e.min?" ":"\n",spacingOuter:e&&e.min?"":"\n"})),"getConfig");function Ft(e){return new Array(e+1).join(" ")}function qt(e,t){if(t&&(jt(t),t.plugins)){const n=kt(t.plugins,e);if(null!==n)return At(n,e,Bt(t),"",0,[])}const n=Ct(e,Mt(t),Dt(t),Rt(t));return null!==n?n:Et(e,Bt(t),"",0,[])}Ye(Ft,"createIndent"),Ye(qt,"format");var It={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let Ht;const $t=new Uint8Array(16);function Ut(){if(!Ht&&(Ht="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!Ht))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return Ht($t)}const zt=[];for(let e=0;e<256;++e)zt.push((e+256).toString(16).slice(1));function Vt(e,t=0){return zt[e[t+0]]+zt[e[t+1]]+zt[e[t+2]]+zt[e[t+3]]+"-"+zt[e[t+4]]+zt[e[t+5]]+"-"+zt[e[t+6]]+zt[e[t+7]]+"-"+zt[e[t+8]]+zt[e[t+9]]+"-"+zt[e[t+10]]+zt[e[t+11]]+zt[e[t+12]]+zt[e[t+13]]+zt[e[t+14]]+zt[e[t+15]]}var Wt=function(e,t,n){if(It.randomUUID&&!t&&!e)return It.randomUUID();const r=(e=e||{}).random||(e.rng||Ut)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=r[e];return t}return Vt(r)},Kt=n(139),Gt=n(99),Jt=Object.defineProperty,Xt=(e,t,n)=>(((e,t,n)=>{t in e?Jt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n})(e,"symbol"!=typeof t?t+"":t,n),n);const Yt=class e{constructor(e=23517,t="localhost",n="http"){this.portNumber=e,this.host=t,this.scheme=n}async init(){await this.updateRayAvailability()}isRayAvailable(){return this.attemptAvailableReset(),null===e.rayState&&this.updateRayAvailability(),null===e.rayState||e.rayState}attemptAvailableReset(){null!==e.lastRayStateCheck&&(new Date).getTime()-e.lastRayStateCheck>=3e4&&(e.rayState=null)}async updateRayAvailability(){let t=!0;if(null!==e.lastRayStateCheck&&(new Date).getTime()-e.lastRayStateCheck<3e4)return!0;e.lastRayStateCheck=(new Date).getTime();try{await Ge.get(this.getUrlForPath("/locks/__availabilty_check"),{})}catch(e){t=!1,e.response&&(t=!0)}finally{e.rayState=t}}getUrlForPath(e){var t;return e=e.replace(/^\//,""),`${null!=(t=this.scheme)?t:"http"}://${this.host}:${this.portNumber}/${e}`}async send(t){null!==e.rayState&&null!==e.lastRayStateCheck||this.updateRayAvailability();try{t.payloads=this.ensureAllPayloadsHaveAnOrigin(t.payloads),await Ge.post(this.getUrlForPath("/"),t.toArray(),{withCredentials:!1}),await new Promise((e=>setTimeout(e,50)))}catch(e){}}ensureAllPayloadsHaveAnOrigin(e){return e.forEach((e=>{null!==e.data.origin.file&&""!==e.data.origin.file&&void 0!==e.data.origin.file||(e.data.origin.file="/unknown-file.js",e.data.origin.line_number=1,e.data.origin.function_name="unknown")})),e}async lockExists(e){return new Promise((async(t,n)=>{let r;try{r=await Ge.get(this.getUrlForPath(`/locks/${e}`))}catch(e){return!1}r.data.stop_execution?n(new Error("stopping execution")):(r.data.active,t(r.data))}))}};Xt(Yt,"rayState",!0),Xt(Yt,"lastRayStateCheck",null);let Zt=Yt;class Qt{color(e){return this}green(){return this.color("green")}orange(){return this.color("orange")}red(){return this.color("red")}purple(){return this.color("purple")}blue(){return this.color("blue")}gray(){return this.color("gray")}}class en{screenColor(e){return this}screenGreen(){return this.screenColor("green")}screenOrange(){return this.screenColor("orange")}screenRed(){return this.screenColor("red")}screenPurple(){return this.screenColor("purple")}screenBlue(){return this.screenColor("blue")}screenGray(){return this.screenColor("gray")}}class tn{size(e){return this}small(){return this.size("sm")}large(){return this.size("lg")}}class nn{static removeRayFrames(e){return e.filter((e=>!nn.isRayFrame(e)&&!nn.isNodeFrame(e)))}static isRayFrame(e){var t;for(const n of this.rayNamespaces())if(null==(t=e.fileName)?void 0:t.includes(n))return!0;return!1}static isNodeFrame(e){var t,n;return(null==(t=e.fileName)?void 0:t.includes("node:"))||(null==(n=e.fileName)?void 0:n.includes("node_modules"))||!1}static rayNamespaces(){return["ray-node/dist","node-ray/dist","vue-ray/dist","-ray"]}}const rn=console.log.bind({}),on=(...e)=>{void 0!==Nr.client&&Nr.client.isRayAvailable()&&Nr.create().then((t=>t.send(...e))),rn(...e)},sn=class e{enable(){e.active=!0,console.log=on}disable(){e.active=!1,console.log=rn}active(){return e.active}};Xt(sn,"active",!1);let an=sn;const ln=class e{static get(){var t;return null!=(t=e.hostname)?t:"remote"}static set(t){e.hostname=t}};Xt(ln,"hostname",null);let cn=ln;class un{static convertToPrimitive(e){return null===e?{value:null,isHtml:!1}:"string"==typeof e||"number"==typeof e||"boolean"==typeof e?{value:e,isHtml:!1}:{value:un.prettyFormatForHtml(e),isHtml:!0}}static buildHtmlElement(e,t,n){return`<${e} style="font-size: 0.8rem!important;" class="${t}">${n}`}static prettyFormatForHtml(e){const t=qt(e,{indent:" "}).replaceAll(" "," ").replace(/\r\n|\r|\n/g,"
").replace(/("[^"]+")/g,this.buildHtmlElement("code","bold text-green-600 p-0","$1")).replace(/Array( |\s)+(\[[^\]]+\])/g,this.buildHtmlElement("code","bold text-gray-500 p-0","$1$2")).replace(/^(\[[^\]]+\])$/g,this.buildHtmlElement("code","bold text-gray-500 p-0","$1")).replace(/(\{.+\})/g,this.buildHtmlElement("code","text-gray-600","$1")).replace(/(Array|Object|Number|Function|Circular|Symbol|WeakMap|Map)/g,this.buildHtmlElement("span","bold text-yellow-600","$1")).replaceAll(/(true|false|null|undefined|NaN)/g,this.buildHtmlElement("span","bold text-indigo-600","$1")).replace(/(: |[,[\]{}])/g,this.buildHtmlElement("span","bold text-orange-400","$1"));return this.buildHtmlElement("code","",t)}}class dn{constructor(){Xt(this,"remotePath",null),Xt(this,"localPath",null),Xt(this,"initialized",!1),Xt(this,"data",{type:"",content:"",origin:{function_name:"",file:"",line_number:0,hostname:"remote"}})}replaceRemotePathWithLocalPath(e){if(null===this.remotePath||null===this.localPath)return e;const t=new RegExp(`^${this.remotePath}`);return e.replace(t,this.localPath)}getContent(){return{}}toArray(){return this.initialized||(this.initialized=!0,this.data.type=this.getType(),this.data.content=this.getContent(),this.data.origin.file=this.replaceRemotePathWithLocalPath(this.data.origin.file)),this.data}toJson(){return JSON.stringify(this.toArray())}}class hn extends dn{constructor(e){super(),Xt(this,"value"),this.value=e}getType(){return"custom"}getContent(){return{content:this.value,label:"Boolean"}}}class pn extends dn{constructor(e=""){super(),Xt(this,"html"),this.html=e}getType(){return"custom"}getContent(){return{content:this.html,label:"HTML"}}}class fn extends dn{constructor(e){super(),Xt(this,"values"),this.values=Array.isArray(e)?e:[e]}static createForArguments(e){return new this(e.map((e=>un.convertToPrimitive(e).value)))}getType(){return"log"}getContent(){return{values:this.values}}}class mn extends dn{getType(){return"custom"}getContent(){return{content:null,label:"Null"}}}class gn{constructor(e){Xt(this,"values"),this.values=e}static createForValues(e){return new this(e).getPayloads()}static registerPayloadFinder(e){this.payloadFinder=e}getPayloads(){return this.values.map((e=>this.getPayload(e)))}getPayload(e){if("boolean"==typeof e)return new hn(e);if(null===e)return new mn;const t=un.convertToPrimitive(e);return t.isHtml?new pn(t.value):new fn(t.value)}}Xt(gn,"payloadFinder",null);class vn extends dn{constructor(e){super(),Xt(this,"frames"),this.frames=nn.removeRayFrames(e)}getType(){return"caller"}getContent(){var e,t,n,r,o,i,s,a;const l=this.frames.slice(0)[0]||null,c=null!=(r=null==(n=null==(t=null==(e=null==l?void 0:l.getFunctionName())?void 0:e.replace("Proxy.",""))?void 0:t.split("."))?void 0:n.slice(0))?r:[];return{frame:{file_name:this.replaceRemotePathWithLocalPath(null!=(o=null==l?void 0:l.getFileName())?o:""),line_number:(null==l?void 0:l.getLineNumber())||0,class:null!=(i=c[0])?i:"",method:c?c.slice(1).join("."):"",vendor_frame:null!=(a=null==(s=null==l?void 0:l.getFileName())?void 0:s.includes("node_modules"))&&a}}}}class yn extends dn{getType(){return"clear_all"}}class wn extends dn{constructor(e){super(),Xt(this,"color"),this.color=e}getType(){return"color"}getContent(){return{color:this.color}}}class bn extends dn{getType(){return"confetti"}}class xn extends dn{constructor(e){super(),Xt(this,"name"),this.name=e}getType(){return"create_lock"}getContent(){return{name:this.name}}}class Cn extends dn{constructor(e,t=""){super(),Xt(this,"content"),Xt(this,"label"),this.content=e,this.label=t}getType(){return"custom"}getContent(){return{content:this.content,label:this.label}}}function En(e,t){if(void 0===t&&(t=e,e=0),"number"!=typeof e||"number"!=typeof t)throw new TypeError("Expected all arguments to be numbers");return Math.floor(Math.random()*(t-e+1)+e)}const On=e=>{const t=(new Date).getTime();for(;(new Date).getTime()(t.encodeEntities&&(e=(e=>{const t={"¢":"cent","£":"pound","¥":"yen","€":"euro","©":"copy","®":"reg","<":"lt",">":"gt",'"':"quot","&":"amp","'":"#39"},n=Object.keys(t),r=new RegExp(`[${n.join("")}]`,"g");return e.replace(r,(e=>`&${t[e]};`))})(e)),e.replace(/^(\s+)/gm,(e=>{return`${t=e," ".repeat(t.length)}`;var t})).replace(/(\r\n|\r|\n)/g,"
")),kn=e=>!!e.length&&e[e.length-1];function Sn(e){const t="0123456789abcdef";function n(e){let n,r="";for(n=0;n<=3;n++)r+=t.charAt(e>>8*n+4&15)+t.charAt(e>>8*n&15);return r}function r(e,t){const n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function o(e,t,n,o,i,s){return r((a=r(r(t,e),r(o,s)))<<(l=i)|a>>>32-l,n);var a,l}function i(e,t,n,r,i,s,a){return o(t&n|~t&r,e,t,i,s,a)}function s(e,t,n,r,i,s,a){return o(t&r|n&~r,e,t,i,s,a)}function a(e,t,n,r,i,s,a){return o(t^n^r,e,t,i,s,a)}function l(e,t,n,r,i,s,a){return o(n^(t|~r),e,t,i,s,a)}let c,u,d,h,p,f=1732584193,m=-271733879,g=-1732584194,v=271733878;const y=function(e){let t;const n=1+(e.length+8>>6),r=new Array(16*n);for(t=0;t<16*n;t++)r[t]=0;for(t=0;t>2]|=e.charCodeAt(t)<>2]|=128<e<10?`0${e}`:e,r={YYYY:()=>e.getFullYear(),YY:()=>String(e.getFullYear()).slice(-2),MM:()=>n(e.getMonth()+1),M:()=>e.getMonth()+1,DD:()=>n(e.getDate()),D:()=>e.getDate(),HH:()=>n(e.getHours()),H:()=>e.getHours(),hh:()=>n(e.getHours()%12||12),h:()=>e.getHours()%12||12,mm:()=>n(e.getMinutes()),m:()=>e.getMinutes(),ss:()=>n(e.getSeconds()),s:()=>e.getSeconds(),A:()=>e.getHours()<12?"AM":"PM",a:()=>e.getHours()<12?"am":"pm",T:()=>(e=>{const t=new Intl.DateTimeFormat("en",{timeZoneName:"short"}).formatToParts(e).find((e=>"timeZoneName"===e.type));return t?t.value:""})(e),Z:()=>{const t=e.getTimezoneOffset();return`${(t>0?"-":"+")+n(Math.floor(Math.abs(t)/60))}:${n(Math.abs(t)%60)}`},z:()=>{const t=e.getTimezoneOffset();return""+((t>0?"-":"+")+n(Math.floor(Math.abs(t)/60))+n(Math.abs(t)%60))}};let o="",i=!1;for(let e=0;e${this.err.name}:
${this.err.message}`}}class Pn extends dn{constructor(e,t){super(),Xt(this,"eventName"),Xt(this,"payload"),this.eventName=e,this.payload=t}getType(){return"event"}getContent(){return{name:this.eventName,event:this.payload[0],payload:un.convertToPrimitive(this.payload).value,class_based_event:!0}}}class Ln extends dn{constructor(e,t={}){super(),Xt(this,"exception"),Xt(this,"meta",{}),Xt(this,"stack"),this.exception=e,this.meta=t}static async make(e,t={}){const n=new Ln(e,t);return n.stack=await Kt.get(),n}getType(){return"exception"}getContent(){return{class:this.exception.name,message:this.exception.message,frames:this.getFrames(),meta:this.meta}}getFrames(){return this.stack.slice(1).map((e=>{var t,n,r,o;const i=null!=(n=null==(t=e.functionName)?void 0:t.split("."))?n:["unknown","unknown"],s=i.pop();let a="string"!=typeof e.functionName?"unknown":i.pop();void 0===e.functionName&&(a="unknown");return{file_name:this.replaceRemotePathWithLocalPath(null!=(r=e.getFileName())?r:""),line_number:e.getLineNumber(),class:a,method:void 0===e.fileName?"":s,vendor_frame:null==(o=e.getFileName())?void 0:o.includes("node_modules"),snippet:[]}})).filter((e=>!e.file_name.startsWith("node:"))).filter((e=>!e.file_name.includes("jest-circus"))).filter((e=>"Ray"!==e.class&&"exception"!==e.method))}}class Mn extends dn{getType(){return"hide_app"}}class Dn extends dn{getType(){return"hide"}}class Rn extends dn{constructor(e,t={highlight:"none"}){super(),Xt(this,"value"),Xt(this,"options"),this.value=e,this.options=t}getType(){return"custom"}getContent(){return{content:this.formatMarkupForDisplay(this.value),label:"Markup"}}formatMarkupForDisplay(e){const t=this.formatAndIndentMarkup(e);return this.highlightHtmlMarkup(An(t,{encodeEntities:!0}))}formatAndIndentMarkup(e){return Gt(e.toString(),{indentation:" ",collapseContent:!0,lineSeparator:"\n"})}highlightHtmlMarkup(e){return e.replace(/"/g,'"').replace(/="([^"]+)"/g,"="$1"").replace(/(<[A-Za-z\d-]+)(\s| |>)/g,'$1$2').replace(/(<\/[A-Za-z\d-]+)(>)/g,'$1$2')}}class Bn extends dn{constructor(e){super(),Xt(this,"location"),this.location=e}getType(){return"custom"}getContent(){return{content:``,label:"Image"}}}class Fn extends dn{constructor(e){super(),Xt(this,"value"),this.value=e}getType(){return"json_string"}getContent(){return{value:JSON.stringify(this.value)}}}class qn extends dn{constructor(e){super(),Xt(this,"label"),this.label=e}getType(){return"label"}getContent(){return{label:this.label}}}class In extends dn{constructor(e,t){super(),Xt(this,"name"),Xt(this,"isNewTimer",!1),Xt(this,"totalTime",0),Xt(this,"maxMemoryUsageDuringTotalTime",0),Xt(this,"timeSinceLastCall",0),Xt(this,"maxMemoryUsageSinceLastCall",0),this.name=e,this.totalTime=t.getDuration(),this.maxMemoryUsageDuringTotalTime=t.getMemory();const n=t.getPeriods();n.length>1&&(this.timeSinceLastCall=kn(n),this.maxMemoryUsageSinceLastCall=0)}getType(){return"measure"}concernsNewTimer(){return this.isNewTimer=!0,this.totalTime=0,this.maxMemoryUsageDuringTotalTime=0,this.timeSinceLastCall=0,this.maxMemoryUsageSinceLastCall=0,this}getContent(){return{name:this.name,is_new_timer:this.isNewTimer,total_time:this.totalTime,max_memory_usage_during_total_time:this.maxMemoryUsageDuringTotalTime,time_since_last_call:this.timeSinceLastCall,max_memory_usage_since_last_call:this.maxMemoryUsageSinceLastCall}}}class Hn extends dn{constructor(e){super(),Xt(this,"name"),this.name=e}getType(){return"new_screen"}getContent(){return{name:this.name}}}class $n extends dn{constructor(e){super(),Xt(this,"text"),this.text=e}getType(){return"notify"}getContent(){return{value:this.text}}}class Un extends dn{getType(){return"remove"}}class zn extends dn{constructor(e){super(),Xt(this,"color"),this.color=e}getType(){return"screen_color"}getContent(){return{color:this.color}}}class Vn extends dn{getType(){return"separator"}}class Wn extends dn{getType(){return"show_app"}}class Kn extends dn{constructor(e){super(),Xt(this,"size"),this.size=e}getType(){return"size"}getContent(){return{size:this.size}}}class Gn extends dn{constructor(e,t="Table"){super(),Xt(this,"values"),Xt(this,"label"),this.values=e,this.label=t}getType(){return"table"}getContent(){return{values:this.getValues(),label:this.label}}getValues(){if(Array.isArray(this.values))return this.values.map((e=>un.convertToPrimitive(e).value));const e={};for(const t in this.values)e[t]=un.convertToPrimitive(this.values[t]).value;return e}}class Jn extends dn{constructor(e){super(),this.text=e}getType(){return"custom"}getContent(){return{content:An(this.text,{encodeEntities:!0}),label:"Text"}}}class Xn extends dn{constructor(e){super(),Xt(this,"frames"),Xt(this,"startFromIndexNum",null),Xt(this,"limitNum",null),this.frames=nn.removeRayFrames(e)}getType(){return"trace"}getContent(){var e;let t=this.frames.map((e=>{var t,n,r,o;const i=null==(t=e.getFunctionName())?void 0:t.replace("Proxy.","").split(".").slice(0),s=(null==i?void 0:i.length)?i.shift():"",a=null!=(n=null==i?void 0:i.join("."))?n:"";return{file_name:this.replaceRemotePathWithLocalPath(null!=(r=e.getFileName())?r:""),line_number:e.getLineNumber(),class:s,method:a,vendor_frame:null==(o=e.getFileName())?void 0:o.includes("node_modules")}}));return null!==this.limitNum&&(t=t.slice(null!=(e=this.startFromIndexNum)?e:0,this.limitNum)),{frames:t}}}class Yn extends dn{constructor(e){super(),Xt(this,"value"),this.value=e}getType(){return"custom"}getContent(){return{content:this.formatXmlForDisplay(this.value),label:"XML"}}formatXmlForDisplay(e){const t=this.formatAndIndentXml(e);return this.encodeXml(t)}encodeXml(e){return An(e,{encodeEntities:!0})}formatAndIndentXml(e){return Gt(e.toString(),{indentation:" ",collapseContent:!0,lineSeparator:"\n"})}}class Zn{constructor(e,t,n={}){Xt(this,"uuid"),Xt(this,"payloads"),Xt(this,"meta"),this.uuid=e,this.payloads=t,this.meta=n}toArray(){return{uuid:this.uuid,payloads:this.payloads.map((e=>e.toArray())),meta:this.meta}}toJson(){return JSON.stringify(this.toArray())}}class Qn{constructor(e){Xt(this,"enable",!0),Xt(this,"_host","localhost"),Xt(this,"_port",23517),Xt(this,"_scheme","http"),Xt(this,"remote_path",null),Xt(this,"local_path",null),Xt(this,"always_send_raw_values",!1),Xt(this,"intercept_console_log",!1),Xt(this,"enabled_callback",null),Xt(this,"sent_payload_callback",null),Xt(this,"sending_payload_callback",null),Xt(this,"originalSettings"),this.originalSettings=Object.assign({},e);for(const t in e)this[t]=e[t]}set host(e){this._host=e,Nr.useClient(new Zt(this.port,this.host,this.scheme))}get host(){return this._host}set port(e){this._port=e,Nr.useClient(new Zt(this.port,this.host,this.scheme))}get port(){return this._port}get scheme(){return this._scheme}set scheme(e){this._scheme=e,Nr.useClient(new Zt(this.port,this.host,this.scheme))}toObject(){return this.originalSettings}}class er{constructor(e,t=null){var n;Xt(this,"name"),Xt(this,"laps",[]),Xt(this,"startedAt"),Xt(this,"endedAt"),Xt(this,"lapTime"),this.name=null==(n=e.name)?void 0:n.slice(0),this.laps=e.laps.slice(0),this.startedAt=e.startedAt,this.endedAt=e.endedAt,this.lapTime=null!=t?t:(new Date).getTime()}getDuration(){return this.laps.reduce(((e,t)=>t+e),0)}getMemory(e=null){return 0}getPeriods(){return this.laps.slice()}getPreviousDuration(){return kn(this.laps)-((new Date).getTime()-this.lapTime)}}class tr{constructor(e=void 0){Xt(this,"name"),Xt(this,"laps",[]),Xt(this,"startedAt",0),Xt(this,"endedAt",0),this.name=e,this.laps=[],this.startedAt=0,this.endedAt=0}initialize(e){this.name=e,this.laps=[],this.startedAt=0,this.endedAt=0}start(e){return this.startedAt=(new Date).getTime(),new er(this)}lap(){const e=(new Date).getTime(),t=e-this.startedAt;return this.laps.push(t-this.totalDuration()),new er(this,e)}stop(){this.endedAt=(new Date).getTime();const e=this.endedAt-this.startedAt;return this.laps.push(e-this.totalDuration()),new er(this)}totalDuration(){return this.laps.reduce(((e,t)=>t+e),0)}reset(){return this.initialize(this.name),this}getLaps(){return this.laps}}class nr{constructor(e){Xt(this,"store",[]),Xt(this,"clock"),this.clock=e}hit(){return this.store.push(this.clock.now()),this}clear(){return this.store=[],this}count(){return this.store.length}countLastSecond(){const e=this.clock.now().subSeconds(1);let t=0;return this.store.forEach((n=>{this.isBetween(n,e,this.clock.now())&&t++})),t}isBetween(e,t,n){return e.getTimestamp()>=t.getTimestamp()&&e.getTimestamp()<=n.getTimestamp()}}class rr{}class or{constructor(e=null){Xt(this,"dateStr"),Xt(this,"dateTs"),Xt(this,"_date"),this._date=null!=e?e:new Date,this.date=this._date,this.dateStr=this.date.toISOString(),this.dateTs=this.date.getTime()}get date(){return this._date}set date(e){this.dateTs=e.getTime(),this.dateStr=e.toISOString()}static createFrom(e){return new or(e)}getTimestamp(){return Math.floor(this.dateTs/1e3)}addSeconds(e){return or.createFrom(new Date(this.dateTs+1e3*e))}subSeconds(e){return or.createFrom(new Date(this.dateTs-1e3*e))}}class ir extends rr{now(){return new or}}class sr{constructor(e=null,t=null){Xt(this,"maxCalls"),Xt(this,"maxPerSecond"),Xt(this,"cache"),Xt(this,"notified",!1),this.maxCalls=e,this.maxPerSecond=t,this.cache=new nr(new ir)}static disabled(){return new sr(null,null)}hit(){return this.cache.hit(),this}max(e=null){return this.maxCalls=e,this}perSecond(e=null){return this.maxPerSecond=e,this}isMaxReached(){if(null===this.maxCalls)return!1;const e=this.cache.count()>=this.maxCalls;return e||(this.notified=!1),e}isMaxPerSecondReached(){if(null===this.maxPerSecond)return!1;const e=this.cache.countLastSecond()>=this.maxPerSecond;return!1===e&&(this.notified=!1),e}clear(){return this.maxCalls=null,this.maxPerSecond=null,this.cache.clear(),this}isNotified(){return this.notified}notify(){this.notified=!0}getCache(){return this.cache}}var ar=(e=>(e.Sending="sending",e.Sent="sent",e))(ar||{});const lr="2.1.2",cr=(e,t,n=[])=>{const r=Object.getOwnPropertyDescriptors(t);for(let e of n)delete r[e];Object.defineProperties(e,r)},ur=(e,t=[e])=>{const n=Object.getPrototypeOf(e);return null===n?t:ur(n,[...t,n])},dr=(e,t,n=[])=>{var r;const o=null!==(r=((...e)=>{if(0===e.length)return;let t;const n=e.map((e=>ur(e)));for(;n.every((e=>e.length>0));){const e=n.map((e=>e.pop())),r=e[0];if(!e.every((e=>e===r)))break;t=r}return t})(...e))&&void 0!==r?r:Object.prototype,i=Object.create(o),s=ur(o);for(let t of e){let e=ur(t);for(let t=e.length-1;t>=0;t--){let r=e[t];-1===s.indexOf(r)&&(cr(i,r,["constructor",...n]),s.push(r))}}return i.constructor=t,i},hr=e=>e.filter(((t,n)=>e.indexOf(t)==n)),pr=(e,t)=>{const n=t.map((e=>ur(e)));let r=0,o=!0;for(;o;){o=!1;for(let i=t.length-1;i>=0;i--){const t=n[i][r];if(null!=t&&(o=!0,null!=Object.getOwnPropertyDescriptor(t,e)))return n[i][0]}r++}},fr=(e,t=Object.prototype)=>new Proxy({},{getPrototypeOf(){return t},setPrototypeOf(){throw Error("Cannot set prototype of Proxies created by ts-mixer")},getOwnPropertyDescriptor(t,n){return Object.getOwnPropertyDescriptor(pr(n,e)||{},n)},defineProperty(){throw new Error("Cannot define new properties on Proxies created by ts-mixer")},has(n,r){return void 0!==pr(r,e)||void 0!==t[r]},get(n,r){return(pr(r,e)||t)[r]},set(t,n,r){const o=pr(n,e);if(void 0===o)throw new Error("Cannot set new properties on Proxies created by ts-mixer");return o[n]=r,!0},deleteProperty(){throw new Error("Cannot delete properties on Proxies created by ts-mixer")},ownKeys(){return e.map(Object.getOwnPropertyNames).reduce(((e,t)=>t.concat(e.filter((e=>t.indexOf(e)<0)))))}}),mr=null,gr="copy",vr="copy",yr="deep",wr=new WeakMap,br=e=>wr.get(e),xr=(e,t)=>{var n,r;const o=hr([...Object.getOwnPropertyNames(e),...Object.getOwnPropertyNames(t)]),i={};for(let s of o)i[s]=hr([...null!==(n=null==e?void 0:e[s])&&void 0!==n?n:[],...null!==(r=null==t?void 0:t[s])&&void 0!==r?r:[]]);return i},Cr=(e,t)=>{var n,r,o,i;return{property:xr(null!==(n=null==e?void 0:e.property)&&void 0!==n?n:{},null!==(r=null==t?void 0:t.property)&&void 0!==r?r:{}),method:xr(null!==(o=null==e?void 0:e.method)&&void 0!==o?o:{},null!==(i=null==t?void 0:t.method)&&void 0!==i?i:{})}},Er=(e,t)=>{var n,r,o,i,s,a;return{class:hr([...null!==(n=null==e?void 0:e.class)&&void 0!==n?n:[],...null!==(r=null==t?void 0:t.class)&&void 0!==r?r:[]]),static:Cr(null!==(o=null==e?void 0:e.static)&&void 0!==o?o:{},null!==(i=null==t?void 0:t.static)&&void 0!==i?i:{}),instance:Cr(null!==(s=null==e?void 0:e.instance)&&void 0!==s?s:{},null!==(a=null==t?void 0:t.instance)&&void 0!==a?a:{})}},Or=new Map,Ar=(...e)=>{const t=((...e)=>{var t;const n=new Set,r=new Set([...e]);for(;r.size>0;)for(let e of r){const o=[...ur(e.prototype).map((e=>e.constructor)),...null!==(t=br(e))&&void 0!==t?t:[]].filter((e=>!n.has(e)));for(let e of o)r.add(e);n.add(e),r.delete(e)}return[...n]})(...e).map((e=>Or.get(e))).filter((e=>!!e));return 0==t.length?{}:1==t.length?t[0]:t.reduce(((e,t)=>Er(e,t)))},kr=e=>{let t=Or.get(e);return t||(t={},Or.set(e,t)),t};function Sr(...e){var t,n,r;const o=e.map((e=>e.prototype)),i=mr;if(null!==i){const e=o.map((e=>e[i])).filter((e=>"function"==typeof e)),t={[i]:function(...t){for(let n of e)n.apply(this,t)}};o.push(t)}function s(...t){for(const n of e)cr(this,new n(...t));null!==i&&"function"==typeof this[i]&&this[i].apply(this,t)}var a,l;s.prototype="copy"===vr?dr(o,s):(a=o,l=s,fr([...a,{constructor:l}])),Object.setPrototypeOf(s,"copy"===gr?dr(e,null,["prototype"]):fr(e,Function.prototype));let c=s;if("none"!==yr){const o="deep"===yr?Ar(...e):((...e)=>{const t=e.map((e=>kr(e)));return 0===t.length?{}:1===t.length?t[0]:t.reduce(((e,t)=>Er(e,t)))})(...e);for(let e of null!==(t=null==o?void 0:o.class)&&void 0!==t?t:[]){const t=e(c);t&&(c=t)}Tr(null!==(n=null==o?void 0:o.static)&&void 0!==n?n:{},c),Tr(null!==(r=null==o?void 0:o.instance)&&void 0!==r?r:{},c.prototype)}var u,d;return u=c,d=e,wr.set(u,d),c}const Tr=(e,t)=>{const n=e.property,r=e.method;if(n)for(let e in n)for(let r of n[e])r(t,e);if(r)for(let e in r)for(let n of r[e])n(t,e,Object.getOwnPropertyDescriptor(t,e))},_r=class e extends(Sr(Qt,tn,en)){constructor(t,n=null,r=null,o=!1){var i,s,a;super(),Xt(this,"inCallback",!1),Xt(this,"settings"),Xt(this,"uuid"),Xt(this,"limitOrigin",null),Xt(this,"canSendPayload",!0),Xt(this,"chaining",!1),Xt(this,"chainedPayloads",[]),!0===e.defaultSettings.not_defined&&(e.defaultSettings={enable:!0,host:"localhost",port:23517,scheme:"http",local_path:null,remote_path:null,always_send_raw_values:!1,enabled_callback:null,sending_payload_callback:null,sent_payload_callback:null,not_defined:!1}),e.defaultSettings=Object.assign({},e.defaultSettings,t.toObject()),this.inCallback=o,this.settings=new Qn(e.defaultSettings),null===e.enabled&&(e.enabled=!1!==this.settings.enable),e.client=null!=(i=null!=n?n:e.client)?i:new Zt(this.settings.port,this.settings.host),e._rateLimiter=null!=(s=e._rateLimiter)?s:sr.disabled(),this.uuid=null!=(a=null!=r?r:e.fakeUuid)?a:(()=>{const e={random:[En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255),En(1,255)]};return Wt(e).toString()})(),this.settings.intercept_console_log&&!this.interceptor().active()&&this.interceptor().enable(),this.loadMacros()}static create(t=null,n=null){!0===e.defaultSettings.not_defined&&(e.defaultSettings={enable:!0,host:"localhost",port:23517,scheme:"http",local_path:null,remote_path:null,always_send_raw_values:!1,not_defined:!1,intercept_console_log:!1,enabled_callback:null,sending_payload_callback:null,sent_payload_callback:null});return new this(new Qn(e.defaultSettings),t,n)}static useDefaultSettings(t){return!0===e.defaultSettings.not_defined&&(e.defaultSettings={enable:!0,host:"localhost",port:23517,scheme:"http",local_path:null,remote_path:null,always_send_raw_values:!1,enabled_callback:null,sending_payload_callback:null,sent_payload_callback:null,not_defined:!1}),e.defaultSettings=Object.assign({},e.defaultSettings,t),e.defaultSettings.not_defined=!1,e.client=new Zt(this.defaultSettings.port,this.defaultSettings.host),this}loadMacros(){for(const t in e.macros){const n=e.macros[t];this[t]=n.bind(this)}return this}interceptor(){return e.interceptor}client(){return e.client}enable(){return e.enabled=!0,this}disable(){return e.enabled=!1,this}enabled(){return"function"==typeof this.settings.enabled_callback?e.enabled&&this.settings.enabled_callback():e.enabled}disabled(){return!this.enabled()}static useClient(e){this.client=e}project(t){return e.projectName=t,this}newScreen(e=""){const t=new Hn(e);return this.sendRequest(t)}clearAll(){const e=new yn;return this.sendRequest(e)}clearScreen(){return this.newScreen()}color(e){const t=new wn(e);return this.sendRequest(t)}confetti(){const e=new bn;return this.sendRequest(e)}screenColor(e){const t=new zn(e);return this.sendRequest(t)}label(e){const t=new qn(e);return this.sendRequest(t)}size(e){const t=new Kn(e);return this.sendRequest(t)}remove(){const e=new Un;return this.sendRequest(e)}hide(){const e=new Dn;return this.sendRequest(e)}notify(e){const t=new $n(e);return this.sendRequest(t)}toJson(...e){const t=e.map((e=>new Fn(e)));return this.sendRequest(t)}json(...e){const t=e.map((e=>new Nn(e)));return this.sendRequest(t)}file(e){throw new Error("file() unsupported on node-ray/web.")}image(e){const t=new Bn(e);return this.sendRequest(t)}die(e=""){throw new Error(`Ray.die() called: ${e||"no message"}`)}className(e){return this.send(e.constructor.name)}error(e){const t=new jn(e,"Error");return this.sendRequest(t).red()}event(e,t=[]){const n=new Pn(e,t);return this.sendRequest(n)}async exception(e,t={}){const n=await Ln.make(e,t);return await this.sendRequest(n).red()}ban(){return this.send("🕶")}charles(){return this.send("🎶 🎹 🎷 🕺")}table(e,t="Table"){const n=new Gn(e,t);return this.sendRequest(n)}async count(t=null){var n;const r=await this.getCaller(),o=Sn(`${null==r?void 0:r.getFileName()}${null==r?void 0:r.getLineNumber()}`),[i,s]=await e.counters.increment(null!=(n=null!=t?t:o)?n:"none");let a="Called ";return t&&(a+=`'${t}' `),a+=`${s} ${1===s?"time":"times"}.`,i.sendCustom(a,"Count"),i}clearCounters(){return e.counters.clear(),this}async pause(){e.lockCounter++;const t=Sn(`${(new Date).getTime()}-${e.lockCounter}`),n=new xn(t);return this.sendRequest(n),new Promise((async(n,r)=>{let o;do{On(1e3*1);try{o=await e.client.lockExists(t)}catch(e){return r(e),!1}if(!0!==o&&o&&o.stop_execution)return r(!1),!1}while(o.active);n(this)}))}stopTime(t=""){return""===t?(e.stopWatches={},this):(void 0!==e.stopWatches[t]&&delete e.stopWatches[t],this)}async caller(){const e=await Kt.get(),t=new vn(e);return this.sendRequest(t)}async trace(){const e=await Kt.get();return this.sendRequest(new Xn(e))}measure(t="default"){if(t instanceof Function)return this.measureClosure(t);if(void 0===e.stopWatches[t]){const n=this.getStopwatch(t);e.stopWatches[t]=n;const r=n.start(t),o=this.getMeasurePayload(t,r);return o.concernsNewTimer(),this.sendRequest(o)}const n=e.stopWatches[t].lap(),r=this.getMeasurePayload(t,n);return this.sendRequest(r)}measureClosure(e){const t=this.getStopwatch("closure");t.start("closure"),e();const n=t.stop(),r=this.getMeasurePayload("closure",n);return this.sendRequest(r)}getStopwatch(e){return new tr(e)}getMeasurePayload(e,t){return new In(e,t)}separator(){const e=new Vn;return this.sendRequest(e)}xml(e){const t=new Yn(e);return this.sendRequest(t)}html(e=""){const t=new pn(e);return this.sendRequest(t)}text(e=""){const t=new Jn(e);return this.sendRequest(t)}date(e){const t=new _n(e);return this.sendRequest(t)}raw(...e){if(!e.length)return this;const t=e.map((e=>fn.createForArguments([e])));return this.sendRequest(t)}send(...e){if(!e.length)return this;if(this.settings.always_send_raw_values)return this.raw(...e);const t=gn.createForValues(e);return this.sendRequest(t)}pass(e){return this.send(e),e}showApp(){const e=new Wn;return this.sendRequest(e)}hideApp(){const e=new Mn;return this.sendRequest(e)}macro(t,n){return e.macros[t]=n,this[t]=n.bind(this),this}htmlMarkup(e,t={}){const n=new Rn(e,t);return this.sendRequest(n)}if(e,t=null){return"function"==typeof e&&(e=e()),e&&null!==t&&t(this),null===t&&(this.canSendPayload=e),this}async limit(t){const n=await this.getCaller();return this.limitOrigin={function_name:null==n?void 0:n.getFunctionName(),file:null==n?void 0:n.getFileName(),line_number:null==n?void 0:n.getLineNumber(),hostname:cn.get()},e.limiters.initialize(this.limitOrigin,t),this}async once(...t){const n=await this.getCaller();return this.limitOrigin={function_name:null==n?void 0:n.getFunctionName(),file:null==n?void 0:n.getFileName(),line_number:null==n?void 0:n.getLineNumber(),hostname:cn.get()},e.limiters.initialize(this.limitOrigin,1),t.length>0?this.send(...t):this}chain(e){return this.chaining=!0,e(this),this.chaining=!1,this.sendRequest(this.chainedPayloads.slice(0)),this.chainedPayloads=[],this}sendCustom(e,t=""){const n=new Cn(e,t);return this.sendRequest(n)}async getOriginFrame(){const e=await Kt.get();let t=e.findIndex((e=>{var t;return null==(t=e.functionName)?void 0:t.includes("Ray.sendRequest")}));-1===t&&(t=0);return nn.removeRayFrames(e.slice(t)).slice(0).shift()}async getCaller(){const e=await Kt.get();let t=e.findIndex((e=>{var t;return null==(t=e.functionName)?void 0:t.includes("Ray.getCaller")}));-1===t&&(t=0);const n=e.slice(t);return 1===n.length?n.shift():n.slice(2).shift()}async getOriginData(){const e=await this.getOriginFrame();return{function_name:null==e?void 0:e.getFunctionName(),file:null==e?void 0:e.getFileName(),line_number:null==e?void 0:e.getLineNumber(),hostname:cn.get()}}prepareMeta(t){return Object.assign({},{node_ray_package_version:lr,project_name:e.projectName},t)}executePayloadCallback(t,n=[]){if(!this.inCallback){this.inCallback=!0;try{t===ar.Sending&&null!==this.settings.sending_payload_callback&&this.settings.sending_payload_callback(new e(this.settings,this.client(),this.uuid,!0),n),t===ar.Sent&&null!==this.settings.sent_payload_callback&&this.settings.sent_payload_callback(this)}catch(e){}this.inCallback=!1}}sendRequest(t,n=[]){if(!this.enabled())return this;if(!this.canSendPayload)return this;if(this.chaining){const e=Array.isArray(t)?t:[t];return this.chainedPayloads.push(...e),this}if(null!==this.limitOrigin){if(!e.limiters.canSendPayload(this.limitOrigin))return this;e.limiters.increment(this.limitOrigin)}return Array.isArray(t)||(t=[t]),this.rateLimiter().isMaxReached()||this.rateLimiter().isMaxPerSecondReached()?(this.rateLimiter().notified=!0,this.notifyWhenRateLimitReached(),this):(t.forEach((e=>{this.getOriginData().then((t=>{e.data.origin=t})),e.remotePath=this.settings.remote_path,e.localPath=this.settings.local_path})),this.executePayloadCallback(ar.Sending,t),e.client.send(new Zn(this.uuid,t,this.prepareMeta(n))),this.rateLimiter().hit(),this.executePayloadCallback(ar.Sent,t),this)}rateLimiter(){return e._rateLimiter}async notifyWhenRateLimitReached(){if(this.rateLimiter().isNotified())return;const t=new Cn("Rate limit has been reached...","Rate limit"),n=new Zn(this.uuid,[t],[]);await e.client.send(n),this.rateLimiter().notify()}standalone(t){void 0!==t&&(t.ray=jr,t.Ray=e)}};Xt(_r,"lockCounter",0),Xt(_r,"defaultSettings",{not_defined:!0}),Xt(_r,"client"),Xt(_r,"projectName",""),Xt(_r,"counters",new class{constructor(){Xt(this,"counters",{})}async increment(e){void 0===this.counters[e]&&(this.counters[e]=[await jr(),0]);const t=this.counters[e],n=t[0],r=t[1]+1;return this.counters[e]=[n,r],[n,r]}get(e){return void 0===this.counters[e]?0:this.counters[e][1]}clear(){this.counters=[]}setRay(e,t){this.counters[e][0]=t}getCounters(){return this.counters}}),Xt(_r,"limiters",new class{constructor(){Xt(this,"counters",{})}initialize(e,t){const n=`${e.file}:${e.line_number}`;return void 0===this.counters[n]&&(this.counters[n]={counter:0,limit:t,valid:!0}),this.counters[n]}increment(e){const t=`${e.file}:${e.line_number}`;if(void 0===this.counters[t])return{counter:0,limit:0,valid:!1};const{counter:n,limit:r,valid:o}=this.counters[t];return this.counters[t]={counter:n+1,limit:r,valid:o},this.counters[t]}canSendPayload(e){const t=`${e.file}:${e.line_number}`;if(void 0===this.counters[t])return!0;const{counter:n,limit:r,valid:o}=this.counters[t];return o&&(nNr.create().send(...e);var Pr=class extends o.xI{initialize(){window.ray=jr}}},242:function(e,t,n){"use strict";n.r(t);var r=n(891),o=n(61);t.default=class extends r.xI{connect(){(0,o.b)("sweetalert")}}},921:function(e,t,n){"use strict";n.r(t);var r=n(891),o=n(61);t.default=class extends r.xI{connect(){(0,o.b)("toastr")}}},759:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return A}});var r=n(891),o=n(104),i=n(3);class s{success(e,t,n){this.flash("success",e,t,n)}error(e,t,n){this.flash("error",e,t,n)}info(e,t,n){this.flash("info",e,t,n)}warning(e,t,n){this.flash("warning",e,t,n)}flash(e,t,n,r){if("object"==typeof e?(e=(r=e).type,t=r.message,n=r.title):"object"==typeof t?(t=(r=t).message,n=r.title):"object"==typeof n&&(n=(r=n).title),void 0===t)throw new Error("message option is required");const o={type:e,message:t,title:n||e,options:r||{},metadata:{plugin:""}};this.renderOptions(r||{}),this.renderEnvelopes([o])}}const a=new class extends s{renderEnvelopes(e){e.forEach((e=>{const{message:t,title:n,type:r,options:o}=e,s=i[r](t,n,o);s&&s.parent().attr("data-turbo-cache","false")}))}renderOptions(e){i.options=Object.assign({timeOut:e.timeOut||5e3,progressBar:e.progressBar||!0},e)}};o.A.addPlugin("toastr",a);var l=n(113);class c{success(e,t,n){this.flash("success",e,t,n)}error(e,t,n){this.flash("error",e,t,n)}info(e,t,n){this.flash("info",e,t,n)}warning(e,t,n){this.flash("warning",e,t,n)}flash(e,t,n,r){if("object"==typeof e?(e=(r=e).type,t=r.message,n=r.title):"object"==typeof t?(t=(r=t).message,n=r.title):"object"==typeof n&&(n=(r=n).title),void 0===t)throw new Error("message option is required");const o={type:e,message:t,title:n||e,options:r||{},metadata:{plugin:""}};this.renderOptions(r||{}),this.renderEnvelopes([o])}}const u=new class extends c{renderEnvelopes(e){e.forEach((e=>{var t;const n=Object.assign({text:e.message,type:e.type},e.options),r=new l(n);r.show(),null===(t=r.layoutDom)||void 0===t||(t.dataset.turboCache="false")}))}renderOptions(e){l.overrideDefaults(Object.assign({timeout:e.timeout||5e3},e))}};o.A.addPlugin("noty",u);class d{success(e,t,n){this.flash("success",e,t,n)}error(e,t,n){this.flash("error",e,t,n)}info(e,t,n){this.flash("info",e,t,n)}warning(e,t,n){this.flash("warning",e,t,n)}flash(e,t,n,r){if("object"==typeof e?(e=(r=e).type,t=r.message,n=r.title):"object"==typeof t?(t=(r=t).message,n=r.title):"object"==typeof n&&(n=(r=n).title),void 0===t)throw new Error("message option is required");const o={type:e,message:t,title:n||e,options:r||{},metadata:{plugin:""}};this.renderOptions(r||{}),this.renderEnvelopes([o])}}var h,p=function(){return p=Object.assign||function(e){for(var t,n=1,r=arguments.length;n{var t;const n=Object.assign(Object.assign({},e),e.options);null===(t=this.notyf)||void 0===t||t.open(n)})),this.notyf.view.container.dataset.turboCache="false",this.notyf.view.a11yContainer.dataset.turboCache="false"}renderOptions(e){const t=Object.assign({duration:e.duration||5e3},e);t.types=t.types||[],t.types.push({type:"info",className:"notyf__toast--info",background:"#5784E5",icon:{className:"notyf__icon--info",tagName:"i"}}),t.types.push({type:"warning",className:"notyf__toast--warning",background:"#E3A008",icon:{className:"notyf__icon--warning",tagName:"i"}}),this.notyf=this.notyf||new w(t)}};o.A.addPlugin("notyf",b);var x=n(325);function C(e,t,n,r){return new(n||(n=Promise))((function(o,i){function s(e){try{l(r.next(e))}catch(e){i(e)}}function a(e){try{l(r.throw(e))}catch(e){i(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}l((r=r.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class E{success(e,t,n){this.flash("success",e,t,n)}error(e,t,n){this.flash("error",e,t,n)}info(e,t,n){this.flash("info",e,t,n)}warning(e,t,n){this.flash("warning",e,t,n)}flash(e,t,n,r){if("object"==typeof e?(e=(r=e).type,t=r.message,n=r.title):"object"==typeof t?(t=(r=t).message,n=r.title):"object"==typeof n&&(n=(r=n).title),void 0===t)throw new Error("message option is required");const o={type:e,message:t,title:n||e,options:r||{},metadata:{plugin:""}};this.renderOptions(r||{}),this.renderEnvelopes([o])}}const O=new class extends E{renderEnvelopes(e){return C(this,void 0,void 0,(function*(){for(const t of e)yield this.renderEnvelope(t)}))}renderOptions(e){this.sweetalert=this.sweetalert||x.mixin(Object.assign({timer:e.timer||5e3,timerProgressBar:e.timerProgressBar||!0},e)),document.addEventListener("turbo:before-cache",(()=>{var e;x.isVisible()&&(null===(e=x.getPopup())||void 0===e||e.style.setProperty("animation-duration","0ms"),x.close())}))}renderEnvelope(e){return C(this,void 0,void 0,(function*(){var t;let{options:n}=e;n=Object.assign(Object.assign({},n),{icon:(null==n?void 0:n.icon)||e.type,text:(null==n?void 0:n.text)||e.message}),yield null===(t=this.sweetalert)||void 0===t?void 0:t.fire(n).then((t=>{window.dispatchEvent(new CustomEvent("flasher:sweetalert:promise",{detail:{promise:t,envelope:e}}))}))}))}};o.A.addPlugin("sweetalert",O),window.flasher=o.A;var A=class extends r.xI{connect(){this.initializeCodeBlocks()}initializeCodeBlocks(){document.querySelectorAll("pre > code").forEach((e=>{e.textContent.trim().startsWith("#/")&&this.addTryItButtonToCodeBlock(e)}))}addTryItButtonToCodeBlock(e){const t=document.createElement("button");t.className="tryit text-indigo-500",t.type="button",t.ariaLabel=t.title="Try it!",t.innerHTML='',e.parentElement.classList.add("tryable"),e.parentElement.append(t),t.addEventListener("click",(()=>this.handleTryItButtonClick(t,e.textContent.trim())))}handleTryItButtonClick(e,t){e.innerHTML='';const n=this.defineThemes(),r=t.split("\n")[0].trim();try{"#/ flasher darkMode"===r?this.toggleDarkMode(r):r in n?this.applyTheme(r,n):Array.isArray(window.messages[r])?window.messages[r].forEach(this.flash.bind(this)):this.flash(window.messages[r])}catch(e){console.error(e)}finally{setTimeout((()=>e.innerHTML=''),500)}}toggleDarkMode(e){document.documentElement.classList.add("dark"),this.flash(window.messages[e]),setTimeout((()=>document.documentElement.classList.remove("dark")),5e3)}applyTheme(e,t){n(941)(`./${t[e]}`).then((()=>{window.messages[e].forEach(this.flash.bind(this))}))}defineThemes(){return{"#/ noty theme sunset":"sunset.css","#/ noty theme relax":"relax.css","#/ noty theme light":"light.css","#/ noty theme metroui":"metroui.css"}}flash(e){let{handler:t,type:n,message:r,title:i,options:s}=e;const a=o.A.use(t);a&&a.flash(n,r,i,s)}}},499:function(e){"use strict";e.exports=({onlyFirst:e=!1}={})=>{const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}},61:function(e,t,n){"use strict";n.d(t,{b:function(){return i}});var r=n(104);function o(e){0!==e.length&&setTimeout((()=>{e[0](),o(e.slice(1))}),1500)}function i(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=r.A.use(e);n.info("Welcome back","Info",t),["sweetalert"].includes(e)||o([()=>n.error("Oops! Something went wrong!","Error",t),()=>n.warning("Are you sure you want to proceed ?","Warning",t),()=>n.success("Data has been saved successfully!","Success",t)])}},263:function(e,t,n){var r,o,i;!function(s,a){"use strict";o=[n(343)],void 0===(i="function"==typeof(r=function(e){var t=/(^|@)\S+:\d+/,n=/^\s*at .*(\S+:\d+|\(native\))/m,r=/^(eval@)?(\[native code])?$/;return{parse:function(e){if(void 0!==e.stacktrace||void 0!==e["opera#sourceloc"])return this.parseOpera(e);if(e.stack&&e.stack.match(n))return this.parseV8OrIE(e);if(e.stack)return this.parseFFOrSafari(e);throw new Error("Cannot parse given Error object")},extractLocation:function(e){if(-1===e.indexOf(":"))return[e];var t=/(.+?)(?::(\d+))?(?::(\d+))?$/.exec(e.replace(/[()]/g,""));return[t[1],t[2]||void 0,t[3]||void 0]},parseV8OrIE:function(t){return t.stack.split("\n").filter((function(e){return!!e.match(n)}),this).map((function(t){t.indexOf("(eval ")>-1&&(t=t.replace(/eval code/g,"eval").replace(/(\(eval at [^()]*)|(,.*$)/g,""));var n=t.replace(/^\s+/,"").replace(/\(eval code/g,"(").replace(/^.*?\s+/,""),r=n.match(/ (\(.+\)$)/);n=r?n.replace(r[0],""):n;var o=this.extractLocation(r?r[1]:n),i=r&&n||void 0,s=["eval",""].indexOf(o[0])>-1?void 0:o[0];return new e({functionName:i,fileName:s,lineNumber:o[1],columnNumber:o[2],source:t})}),this)},parseFFOrSafari:function(t){return t.stack.split("\n").filter((function(e){return!e.match(r)}),this).map((function(t){if(t.indexOf(" > eval")>-1&&(t=t.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1")),-1===t.indexOf("@")&&-1===t.indexOf(":"))return new e({functionName:t});var n=/((.*".+"[^@]*)?[^@]*)(?:@)/,r=t.match(n),o=r&&r[1]?r[1]:void 0,i=this.extractLocation(t.replace(n,""));return new e({functionName:o,fileName:i[0],lineNumber:i[1],columnNumber:i[2],source:t})}),this)},parseOpera:function(e){return!e.stacktrace||e.message.indexOf("\n")>-1&&e.message.split("\n").length>e.stacktrace.split("\n").length?this.parseOpera9(e):e.stack?this.parseOpera11(e):this.parseOpera10(e)},parseOpera9:function(t){for(var n=/Line (\d+).*script (?:in )?(\S+)/i,r=t.message.split("\n"),o=[],i=2,s=r.length;i/,"$2").replace(/\([^)]*\)/g,"")||void 0;i.match(/\(([^)]*)\)/)&&(n=i.replace(/^[^(]+\(([^)]*)\)$/,"$1"));var a=void 0===n||"[arguments not available]"===n?void 0:n.split(",");return new e({functionName:s,args:a,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:t})}),this)}}})?r.apply(t,o):r)||(e.exports=i)}()},941:function(e,t,n){var r={"./bootstrap-v3.css":[455,455],"./bootstrap-v4.css":[792,411],"./light.css":[641,641],"./metroui.css":[779,160],"./mint.css":[265,265],"./nest.css":[371,371],"./relax.css":[735,735],"./semanticui.css":[243,243],"./sunset.css":[107,107]};function o(e){if(!n.o(r,e))return Promise.resolve().then((function(){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}));var t=r[e],o=t[0];return n.e(t[1]).then((function(){return n(o)}))}o.keys=function(){return Object.keys(r)},o.id=941,e.exports=o},887:function(e,t,n){var r,o,i;!function(s,a){"use strict";o=[n(343)],r=function(e){return{backtrace:function(t){var n=[],r=10;"object"==typeof t&&"number"==typeof t.maxStackSize&&(r=t.maxStackSize);for(var o=arguments.callee;o&&n.length=0&&e>>=5)>0&&(t|=32),n+=r.encode(t)}while(o>0);return n},t.decode=function(e,t,n){var o,i,s,a,l=e.length,c=0,u=0;do{if(t>=l)throw new Error("Expected more digits in base 64 VLQ value.");if(-1===(i=r.decode(e.charCodeAt(t++))))throw new Error("Invalid base64 digit: "+e.charAt(t-1));o=!!(32&i),c+=(i&=31)<>1,1&~s?a:-a),n.rest=t}},900:function(e,t){var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");t.encode=function(e){if(0<=e&&e0?r-l>1?n(l,r,o,i,s,a):a==t.LEAST_UPPER_BOUND?r1?n(e,l,o,i,s,a):a==t.LEAST_UPPER_BOUND?l:e<0?-1:e}t.GREATEST_LOWER_BOUND=1,t.LEAST_UPPER_BOUND=2,t.search=function(e,r,o,i){if(0===r.length)return-1;var s=n(-1,r.length,e,r,o,i||t.GREATEST_LOWER_BOUND);if(s<0)return-1;for(;s-1>=0&&0===o(r[s],r[s-1],!0);)--s;return s}},238:function(e,t,n){var r=n(216);function o(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}o.prototype.unsortedForEach=function(e,t){this._array.forEach(e,t)},o.prototype.add=function(e){var t,n,o,i,s,a;t=this._last,n=e,o=t.generatedLine,i=n.generatedLine,s=t.generatedColumn,a=n.generatedColumn,i>o||i==o&&a>=s||r.compareByGeneratedPositionsInflated(t,n)<=0?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},o.prototype.toArray=function(){return this._sorted||(this._array.sort(r.compareByGeneratedPositionsInflated),this._sorted=!0),this._array},t.P=o},737:function(e,t){function n(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function r(e,t,o,i){if(o=0){var a=this._originalMappings[s];if(void 0===e.column)for(var l=a.originalLine;a&&a.originalLine===l;)i.push({line:r.getArg(a,"generatedLine",null),column:r.getArg(a,"generatedColumn",null),lastColumn:r.getArg(a,"lastGeneratedColumn",null)}),a=this._originalMappings[++s];else for(var c=a.originalColumn;a&&a.originalLine===t&&a.originalColumn==c;)i.push({line:r.getArg(a,"generatedLine",null),column:r.getArg(a,"generatedColumn",null),lastColumn:r.getArg(a,"lastGeneratedColumn",null)}),a=this._originalMappings[++s]}return i},t.SourceMapConsumer=l,c.prototype=Object.create(l.prototype),c.prototype.consumer=l,c.fromSourceMap=function(e){var t=Object.create(c.prototype),n=t._names=i.fromArray(e._names.toArray(),!0),o=t._sources=i.fromArray(e._sources.toArray(),!0);t.sourceRoot=e._sourceRoot,t.sourcesContent=e._generateSourcesContent(t._sources.toArray(),t.sourceRoot),t.file=e._file;for(var s=e._mappings.toArray().slice(),l=t.__generatedMappings=[],d=t.__originalMappings=[],h=0,p=s.length;h1&&(n.source=m+i[1],m+=i[1],n.originalLine=p+i[2],p=n.originalLine,n.originalLine+=1,n.originalColumn=f+i[3],f=n.originalColumn,i.length>4&&(n.name=g+i[4],g+=i[4])),C.push(n),"number"==typeof n.originalLine&&x.push(n)}a(C,r.compareByGeneratedPositionsDeflated),this.__generatedMappings=C,a(x,r.compareByOriginalPositions),this.__originalMappings=x},c.prototype._findMapping=function(e,t,n,r,i,s){if(e[n]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[n]);if(e[r]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[r]);return o.search(e,t,i,s)},c.prototype.computeColumnSpans=function(){for(var e=0;e=0){var o=this._generatedMappings[n];if(o.generatedLine===t.generatedLine){var i=r.getArg(o,"source",null);null!==i&&(i=this._sources.at(i),null!=this.sourceRoot&&(i=r.join(this.sourceRoot,i)));var s=r.getArg(o,"name",null);return null!==s&&(s=this._names.at(s)),{source:i,line:r.getArg(o,"originalLine",null),column:r.getArg(o,"originalColumn",null),name:s}}}return{source:null,line:null,column:null,name:null}},c.prototype.hasContentsOfAllSources=function(){return!!this.sourcesContent&&(this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return null==e})))},c.prototype.sourceContentFor=function(e,t){if(!this.sourcesContent)return null;if(null!=this.sourceRoot&&(e=r.relative(this.sourceRoot,e)),this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];var n;if(null!=this.sourceRoot&&(n=r.urlParse(this.sourceRoot))){var o=e.replace(/^file:\/\//,"");if("file"==n.scheme&&this._sources.has(o))return this.sourcesContent[this._sources.indexOf(o)];if((!n.path||"/"==n.path)&&this._sources.has("/"+e))return this.sourcesContent[this._sources.indexOf("/"+e)]}if(t)return null;throw new Error('"'+e+'" is not in the SourceMap.')},c.prototype.generatedPositionFor=function(e){var t=r.getArg(e,"source");if(null!=this.sourceRoot&&(t=r.relative(this.sourceRoot,t)),!this._sources.has(t))return{line:null,column:null,lastColumn:null};var n={source:t=this._sources.indexOf(t),originalLine:r.getArg(e,"line"),originalColumn:r.getArg(e,"column")},o=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",r.compareByOriginalPositions,r.getArg(e,"bias",l.GREATEST_LOWER_BOUND));if(o>=0){var i=this._originalMappings[o];if(i.source===n.source)return{line:r.getArg(i,"generatedLine",null),column:r.getArg(i,"generatedColumn",null),lastColumn:r.getArg(i,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},d.prototype=Object.create(l.prototype),d.prototype.constructor=l,d.prototype._version=3,Object.defineProperty(d.prototype,"sources",{get:function(){for(var e=[],t=0;t0&&e.column>=0)||t||n||r)&&!(e&&"line"in e&&"column"in e&&t&&"line"in t&&"column"in t&&e.line>0&&e.column>=0&&t.line>0&&t.column>=0&&n))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:t,name:r}))},a.prototype._serializeMappings=function(){for(var e,t,n,i,s=0,a=1,l=0,c=0,u=0,d=0,h="",p=this._mappings.toArray(),f=0,m=p.length;f0){if(!o.compareByGeneratedPositionsInflated(t,p[f-1]))continue;e+=","}e+=r.encode(t.generatedColumn-s),s=t.generatedColumn,null!=t.source&&(i=this._sources.indexOf(t.source),e+=r.encode(i-d),d=i,e+=r.encode(t.originalLine-1-c),c=t.originalLine-1,e+=r.encode(t.originalColumn-l),l=t.originalColumn,null!=t.name&&(n=this._names.indexOf(t.name),e+=r.encode(n-u),u=n)),h+=e}return h},a.prototype._generateSourcesContent=function(e,t){return e.map((function(e){if(!this._sourcesContents)return null;null!=t&&(e=o.relative(t,e));var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)},a.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},a.prototype.toString=function(){return JSON.stringify(this.toJSON())},t.SourceMapGenerator=a},171:function(e,t,n){var r=n(945).SourceMapGenerator,o=n(216),i=/(\r?\n)/,s="$$$isSourceNode$$$";function a(e,t,n,r,o){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==t?null:t,this.source=null==n?null:n,this.name=null==o?null:o,this[s]=!0,null!=r&&this.add(r)}a.fromStringWithSourceMap=function(e,t,n){var r=new a,s=e.split(i),l=function(){return s.shift()+(s.shift()||"")},c=1,u=0,d=null;return t.eachMapping((function(e){if(null!==d){if(!(c0&&(d&&h(d,l()),r.add(s.join(""))),t.sources.forEach((function(e){var i=t.sourceContentFor(e);null!=i&&(null!=n&&(e=o.join(n,e)),r.setSourceContent(e,i))})),r;function h(e,t){if(null===e||void 0===e.source)r.add(t);else{var i=n?o.join(n,e.source):e.source;r.add(new a(e.originalLine,e.originalColumn,i,t,e.name))}}},a.prototype.add=function(e){if(Array.isArray(e))e.forEach((function(e){this.add(e)}),this);else{if(!e[s]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);e&&this.children.push(e)}return this},a.prototype.prepend=function(e){if(Array.isArray(e))for(var t=e.length-1;t>=0;t--)this.prepend(e[t]);else{if(!e[s]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},a.prototype.walk=function(e){for(var t,n=0,r=this.children.length;n0){for(t=[],n=0;n=0;u--)"."===(s=l[u])?l.splice(u,1):".."===s?c++:c>0&&(""===s?(l.splice(u+1,c),c=0):(l.splice(u,2),c--));return""===(n=l.join("/"))&&(n=a?"/":"."),r?(r.path=n,i(r)):n}t.urlParse=o,t.urlGenerate=i,t.normalize=s,t.join=function(e,t){""===e&&(e="."),""===t&&(t=".");var n=o(t),a=o(e);if(a&&(e=a.path||"/"),n&&!n.scheme)return a&&(n.scheme=a.scheme),i(n);if(n||t.match(r))return t;if(a&&!a.host&&!a.path)return a.host=t,i(a);var l="/"===t.charAt(0)?t:s(e.replace(/\/+$/,"")+"/"+t);return a?(a.path=l,i(a)):l},t.isAbsolute=function(e){return"/"===e.charAt(0)||!!e.match(n)},t.relative=function(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");for(var n=0;0!==t.indexOf(e+"/");){var r=e.lastIndexOf("/");if(r<0)return t;if((e=e.slice(0,r)).match(/^([^\/]+:\/)?\/*$/))return t;++n}return Array(n+1).join("../")+t.substr(e.length+1)};var a=!("__proto__"in Object.create(null));function l(e){return e}function c(e){if(!e)return!1;var t=e.length;if(t<9)return!1;if(95!==e.charCodeAt(t-1)||95!==e.charCodeAt(t-2)||111!==e.charCodeAt(t-3)||116!==e.charCodeAt(t-4)||111!==e.charCodeAt(t-5)||114!==e.charCodeAt(t-6)||112!==e.charCodeAt(t-7)||95!==e.charCodeAt(t-8)||95!==e.charCodeAt(t-9))return!1;for(var n=t-10;n>=0;n--)if(36!==e.charCodeAt(n))return!1;return!0}function u(e,t){return e===t?0:e>t?1:-1}t.toSetString=a?l:function(e){return c(e)?"$"+e:e},t.fromSetString=a?l:function(e){return c(e)?e.slice(1):e},t.compareByOriginalPositions=function(e,t,n){var r=e.source-t.source;return 0!==r||0!==(r=e.originalLine-t.originalLine)||0!==(r=e.originalColumn-t.originalColumn)||n||0!==(r=e.generatedColumn-t.generatedColumn)||0!==(r=e.generatedLine-t.generatedLine)?r:e.name-t.name},t.compareByGeneratedPositionsDeflated=function(e,t,n){var r=e.generatedLine-t.generatedLine;return 0!==r||0!==(r=e.generatedColumn-t.generatedColumn)||n||0!==(r=e.source-t.source)||0!==(r=e.originalLine-t.originalLine)||0!==(r=e.originalColumn-t.originalColumn)?r:e.name-t.name},t.compareByGeneratedPositionsInflated=function(e,t){var n=e.generatedLine-t.generatedLine;return 0!==n||0!==(n=e.generatedColumn-t.generatedColumn)||0!==(n=u(e.source,t.source))||0!==(n=e.originalLine-t.originalLine)||0!==(n=e.originalColumn-t.originalColumn)?n:u(e.name,t.name)}},65:function(e,t,n){t.SourceMapGenerator=n(945).SourceMapGenerator,t.SourceMapConsumer=n(606).SourceMapConsumer,t.SourceNode=n(171).SourceNode},885:function(e,t,n){var r,o,i;!function(s,a){"use strict";o=[n(65),n(343)],void 0===(i="function"==typeof(r=function(e,t){function n(e){return new Promise((function(t,n){var r=new XMLHttpRequest;r.open("get",e),r.onerror=n,r.onreadystatechange=function(){4===r.readyState&&(r.status>=200&&r.status<300||"file://"===e.substr(0,7)&&r.responseText?t(r.responseText):n(new Error("HTTP status: "+r.status+" retrieving "+e)))},r.send()}))}function r(e){if("undefined"!=typeof window&&window.atob)return window.atob(e);throw new Error("You must supply a polyfill for window.atob in this environment")}function o(e){if("undefined"!=typeof JSON&&JSON.parse)return JSON.parse(e);throw new Error("You must supply a polyfill for JSON.parse in this environment")}function i(e,t){for(var n=[/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*function\b/,/function\s+([^('"`]*?)\s*\(([^)]*)\)/,/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*(?:eval|new Function)\b/,/\b(?!(?:if|for|switch|while|with|catch)\b)(?:(?:static)\s+)?(\S+)\s*\(.*?\)\s*\{/,/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*\(.*?\)\s*=>/],r=e.split("\n"),o="",i=Math.min(t,20),s=0;s=0&&(a=a.substr(0,l)),a){o=a+o;for(var c=n.length,u=0;u=200&&s.status<400?o(s.responseText):i(new Error("POST to "+t+" failed with status: "+s.status)))},s.open("post",t),s.setRequestHeader("Content-Type","application/json"),r&&"object"==typeof r.headers){var a=r.headers;for(var l in a)Object.prototype.hasOwnProperty.call(a,l)&&s.setRequestHeader(l,a[l])}var c={stack:e};null!=n&&(c.message=n),s.send(JSON.stringify(c))}))}}},void 0===(i="function"==typeof r?r.apply(t,o):r)||(e.exports=i)}()},99:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const o=r(n(308));function i(e){if(!e.options.indentation&&!e.options.lineSeparator)return;let t;for(e.content+=e.options.lineSeparator,t=0;t0&&(!n&&t.content.length>0&&i(t),s(t,e))}(e.content,t,n);else if("Element"===e.type)!function(e,t,n){t.path.push(e.name),!n&&t.content.length>0&&i(t);if(s(t,"<"+e.name),l(t,e.attributes),null===e.children||t.options.forceSelfClosingEmptyTag&&0===e.children.length){const e=t.options.whiteSpaceAtEndOfSelfclosingTag?" />":"/>";s(t,e)}else if(0===e.children.length)s(t,">");else{const r=e.children;s(t,">"),t.level++;let o="preserve"===e.attributes["xml:space"],l=!1;if(!o&&t.options.ignoredPaths&&(l=function(e,t){const n="/"+e.join("/"),r=e[e.length-1];return t.includes(r)||t.includes(n)}(t.path,t.options.ignoredPaths),o=l),!o&&t.options.collapseContent){let e=!1,t=!1,i=!1;r.forEach((function(o,s){"Text"===o.type?(o.content.includes("\n")?(t=!0,o.content=o.content.trim()):0!==s&&s!==r.length-1||n||0===o.content.trim().length&&(o.content=""),o.content.trim().length>0&&(e=!0)):"CDATA"===o.type?e=!0:i=!0})),!e||i&&t||(o=!0)}r.forEach((function(e){a(e,t,n||o)})),t.level--,n||o||i(t),l&&function(e){let t;for(e.content=e.content.replace(/ +$/,""),t=0;t")}t.path.pop()}(e,t,n);else{if("ProcessingInstruction"!==e.type)throw new Error("Unknown node type: "+e.type);c(e,t)}}function l(e,t){Object.keys(t).forEach((function(n){const r=t[n].replace(/"/g,""");s(e," "+n+'="'+r+'"')}))}function c(e,t){t.content.length>0&&i(t),s(t,"")}function u(e,t={}){t.indentation="indentation"in t?t.indentation:" ",t.collapseContent=!0===t.collapseContent,t.lineSeparator="lineSeparator"in t?t.lineSeparator:"\r\n",t.whiteSpaceAtEndOfSelfclosingTag=!0===t.whiteSpaceAtEndOfSelfclosingTag,t.throwOnFailure=!1!==t.throwOnFailure;try{const n=(0,o.default)(e,{filter:t.filter,strictMode:t.strictMode}),r={content:"",level:0,options:t,path:[]};return n.declaration&&c(n.declaration,r),n.children.forEach((function(e){a(e,r,!1)})),t.lineSeparator?r.content.replace(/\r\n/g,"\n").replace(/\n/g,t.lineSeparator):r.content}catch(n){if(t.throwOnFailure)throw n;return e}}u.minify=(e,t={})=>u(e,Object.assign(Object.assign({},t),{indentation:"",lineSeparator:""})),e.exports=u,t.default=u},308:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ParsingError=void 0;class n extends Error{constructor(e,t){super(e),this.cause=t}}let r;function o(){return a(!1)||function(){const e=u(/^([^<]+)/);if(e){const t={type:"Text",content:e[1]};return{excluded:!1===r.options.filter(t),node:t}}}()||l()||function(){if(r.xml.startsWith("");if(e>-1){const t=e+3,n={type:"CDATA",content:r.xml.substring(0,t)};return r.xml=r.xml.slice(t),{excluded:!1===r.options.filter(n),node:n}}}}()}function i(){return u(/\s*/),a(!0)||l()||function(){const e=u(/^]*>/)||u(/^]*>/)||u(/^/)||u(/^/);if(e){const t={type:"DocumentType",content:e[0]};return{excluded:!1===r.options.filter(t),node:t}}}()||s(!1)}function s(e){const t=u(e?/^<\?(xml)\s*/:/^<\?([\w-:.]+)\s*/);if(!t)return;const n={name:t[1],type:"ProcessingInstruction",attributes:{}};for(;!d()&&!h("?>");){const e=c();if(!e)return;n.attributes[e.name]=e.value}return u(/\?>/),{excluded:!e&&!1===r.options.filter(n),node:n}}function a(e){const t=u(/^<([^?!\s]+)\s*/);if(!t)return;const i={type:"Element",name:t[1],attributes:{},children:[]},s=!e&&!1===r.options.filter(i);for(;!(d()||h(">")||h("?>")||h("/>"));){const e=c();if(!e)return;i.attributes[e.name]=e.value}if(u(/^\s*\/>/))return i.children=null,{excluded:s,node:i};u(/\??>/);let a=o();for(;a;)a.excluded||i.children.push(a.node),a=o();if(r.options.strictMode){const e=``;if(!r.xml.startsWith(e))throw new n("Failed to parse XML",`Closing tag not matching "${e}"`);r.xml=r.xml.slice(e.length)}else u(/^<\/\s*[\w-:.\u00C0-\u00FF]+>/);return{excluded:s,node:i}}function l(){const e=u(/^/);if(e){const t={type:"Comment",content:e[0]};return{excluded:!1===r.options.filter(t),node:t}}}function c(){const e=u(/([^=]+)\s*=\s*("[^"]*"|'[^']*'|[^>\s]+)\s*/);if(e)return{name:e[1].trim(),value:(t=e[2].trim(),t.replace(/^['"]|['"]$/g,""))};var t}function u(e){const t=r.xml.match(e);if(t)return r.xml=r.xml.slice(t[0].length),t}function d(){return 0===r.xml.length}function h(e){return 0===r.xml.indexOf(e)}function p(e,t={}){e=e.trim();const o=t.filter||(()=>!0);return r={xml:e,options:Object.assign(Object.assign({},t),{filter:o,strictMode:!0===t.strictMode})},function(){const e=s(!0),t=[];let o,a=i();for(;a;){if("Element"===a.node.type){if(o)throw new Error("Found multiple root nodes");o=a.node}a.excluded||t.push(a.node),a=i()}if(!o)throw new n("Failed to parse XML","Root Element not found");if(0!==r.xml.length)throw new n("Failed to parse XML","Not Well-Formed XML");return{declaration:e?e.node:null,root:o,children:t}}()}t.ParsingError=n,e.exports=p,t.default=p},616:function(e,t){var n;!function(t,n){"use strict";"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,(function(r,o){"use strict";var i=[],s=Object.getPrototypeOf,a=i.slice,l=i.flat?function(e){return i.flat.call(e)}:function(e){return i.concat.apply([],e)},c=i.push,u=i.indexOf,d={},h=d.toString,p=d.hasOwnProperty,f=p.toString,m=f.call(Object),g={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},w=r.document,b={type:!0,src:!0,nonce:!0,noModule:!0};function x(e,t,n){var r,o,i=(n=n||w).createElement("script");if(i.text=e,t)for(r in b)(o=t[r]||t.getAttribute&&t.getAttribute(r))&&i.setAttribute(r,o);n.head.appendChild(i).parentNode.removeChild(i)}function C(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?d[h.call(e)]||"object":typeof e}var E="3.7.1",O=/HTML$/i,A=function(e,t){return new A.fn.init(e,t)};function k(e){var t=!!e&&"length"in e&&e.length,n=C(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function S(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}A.fn=A.prototype={jquery:E,constructor:A,length:0,toArray:function(){return a.call(this)},get:function(e){return null==e?a.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=A.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return A.each(this,e)},map:function(e){return this.pushStack(A.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(A.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(A.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+j+")"+j+"*"),H=new RegExp(j+"|>"),$=new RegExp(B),U=new RegExp("^"+L+"$"),z={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+B),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+j+"*(even|odd|(([+-]|)(\\d*)n|)"+j+"*(?:([+-]|)"+j+"*(\\d+)|))"+j+"*\\)|)","i"),bool:new RegExp("^(?:"+k+")$","i"),needsContext:new RegExp("^"+j+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+j+"*((?:-\\d)?\\d*)"+j+"*\\)|)(?=[^-]|$)","i")},V=/^(?:input|select|textarea|button)$/i,W=/^h\d$/i,K=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/[+~]/,J=new RegExp("\\\\[\\da-fA-F]{1,6}"+j+"?|\\\\([^\\r\\n\\f])","g"),X=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},Y=function(){le()},Z=he((function(e){return!0===e.disabled&&S(e,"fieldset")}),{dir:"parentNode",next:"legend"});try{m.apply(i=a.call(D.childNodes),D.childNodes),i[D.childNodes.length].nodeType}catch(e){m={apply:function(e,t){R.apply(e,a.call(t))},call:function(e){R.apply(e,a.call(arguments,1))}}}function Q(e,t,n,r){var o,i,s,a,c,u,p,f=t&&t.ownerDocument,y=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==y&&9!==y&&11!==y)return n;if(!r&&(le(t),t=t||l,d)){if(11!==y&&(c=K.exec(e)))if(o=c[1]){if(9===y){if(!(s=t.getElementById(o)))return n;if(s.id===o)return m.call(n,s),n}else if(f&&(s=f.getElementById(o))&&Q.contains(t,s)&&s.id===o)return m.call(n,s),n}else{if(c[2])return m.apply(n,t.getElementsByTagName(e)),n;if((o=c[3])&&t.getElementsByClassName)return m.apply(n,t.getElementsByClassName(o)),n}if(!(E[e+" "]||h&&h.test(e))){if(p=e,f=t,1===y&&(H.test(e)||I.test(e))){for((f=G.test(e)&&ae(t.parentNode)||t)==t&&g.scope||((a=t.getAttribute("id"))?a=A.escapeSelector(a):t.setAttribute("id",a=v)),i=(u=ue(e)).length;i--;)u[i]=(a?"#"+a:":scope")+" "+de(u[i]);p=u.join(",")}try{return m.apply(n,f.querySelectorAll(p)),n}catch(t){E(e,!0)}finally{a===v&&t.removeAttribute("id")}}}return ye(e.replace(P,"$1"),t,n,r)}function ee(){var e=[];return function n(r,o){return e.push(r+" ")>t.cacheLength&&delete n[e.shift()],n[r+" "]=o}}function te(e){return e[v]=!0,e}function ne(e){var t=l.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function re(e){return function(t){return S(t,"input")&&t.type===e}}function oe(e){return function(t){return(S(t,"input")||S(t,"button"))&&t.type===e}}function ie(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&Z(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function se(e){return te((function(t){return t=+t,te((function(n,r){for(var o,i=e([],n.length,t),s=i.length;s--;)n[o=i[s]]&&(n[o]=!(r[o]=n[o]))}))}))}function ae(e){return e&&void 0!==e.getElementsByTagName&&e}function le(e){var n,r=e?e.ownerDocument||e:D;return r!=l&&9===r.nodeType&&r.documentElement?(c=(l=r).documentElement,d=!A.isXMLDoc(l),f=c.matches||c.webkitMatchesSelector||c.msMatchesSelector,c.msMatchesSelector&&D!=l&&(n=l.defaultView)&&n.top!==n&&n.addEventListener("unload",Y),g.getById=ne((function(e){return c.appendChild(e).id=A.expando,!l.getElementsByName||!l.getElementsByName(A.expando).length})),g.disconnectedMatch=ne((function(e){return f.call(e,"*")})),g.scope=ne((function(){return l.querySelectorAll(":scope")})),g.cssHas=ne((function(){try{return l.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}})),g.getById?(t.filter.ID=function(e){var t=e.replace(J,X);return function(e){return e.getAttribute("id")===t}},t.find.ID=function(e,t){if(void 0!==t.getElementById&&d){var n=t.getElementById(e);return n?[n]:[]}}):(t.filter.ID=function(e){var t=e.replace(J,X);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},t.find.ID=function(e,t){if(void 0!==t.getElementById&&d){var n,r,o,i=t.getElementById(e);if(i){if((n=i.getAttributeNode("id"))&&n.value===e)return[i];for(o=t.getElementsByName(e),r=0;i=o[r++];)if((n=i.getAttributeNode("id"))&&n.value===e)return[i]}return[]}}),t.find.TAG=function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},t.find.CLASS=function(e,t){if(void 0!==t.getElementsByClassName&&d)return t.getElementsByClassName(e)},h=[],ne((function(e){var t;c.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+j+"*(?:value|"+k+")"),e.querySelectorAll("[id~="+v+"-]").length||h.push("~="),e.querySelectorAll("a#"+v+"+*").length||h.push(".#.+[+~]"),e.querySelectorAll(":checked").length||h.push(":checked"),(t=l.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),c.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&h.push(":enabled",":disabled"),(t=l.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||h.push("\\["+j+"*name"+j+"*="+j+"*(?:''|\"\")")})),g.cssHas||h.push(":has"),h=h.length&&new RegExp(h.join("|")),O=function(e,t){if(e===t)return s=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!g.sortDetached&&t.compareDocumentPosition(e)===n?e===l||e.ownerDocument==D&&Q.contains(D,e)?-1:t===l||t.ownerDocument==D&&Q.contains(D,t)?1:o?u.call(o,e)-u.call(o,t):0:4&n?-1:1)},l):l}for(e in Q.matches=function(e,t){return Q(e,null,null,t)},Q.matchesSelector=function(e,t){if(le(e),d&&!E[t+" "]&&(!h||!h.test(t)))try{var n=f.call(e,t);if(n||g.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){E(t,!0)}return Q(t,l,null,[e]).length>0},Q.contains=function(e,t){return(e.ownerDocument||e)!=l&&le(e),A.contains(e,t)},Q.attr=function(e,n){(e.ownerDocument||e)!=l&&le(e);var r=t.attrHandle[n.toLowerCase()],o=r&&p.call(t.attrHandle,n.toLowerCase())?r(e,n,!d):void 0;return void 0!==o?o:e.getAttribute(n)},Q.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},A.uniqueSort=function(e){var t,n=[],r=0,i=0;if(s=!g.sortStable,o=!g.sortStable&&a.call(e,0),_.call(e,O),s){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)N.call(e,n[r],1)}return o=null,e},A.fn.uniqueSort=function(){return this.pushStack(A.uniqueSort(a.apply(this)))},t=A.expr={cacheLength:50,createPseudo:te,match:z,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(J,X),e[3]=(e[3]||e[4]||e[5]||"").replace(J,X),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||Q.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&Q.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return z.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&$.test(n)&&(t=ue(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(J,X).toLowerCase();return"*"===e?function(){return!0}:function(e){return S(e,t)}},CLASS:function(e){var t=b[e+" "];return t||(t=new RegExp("(^|"+j+")"+e+"("+j+"|$)"))&&b(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,n){return function(r){var o=Q.attr(r,e);return null==o?"!="===t:!t||(o+="","="===t?o===n:"!="===t?o!==n:"^="===t?n&&0===o.indexOf(n):"*="===t?n&&o.indexOf(n)>-1:"$="===t?n&&o.slice(-n.length)===n:"~="===t?(" "+o.replace(F," ")+" ").indexOf(n)>-1:"|="===t&&(o===n||o.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,o){var i="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===o?function(e){return!!e.parentNode}:function(t,n,l){var c,u,d,h,p,f=i!==s?"nextSibling":"previousSibling",m=t.parentNode,g=a&&t.nodeName.toLowerCase(),w=!l&&!a,b=!1;if(m){if(i){for(;f;){for(d=t;d=d[f];)if(a?S(d,g):1===d.nodeType)return!1;p=f="only"===e&&!p&&"nextSibling"}return!0}if(p=[s?m.firstChild:m.lastChild],s&&w){for(b=(h=(c=(u=m[v]||(m[v]={}))[e]||[])[0]===y&&c[1])&&c[2],d=h&&m.childNodes[h];d=++h&&d&&d[f]||(b=h=0)||p.pop();)if(1===d.nodeType&&++b&&d===t){u[e]=[y,h,b];break}}else if(w&&(b=h=(c=(u=t[v]||(t[v]={}))[e]||[])[0]===y&&c[1]),!1===b)for(;(d=++h&&d&&d[f]||(b=h=0)||p.pop())&&(!(a?S(d,g):1===d.nodeType)||!++b||(w&&((u=d[v]||(d[v]={}))[e]=[y,b]),d!==t)););return(b-=o)===r||b%r==0&&b/r>=0}}},PSEUDO:function(e,n){var r,o=t.pseudos[e]||t.setFilters[e.toLowerCase()]||Q.error("unsupported pseudo: "+e);return o[v]?o(n):o.length>1?(r=[e,e,"",n],t.setFilters.hasOwnProperty(e.toLowerCase())?te((function(e,t){for(var r,i=o(e,n),s=i.length;s--;)e[r=u.call(e,i[s])]=!(t[r]=i[s])})):function(e){return o(e,0,r)}):o}},pseudos:{not:te((function(e){var t=[],n=[],r=ve(e.replace(P,"$1"));return r[v]?te((function(e,t,n,o){for(var i,s=r(e,null,o,[]),a=e.length;a--;)(i=s[a])&&(e[a]=!(t[a]=i))})):function(e,o,i){return t[0]=e,r(t,null,i,n),t[0]=null,!n.pop()}})),has:te((function(e){return function(t){return Q(e,t).length>0}})),contains:te((function(e){return e=e.replace(J,X),function(t){return(t.textContent||A.text(t)).indexOf(e)>-1}})),lang:te((function(e){return U.test(e||"")||Q.error("unsupported lang: "+e),e=e.replace(J,X).toLowerCase(),function(t){var n;do{if(n=d?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(e){var t=r.location&&r.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===c},focus:function(e){return e===function(){try{return l.activeElement}catch(e){}}()&&l.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:ie(!1),disabled:ie(!0),checked:function(e){return S(e,"input")&&!!e.checked||S(e,"option")&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!t.pseudos.empty(e)},header:function(e){return W.test(e.nodeName)},input:function(e){return V.test(e.nodeName)},button:function(e){return S(e,"input")&&"button"===e.type||S(e,"button")},text:function(e){var t;return S(e,"input")&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:se((function(){return[0]})),last:se((function(e,t){return[t-1]})),eq:se((function(e,t,n){return[n<0?n+t:n]})),even:se((function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e})),gt:se((function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var o=e.length;o--;)if(!e[o](t,n,r))return!1;return!0}:e[0]}function fe(e,t,n,r,o){for(var i,s=[],a=0,l=e.length,c=null!=t;a-1&&(i[c]=!(s[c]=h))}}else p=fe(p===s?p.splice(v,p.length):p),o?o(null,s,p,l):m.apply(s,p)}))}function ge(e){for(var r,o,i,s=e.length,a=t.relative[e[0].type],l=a||t.relative[" "],c=a?1:0,d=he((function(e){return e===r}),l,!0),h=he((function(e){return u.call(r,e)>-1}),l,!0),p=[function(e,t,o){var i=!a&&(o||t!=n)||((r=t).nodeType?d(e,t,o):h(e,t,o));return r=null,i}];c1&&pe(p),c>1&&de(e.slice(0,c-1).concat({value:" "===e[c-2].type?"*":""})).replace(P,"$1"),o,c0,i=e.length>0,s=function(s,a,c,u,h){var p,f,g,v=0,w="0",b=s&&[],x=[],C=n,E=s||i&&t.find.TAG("*",h),O=y+=null==C?1:Math.random()||.1,k=E.length;for(h&&(n=a==l||a||h);w!==k&&null!=(p=E[w]);w++){if(i&&p){for(f=0,a||p.ownerDocument==l||(le(p),c=!d);g=e[f++];)if(g(p,a||l,c)){m.call(u,p);break}h&&(y=O)}o&&((p=!g&&p)&&v--,s&&b.push(p))}if(v+=w,o&&w!==v){for(f=0;g=r[f++];)g(b,x,a,c);if(s){if(v>0)for(;w--;)b[w]||x[w]||(x[w]=T.call(u));x=fe(x)}m.apply(u,x),h&&!s&&x.length>0&&v+r.length>1&&A.uniqueSort(u)}return h&&(y=O,n=C),b};return o?te(s):s}(s,i)),a.selector=e}return a}function ye(e,n,r,o){var i,s,a,l,c,u="function"==typeof e&&e,h=!o&&ue(e=u.selector||e);if(r=r||[],1===h.length){if((s=h[0]=h[0].slice(0)).length>2&&"ID"===(a=s[0]).type&&9===n.nodeType&&d&&t.relative[s[1].type]){if(!(n=(t.find.ID(a.matches[0].replace(J,X),n)||[])[0]))return r;u&&(n=n.parentNode),e=e.slice(s.shift().value.length)}for(i=z.needsContext.test(e)?0:s.length;i--&&(a=s[i],!t.relative[l=a.type]);)if((c=t.find[l])&&(o=c(a.matches[0].replace(J,X),G.test(s[0].type)&&ae(n.parentNode)||n))){if(s.splice(i,1),!(e=o.length&&de(s)))return m.apply(r,o),r;break}}return(u||ve(e,h))(o,n,!d,r,!n||G.test(e)&&ae(n.parentNode)||n),r}ce.prototype=t.filters=t.pseudos,t.setFilters=new ce,g.sortStable=v.split("").sort(O).join("")===v,le(),g.sortDetached=ne((function(e){return 1&e.compareDocumentPosition(l.createElement("fieldset"))})),A.find=Q,A.expr[":"]=A.expr.pseudos,A.unique=A.uniqueSort,Q.compile=ve,Q.select=ye,Q.setDocument=le,Q.tokenize=ue,Q.escape=A.escapeSelector,Q.getText=A.text,Q.isXML=A.isXMLDoc,Q.selectors=A.expr,Q.support=A.support,Q.uniqueSort=A.uniqueSort}();var B=function(e,t,n){for(var r=[],o=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(o&&A(e).is(n))break;r.push(e)}return r},F=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},q=A.expr.match.needsContext,I=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function H(e,t,n){return v(t)?A.grep(e,(function(e,r){return!!t.call(e,r,e)!==n})):t.nodeType?A.grep(e,(function(e){return e===t!==n})):"string"!=typeof t?A.grep(e,(function(e){return u.call(t,e)>-1!==n})):A.filter(t,e,n)}A.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?A.find.matchesSelector(r,e)?[r]:[]:A.find.matches(e,A.grep(t,(function(e){return 1===e.nodeType})))},A.fn.extend({find:function(e){var t,n,r=this.length,o=this;if("string"!=typeof e)return this.pushStack(A(e).filter((function(){for(t=0;t1?A.uniqueSort(n):n},filter:function(e){return this.pushStack(H(this,e||[],!1))},not:function(e){return this.pushStack(H(this,e||[],!0))},is:function(e){return!!H(this,"string"==typeof e&&q.test(e)?A(e):e||[],!1).length}});var $,U=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(A.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||$,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:U.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof A?t[0]:t,A.merge(this,A.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),I.test(r[1])&&A.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(o=w.getElementById(r[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(A):A.makeArray(e,this)}).prototype=A.fn,$=A(w);var z=/^(?:parents|prev(?:Until|All))/,V={children:!0,contents:!0,next:!0,prev:!0};function W(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}A.fn.extend({has:function(e){var t=A(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&A.find.matchesSelector(n,e))){i.push(n);break}return this.pushStack(i.length>1?A.uniqueSort(i):i)},index:function(e){return e?"string"==typeof e?u.call(A(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(A.uniqueSort(A.merge(this.get(),A(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),A.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return B(e,"parentNode")},parentsUntil:function(e,t,n){return B(e,"parentNode",n)},next:function(e){return W(e,"nextSibling")},prev:function(e){return W(e,"previousSibling")},nextAll:function(e){return B(e,"nextSibling")},prevAll:function(e){return B(e,"previousSibling")},nextUntil:function(e,t,n){return B(e,"nextSibling",n)},prevUntil:function(e,t,n){return B(e,"previousSibling",n)},siblings:function(e){return F((e.parentNode||{}).firstChild,e)},children:function(e){return F(e.firstChild)},contents:function(e){return null!=e.contentDocument&&s(e.contentDocument)?e.contentDocument:(S(e,"template")&&(e=e.content||e),A.merge([],e.childNodes))}},(function(e,t){A.fn[e]=function(n,r){var o=A.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(o=A.filter(r,o)),this.length>1&&(V[e]||A.uniqueSort(o),z.test(e)&&o.reverse()),this.pushStack(o)}}));var K=/[^\x20\t\r\n\f]+/g;function G(e){return e}function J(e){throw e}function X(e,t,n,r){var o;try{e&&v(o=e.promise)?o.call(e).done(t).fail(n):e&&v(o=e.then)?o.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}A.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return A.each(e.match(K)||[],(function(e,n){t[n]=!0})),t}(e):A.extend({},e);var t,n,r,o,i=[],s=[],a=-1,l=function(){for(o=o||e.once,r=t=!0;s.length;a=-1)for(n=s.shift();++a-1;)i.splice(n,1),n<=a&&a--})),this},has:function(e){return e?A.inArray(e,i)>-1:i.length>0},empty:function(){return i&&(i=[]),this},disable:function(){return o=s=[],i=n="",this},disabled:function(){return!i},lock:function(){return o=s=[],n||t||(i=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=[e,(n=n||[]).slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},A.extend({Deferred:function(e){var t=[["notify","progress",A.Callbacks("memory"),A.Callbacks("memory"),2],["resolve","done",A.Callbacks("once memory"),A.Callbacks("once memory"),0,"resolved"],["reject","fail",A.Callbacks("once memory"),A.Callbacks("once memory"),1,"rejected"]],n="pending",o={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},catch:function(e){return o.then(null,e)},pipe:function(){var e=arguments;return A.Deferred((function(n){A.each(t,(function(t,r){var o=v(e[r[4]])&&e[r[4]];i[r[1]]((function(){var e=o&&o.apply(this,arguments);e&&v(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,o?[e]:arguments)}))})),e=null})).promise()},then:function(e,n,o){var i=0;function s(e,t,n,o){return function(){var a=this,l=arguments,c=function(){var r,c;if(!(e=i&&(n!==J&&(a=void 0,l=[r]),t.rejectWith(a,l))}};e?u():(A.Deferred.getErrorHook?u.error=A.Deferred.getErrorHook():A.Deferred.getStackHook&&(u.error=A.Deferred.getStackHook()),r.setTimeout(u))}}return A.Deferred((function(r){t[0][3].add(s(0,r,v(o)?o:G,r.notifyWith)),t[1][3].add(s(0,r,v(e)?e:G)),t[2][3].add(s(0,r,v(n)?n:J))})).promise()},promise:function(e){return null!=e?A.extend(e,o):o}},i={};return A.each(t,(function(e,r){var s=r[2],a=r[5];o[r[1]]=s.add,a&&s.add((function(){n=a}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),s.add(r[3].fire),i[r[0]]=function(){return i[r[0]+"With"](this===i?void 0:this,arguments),this},i[r[0]+"With"]=s.fireWith})),o.promise(i),e&&e.call(i,i),i},when:function(e){var t=arguments.length,n=t,r=Array(n),o=a.call(arguments),i=A.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?a.call(arguments):n,--t||i.resolveWith(r,o)}};if(t<=1&&(X(e,i.done(s(n)).resolve,i.reject,!t),"pending"===i.state()||v(o[n]&&o[n].then)))return i.then();for(;n--;)X(o[n],s(n),i.reject);return i.promise()}});var Y=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;A.Deferred.exceptionHook=function(e,t){r.console&&r.console.warn&&e&&Y.test(e.name)&&r.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},A.readyException=function(e){r.setTimeout((function(){throw e}))};var Z=A.Deferred();function Q(){w.removeEventListener("DOMContentLoaded",Q),r.removeEventListener("load",Q),A.ready()}A.fn.ready=function(e){return Z.then(e).catch((function(e){A.readyException(e)})),this},A.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--A.readyWait:A.isReady)||(A.isReady=!0,!0!==e&&--A.readyWait>0||Z.resolveWith(w,[A]))}}),A.ready.then=Z.then,"complete"===w.readyState||"loading"!==w.readyState&&!w.documentElement.doScroll?r.setTimeout(A.ready):(w.addEventListener("DOMContentLoaded",Q),r.addEventListener("load",Q));var ee=function(e,t,n,r,o,i,s){var a=0,l=e.length,c=null==n;if("object"===C(n))for(a in o=!0,n)ee(e,t,a,n[a],!0,i,s);else if(void 0!==r&&(o=!0,v(r)||(s=!0),c&&(s?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(A(e),n)})),t))for(;a1,null,!0)},removeData:function(e){return this.each((function(){le.remove(this,e)}))}}),A.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=ae.get(e,t),n&&(!r||Array.isArray(n)?r=ae.access(e,t,A.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=A.queue(e,t),r=n.length,o=n.shift(),i=A._queueHooks(e,t);"inprogress"===o&&(o=n.shift(),r--),o&&("fx"===t&&n.unshift("inprogress"),delete i.stop,o.call(e,(function(){A.dequeue(e,t)}),i)),!r&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return ae.get(e,n)||ae.access(e,n,{empty:A.Callbacks("once memory").add((function(){ae.remove(e,[t+"queue",n])}))})}}),A.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,Se=/^$|^module$|\/(?:java|ecma)script/i;Ee=w.createDocumentFragment().appendChild(w.createElement("div")),(Oe=w.createElement("input")).setAttribute("type","radio"),Oe.setAttribute("checked","checked"),Oe.setAttribute("name","t"),Ee.appendChild(Oe),g.checkClone=Ee.cloneNode(!0).cloneNode(!0).lastChild.checked,Ee.innerHTML="",g.noCloneChecked=!!Ee.cloneNode(!0).lastChild.defaultValue,Ee.innerHTML="",g.option=!!Ee.lastChild;var Te={thead:[1,"
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function _e(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?A.merge([e],n):n}function Ne(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Pe(e,t,n,r,o){for(var i,s,a,l,c,u,d=t.createDocumentFragment(),h=[],p=0,f=e.length;p-1)o&&o.push(i);else if(c=ge(i),s=_e(d.appendChild(i),"script"),c&&Ne(s),n)for(u=0;i=s[u++];)Se.test(i.type||"")&&n.push(i);return d}var Le=/^([^.]*)(?:\.(.+)|)/;function Me(){return!0}function De(){return!1}function Re(e,t,n,r,o,i){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(r=r||n,n=void 0),t)Re(e,a,n,r,t[a],i);return e}if(null==r&&null==o?(o=n,r=n=void 0):null==o&&("string"==typeof n?(o=r,r=void 0):(o=r,r=n,n=void 0)),!1===o)o=De;else if(!o)return e;return 1===i&&(s=o,o=function(e){return A().off(e),s.apply(this,arguments)},o.guid=s.guid||(s.guid=A.guid++)),e.each((function(){A.event.add(this,t,o,r,n)}))}function Be(e,t,n){n?(ae.set(e,t,!1),A.event.add(e,t,{namespace:!1,handler:function(e){var n,r=ae.get(this,t);if(1&e.isTrigger&&this[t]){if(r)(A.event.special[t]||{}).delegateType&&e.stopPropagation();else if(r=a.call(arguments),ae.set(this,t,r),this[t](),n=ae.get(this,t),ae.set(this,t,!1),r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n}else r&&(ae.set(this,t,A.event.trigger(r[0],r.slice(1),this)),e.stopPropagation(),e.isImmediatePropagationStopped=Me)}})):void 0===ae.get(e,t)&&A.event.add(e,t,Me)}A.event={global:{},add:function(e,t,n,r,o){var i,s,a,l,c,u,d,h,p,f,m,g=ae.get(e);if(ie(e))for(n.handler&&(n=(i=n).handler,o=i.selector),o&&A.find.matchesSelector(me,o),n.guid||(n.guid=A.guid++),(l=g.events)||(l=g.events=Object.create(null)),(s=g.handle)||(s=g.handle=function(t){return void 0!==A&&A.event.triggered!==t.type?A.event.dispatch.apply(e,arguments):void 0}),c=(t=(t||"").match(K)||[""]).length;c--;)p=m=(a=Le.exec(t[c])||[])[1],f=(a[2]||"").split(".").sort(),p&&(d=A.event.special[p]||{},p=(o?d.delegateType:d.bindType)||p,d=A.event.special[p]||{},u=A.extend({type:p,origType:m,data:r,handler:n,guid:n.guid,selector:o,needsContext:o&&A.expr.match.needsContext.test(o),namespace:f.join(".")},i),(h=l[p])||((h=l[p]=[]).delegateCount=0,d.setup&&!1!==d.setup.call(e,r,f,s)||e.addEventListener&&e.addEventListener(p,s)),d.add&&(d.add.call(e,u),u.handler.guid||(u.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,u):h.push(u),A.event.global[p]=!0)},remove:function(e,t,n,r,o){var i,s,a,l,c,u,d,h,p,f,m,g=ae.hasData(e)&&ae.get(e);if(g&&(l=g.events)){for(c=(t=(t||"").match(K)||[""]).length;c--;)if(p=m=(a=Le.exec(t[c])||[])[1],f=(a[2]||"").split(".").sort(),p){for(d=A.event.special[p]||{},h=l[p=(r?d.delegateType:d.bindType)||p]||[],a=a[2]&&new RegExp("(^|\\.)"+f.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=i=h.length;i--;)u=h[i],!o&&m!==u.origType||n&&n.guid!==u.guid||a&&!a.test(u.namespace)||r&&r!==u.selector&&("**"!==r||!u.selector)||(h.splice(i,1),u.selector&&h.delegateCount--,d.remove&&d.remove.call(e,u));s&&!h.length&&(d.teardown&&!1!==d.teardown.call(e,f,g.handle)||A.removeEvent(e,p,g.handle),delete l[p])}else for(p in l)A.event.remove(e,p+t[c],n,r,!0);A.isEmptyObject(l)&&ae.remove(e,"handle events")}},dispatch:function(e){var t,n,r,o,i,s,a=new Array(arguments.length),l=A.event.fix(e),c=(ae.get(this,"events")||Object.create(null))[l.type]||[],u=A.event.special[l.type]||{};for(a[0]=l,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||!0!==c.disabled)){for(i=[],s={},n=0;n-1:A.find(o,this,null,[c]).length),s[o]&&i.push(r);i.length&&a.push({elem:c,handlers:i})}return c=this,l\s*$/g;function He(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&A(e).children("tbody")[0]||e}function $e(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Ue(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function ze(e,t){var n,r,o,i,s,a;if(1===t.nodeType){if(ae.hasData(e)&&(a=ae.get(e).events))for(o in ae.remove(t,"handle events"),a)for(n=0,r=a[o].length;n1&&"string"==typeof f&&!g.checkClone&&qe.test(f))return e.each((function(o){var i=e.eq(o);m&&(t[0]=f.call(this,o,i.html())),We(i,t,n,r)}));if(h&&(i=(o=Pe(t,e[0].ownerDocument,!1,e,r)).firstChild,1===o.childNodes.length&&(o=i),i||r)){for(a=(s=A.map(_e(o,"script"),$e)).length;d0&&Ne(s,!l&&_e(e,"script")),a},cleanData:function(e){for(var t,n,r,o=A.event.special,i=0;void 0!==(n=e[i]);i++)if(ie(n)){if(t=n[ae.expando]){if(t.events)for(r in t.events)o[r]?A.event.remove(n,r):A.removeEvent(n,r,t.handle);n[ae.expando]=void 0}n[le.expando]&&(n[le.expando]=void 0)}}}),A.fn.extend({detach:function(e){return Ke(this,e,!0)},remove:function(e){return Ke(this,e)},text:function(e){return ee(this,(function(e){return void 0===e?A.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return We(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||He(this,e).appendChild(e)}))},prepend:function(){return We(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=He(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return We(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return We(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(A.cleanData(_e(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return A.clone(this,e,t)}))},html:function(e){return ee(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Fe.test(e)&&!Te[(ke.exec(e)||["",""])[1].toLowerCase()]){e=A.htmlPrefilter(e);try{for(;n=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-i-l-a-.5))||0),l+c}function ut(e,t,n){var r=Xe(e),o=(!g.boxSizingReliable()||n)&&"border-box"===A.css(e,"boxSizing",!1,r),i=o,s=Qe(e,t,r),a="offset"+t[0].toUpperCase()+t.slice(1);if(Ge.test(s)){if(!n)return s;s="auto"}return(!g.boxSizingReliable()&&o||!g.reliableTrDimensions()&&S(e,"tr")||"auto"===s||!parseFloat(s)&&"inline"===A.css(e,"display",!1,r))&&e.getClientRects().length&&(o="border-box"===A.css(e,"boxSizing",!1,r),(i=a in e)&&(s=e[a])),(s=parseFloat(s)||0)+ct(e,t,n||(o?"border":"content"),i,r,s)+"px"}function dt(e,t,n,r,o){return new dt.prototype.init(e,t,n,r,o)}A.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Qe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,i,s,a=oe(t),l=Je.test(t),c=e.style;if(l||(t=ot(a)),s=A.cssHooks[t]||A.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(o=s.get(e,!1,r))?o:c[t];"string"===(i=typeof n)&&(o=pe.exec(n))&&o[1]&&(n=we(e,t,o),i="number"),null!=n&&n==n&&("number"!==i||l||(n+=o&&o[3]||(A.cssNumber[a]?"":"px")),g.clearCloneStyle||""!==n||0!==t.indexOf("background")||(c[t]="inherit"),s&&"set"in s&&void 0===(n=s.set(e,n,r))||(l?c.setProperty(t,n):c[t]=n))}},css:function(e,t,n,r){var o,i,s,a=oe(t);return Je.test(t)||(t=ot(a)),(s=A.cssHooks[t]||A.cssHooks[a])&&"get"in s&&(o=s.get(e,!0,n)),void 0===o&&(o=Qe(e,t,r)),"normal"===o&&t in at&&(o=at[t]),""===n||n?(i=parseFloat(o),!0===n||isFinite(i)?i||0:o):o}}),A.each(["height","width"],(function(e,t){A.cssHooks[t]={get:function(e,n,r){if(n)return!it.test(A.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?ut(e,t,r):Ye(e,st,(function(){return ut(e,t,r)}))},set:function(e,n,r){var o,i=Xe(e),s=!g.scrollboxSize()&&"absolute"===i.position,a=(s||r)&&"border-box"===A.css(e,"boxSizing",!1,i),l=r?ct(e,t,r,a,i):0;return a&&s&&(l-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(i[t])-ct(e,t,"border",!1,i)-.5)),l&&(o=pe.exec(n))&&"px"!==(o[3]||"px")&&(e.style[t]=n,n=A.css(e,t)),lt(0,n,l)}}})),A.cssHooks.marginLeft=et(g.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(Qe(e,"marginLeft"))||e.getBoundingClientRect().left-Ye(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),A.each({margin:"",padding:"",border:"Width"},(function(e,t){A.cssHooks[e+t]={expand:function(n){for(var r=0,o={},i="string"==typeof n?n.split(" "):[n];r<4;r++)o[e+fe[r]+t]=i[r]||i[r-2]||i[0];return o}},"margin"!==e&&(A.cssHooks[e+t].set=lt)})),A.fn.extend({css:function(e,t){return ee(this,(function(e,t,n){var r,o,i={},s=0;if(Array.isArray(t)){for(r=Xe(e),o=t.length;s1)}}),A.Tween=dt,dt.prototype={constructor:dt,init:function(e,t,n,r,o,i){this.elem=e,this.prop=n,this.easing=o||A.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=i||(A.cssNumber[n]?"":"px")},cur:function(){var e=dt.propHooks[this.prop];return e&&e.get?e.get(this):dt.propHooks._default.get(this)},run:function(e){var t,n=dt.propHooks[this.prop];return this.options.duration?this.pos=t=A.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):dt.propHooks._default.set(this),this}},dt.prototype.init.prototype=dt.prototype,dt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=A.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){A.fx.step[e.prop]?A.fx.step[e.prop](e):1!==e.elem.nodeType||!A.cssHooks[e.prop]&&null==e.elem.style[ot(e.prop)]?e.elem[e.prop]=e.now:A.style(e.elem,e.prop,e.now+e.unit)}}},dt.propHooks.scrollTop=dt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},A.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},A.fx=dt.prototype.init,A.fx.step={};var ht,pt,ft=/^(?:toggle|show|hide)$/,mt=/queueHooks$/;function gt(){pt&&(!1===w.hidden&&r.requestAnimationFrame?r.requestAnimationFrame(gt):r.setTimeout(gt,A.fx.interval),A.fx.tick())}function vt(){return r.setTimeout((function(){ht=void 0})),ht=Date.now()}function yt(e,t){var n,r=0,o={height:e};for(t=t?1:0;r<4;r+=2-t)o["margin"+(n=fe[r])]=o["padding"+n]=e;return t&&(o.opacity=o.width=e),o}function wt(e,t,n){for(var r,o=(bt.tweeners[t]||[]).concat(bt.tweeners["*"]),i=0,s=o.length;i1)},removeAttr:function(e){return this.each((function(){A.removeAttr(this,e)}))}}),A.extend({attr:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return void 0===e.getAttribute?A.prop(e,t,n):(1===i&&A.isXMLDoc(e)||(o=A.attrHooks[t.toLowerCase()]||(A.expr.match.bool.test(t)?xt:void 0)),void 0!==n?null===n?void A.removeAttr(e,t):o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:(e.setAttribute(t,n+""),n):o&&"get"in o&&null!==(r=o.get(e,t))?r:null==(r=A.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!g.radioValue&&"radio"===t&&S(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,o=t&&t.match(K);if(o&&1===e.nodeType)for(;n=o[r++];)e.removeAttribute(n)}}),xt={set:function(e,t,n){return!1===t?A.removeAttr(e,n):e.setAttribute(n,n),n}},A.each(A.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=Ct[t]||A.find.attr;Ct[t]=function(e,t,r){var o,i,s=t.toLowerCase();return r||(i=Ct[s],Ct[s]=o,o=null!=n(e,t,r)?s:null,Ct[s]=i),o}}));var Et=/^(?:input|select|textarea|button)$/i,Ot=/^(?:a|area)$/i;function At(e){return(e.match(K)||[]).join(" ")}function kt(e){return e.getAttribute&&e.getAttribute("class")||""}function St(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(K)||[]}A.fn.extend({prop:function(e,t){return ee(this,A.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[A.propFix[e]||e]}))}}),A.extend({prop:function(e,t,n){var r,o,i=e.nodeType;if(3!==i&&8!==i&&2!==i)return 1===i&&A.isXMLDoc(e)||(t=A.propFix[t]||t,o=A.propHooks[t]),void 0!==n?o&&"set"in o&&void 0!==(r=o.set(e,n,t))?r:e[t]=n:o&&"get"in o&&null!==(r=o.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=A.find.attr(e,"tabindex");return t?parseInt(t,10):Et.test(e.nodeName)||Ot.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),g.optSelected||(A.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),A.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){A.propFix[this.toLowerCase()]=this})),A.fn.extend({addClass:function(e){var t,n,r,o,i,s;return v(e)?this.each((function(t){A(this).addClass(e.call(this,t,kt(this)))})):(t=St(e)).length?this.each((function(){if(r=kt(this),n=1===this.nodeType&&" "+At(r)+" "){for(i=0;i-1;)n=n.replace(" "+o+" "," ");s=At(n),r!==s&&this.setAttribute("class",s)}})):this:this.attr("class","")},toggleClass:function(e,t){var n,r,o,i,s=typeof e,a="string"===s||Array.isArray(e);return v(e)?this.each((function(n){A(this).toggleClass(e.call(this,n,kt(this),t),t)})):"boolean"==typeof t&&a?t?this.addClass(e):this.removeClass(e):(n=St(e),this.each((function(){if(a)for(i=A(this),o=0;o-1)return!0;return!1}});var Tt=/\r/g;A.fn.extend({val:function(e){var t,n,r,o=this[0];return arguments.length?(r=v(e),this.each((function(n){var o;1===this.nodeType&&(null==(o=r?e.call(this,n,A(this).val()):e)?o="":"number"==typeof o?o+="":Array.isArray(o)&&(o=A.map(o,(function(e){return null==e?"":e+""}))),(t=A.valHooks[this.type]||A.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,o,"value")||(this.value=o))}))):o?(t=A.valHooks[o.type]||A.valHooks[o.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(o,"value"))?n:"string"==typeof(n=o.value)?n.replace(Tt,""):null==n?"":n:void 0}}),A.extend({valHooks:{option:{get:function(e){var t=A.find.attr(e,"value");return null!=t?t:At(A.text(e))}},select:{get:function(e){var t,n,r,o=e.options,i=e.selectedIndex,s="select-one"===e.type,a=s?null:[],l=s?i+1:o.length;for(r=i<0?l:s?i:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),i}}}}),A.each(["radio","checkbox"],(function(){A.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=A.inArray(A(e).val(),t)>-1}},g.checkOn||(A.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}));var _t=r.location,Nt={guid:Date.now()},jt=/\?/;A.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new r.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||A.error("Invalid XML: "+(n?A.map(n.childNodes,(function(e){return e.textContent})).join("\n"):e)),t};var Pt=/^(?:focusinfocus|focusoutblur)$/,Lt=function(e){e.stopPropagation()};A.extend(A.event,{trigger:function(e,t,n,o){var i,s,a,l,c,u,d,h,f=[n||w],m=p.call(e,"type")?e.type:e,g=p.call(e,"namespace")?e.namespace.split("."):[];if(s=h=a=n=n||w,3!==n.nodeType&&8!==n.nodeType&&!Pt.test(m+A.event.triggered)&&(m.indexOf(".")>-1&&(g=m.split("."),m=g.shift(),g.sort()),c=m.indexOf(":")<0&&"on"+m,(e=e[A.expando]?e:new A.Event(m,"object"==typeof e&&e)).isTrigger=o?2:3,e.namespace=g.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:A.makeArray(t,[e]),d=A.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(n,t))){if(!o&&!d.noBubble&&!y(n)){for(l=d.delegateType||m,Pt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)f.push(s),a=s;a===(n.ownerDocument||w)&&f.push(a.defaultView||a.parentWindow||r)}for(i=0;(s=f[i++])&&!e.isPropagationStopped();)h=s,e.type=i>1?l:d.bindType||m,(u=(ae.get(s,"events")||Object.create(null))[e.type]&&ae.get(s,"handle"))&&u.apply(s,t),(u=c&&s[c])&&u.apply&&ie(s)&&(e.result=u.apply(s,t),!1===e.result&&e.preventDefault());return e.type=m,o||e.isDefaultPrevented()||d._default&&!1!==d._default.apply(f.pop(),t)||!ie(n)||c&&v(n[m])&&!y(n)&&((a=n[c])&&(n[c]=null),A.event.triggered=m,e.isPropagationStopped()&&h.addEventListener(m,Lt),n[m](),e.isPropagationStopped()&&h.removeEventListener(m,Lt),A.event.triggered=void 0,a&&(n[c]=a)),e.result}},simulate:function(e,t,n){var r=A.extend(new A.Event,n,{type:e,isSimulated:!0});A.event.trigger(r,null,t)}}),A.fn.extend({trigger:function(e,t){return this.each((function(){A.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return A.event.trigger(e,t,n,!0)}});var Mt=/\[\]$/,Dt=/\r?\n/g,Rt=/^(?:submit|button|image|reset|file)$/i,Bt=/^(?:input|select|textarea|keygen)/i;function Ft(e,t,n,r){var o;if(Array.isArray(t))A.each(t,(function(t,o){n||Mt.test(e)?r(e,o):Ft(e+"["+("object"==typeof o&&null!=o?t:"")+"]",o,n,r)}));else if(n||"object"!==C(t))r(e,t);else for(o in t)Ft(e+"["+o+"]",t[o],n,r)}A.param=function(e,t){var n,r=[],o=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!A.isPlainObject(e))A.each(e,(function(){o(this.name,this.value)}));else for(n in e)Ft(n,e[n],t,o);return r.join("&")},A.fn.extend({serialize:function(){return A.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=A.prop(this,"elements");return e?A.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!A(this).is(":disabled")&&Bt.test(this.nodeName)&&!Rt.test(e)&&(this.checked||!Ae.test(e))})).map((function(e,t){var n=A(this).val();return null==n?null:Array.isArray(n)?A.map(n,(function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}})):{name:t.name,value:n.replace(Dt,"\r\n")}})).get()}});var qt=/%20/g,It=/#.*$/,Ht=/([?&])_=[^&]*/,$t=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ut=/^(?:GET|HEAD)$/,zt=/^\/\//,Vt={},Wt={},Kt="*/".concat("*"),Gt=w.createElement("a");function Jt(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,o=0,i=t.toLowerCase().match(K)||[];if(v(n))for(;r=i[o++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Xt(e,t,n,r){var o={},i=e===Wt;function s(a){var l;return o[a]=!0,A.each(e[a]||[],(function(e,a){var c=a(t,n,r);return"string"!=typeof c||i||o[c]?i?!(l=c):void 0:(t.dataTypes.unshift(c),s(c),!1)})),l}return s(t.dataTypes[0])||!o["*"]&&s("*")}function Yt(e,t){var n,r,o=A.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((o[n]?e:r||(r={}))[n]=t[n]);return r&&A.extend(!0,e,r),e}Gt.href=_t.href,A.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:_t.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(_t.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":A.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Yt(Yt(e,A.ajaxSettings),t):Yt(A.ajaxSettings,e)},ajaxPrefilter:Jt(Vt),ajaxTransport:Jt(Wt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var n,o,i,s,a,l,c,u,d,h,p=A.ajaxSetup({},t),f=p.context||p,m=p.context&&(f.nodeType||f.jquery)?A(f):A.event,g=A.Deferred(),v=A.Callbacks("once memory"),y=p.statusCode||{},b={},x={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=$t.exec(i);)s[t[1].toLowerCase()+" "]=(s[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=s[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return c?i:null},setRequestHeader:function(e,t){return null==c&&(e=x[e.toLowerCase()]=x[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)y[t]=[y[t],e[t]];return this},abort:function(e){var t=e||C;return n&&n.abort(t),O(0,t),this}};if(g.promise(E),p.url=((e||p.url||_t.href)+"").replace(zt,_t.protocol+"//"),p.type=t.method||t.type||p.method||p.type,p.dataTypes=(p.dataType||"*").toLowerCase().match(K)||[""],null==p.crossDomain){l=w.createElement("a");try{l.href=p.url,l.href=l.href,p.crossDomain=Gt.protocol+"//"+Gt.host!=l.protocol+"//"+l.host}catch(e){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=A.param(p.data,p.traditional)),Xt(Vt,p,t,E),c)return E;for(d in(u=A.event&&p.global)&&0==A.active++&&A.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Ut.test(p.type),o=p.url.replace(It,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(qt,"+")):(h=p.url.slice(o.length),p.data&&(p.processData||"string"==typeof p.data)&&(o+=(jt.test(o)?"&":"?")+p.data,delete p.data),!1===p.cache&&(o=o.replace(Ht,"$1"),h=(jt.test(o)?"&":"?")+"_="+Nt.guid+++h),p.url=o+h),p.ifModified&&(A.lastModified[o]&&E.setRequestHeader("If-Modified-Since",A.lastModified[o]),A.etag[o]&&E.setRequestHeader("If-None-Match",A.etag[o])),(p.data&&p.hasContent&&!1!==p.contentType||t.contentType)&&E.setRequestHeader("Content-Type",p.contentType),E.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Kt+"; q=0.01":""):p.accepts["*"]),p.headers)E.setRequestHeader(d,p.headers[d]);if(p.beforeSend&&(!1===p.beforeSend.call(f,E,p)||c))return E.abort();if(C="abort",v.add(p.complete),E.done(p.success),E.fail(p.error),n=Xt(Wt,p,t,E)){if(E.readyState=1,u&&m.trigger("ajaxSend",[E,p]),c)return E;p.async&&p.timeout>0&&(a=r.setTimeout((function(){E.abort("timeout")}),p.timeout));try{c=!1,n.send(b,O)}catch(e){if(c)throw e;O(-1,e)}}else O(-1,"No Transport");function O(e,t,s,l){var d,h,w,b,x,C=t;c||(c=!0,a&&r.clearTimeout(a),n=void 0,i=l||"",E.readyState=e>0?4:0,d=e>=200&&e<300||304===e,s&&(b=function(e,t,n){for(var r,o,i,s,a=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(o in a)if(a[o]&&a[o].test(r)){l.unshift(o);break}if(l[0]in n)i=l[0];else{for(o in n){if(!l[0]||e.converters[o+" "+l[0]]){i=o;break}s||(s=o)}i=i||s}if(i)return i!==l[0]&&l.unshift(i),n[i]}(p,E,s)),!d&&A.inArray("script",p.dataTypes)>-1&&A.inArray("json",p.dataTypes)<0&&(p.converters["text script"]=function(){}),b=function(e,t,n,r){var o,i,s,a,l,c={},u=e.dataTypes.slice();if(u[1])for(s in e.converters)c[s.toLowerCase()]=e.converters[s];for(i=u.shift();i;)if(e.responseFields[i]&&(n[e.responseFields[i]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=i,i=u.shift())if("*"===i)i=l;else if("*"!==l&&l!==i){if(!(s=c[l+" "+i]||c["* "+i]))for(o in c)if((a=o.split(" "))[1]===i&&(s=c[l+" "+a[0]]||c["* "+a[0]])){!0===s?s=c[o]:!0!==c[o]&&(i=a[0],u.unshift(a[1]));break}if(!0!==s)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:"parsererror",error:s?e:"No conversion from "+l+" to "+i}}}return{state:"success",data:t}}(p,b,E,d),d?(p.ifModified&&((x=E.getResponseHeader("Last-Modified"))&&(A.lastModified[o]=x),(x=E.getResponseHeader("etag"))&&(A.etag[o]=x)),204===e||"HEAD"===p.type?C="nocontent":304===e?C="notmodified":(C=b.state,h=b.data,d=!(w=b.error))):(w=C,!e&&C||(C="error",e<0&&(e=0))),E.status=e,E.statusText=(t||C)+"",d?g.resolveWith(f,[h,C,E]):g.rejectWith(f,[E,C,w]),E.statusCode(y),y=void 0,u&&m.trigger(d?"ajaxSuccess":"ajaxError",[E,p,d?h:w]),v.fireWith(f,[E,C]),u&&(m.trigger("ajaxComplete",[E,p]),--A.active||A.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return A.get(e,t,n,"json")},getScript:function(e,t){return A.get(e,void 0,t,"script")}}),A.each(["get","post"],(function(e,t){A[t]=function(e,n,r,o){return v(n)&&(o=o||r,r=n,n=void 0),A.ajax(A.extend({url:e,type:t,dataType:o,data:n,success:r},A.isPlainObject(e)&&e))}})),A.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),A._evalUrl=function(e,t,n){return A.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){A.globalEval(e,t,n)}})},A.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=A(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return v(e)?this.each((function(t){A(this).wrapInner(e.call(this,t))})):this.each((function(){var t=A(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=v(e);return this.each((function(n){A(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){A(this).replaceWith(this.childNodes)})),this}}),A.expr.pseudos.hidden=function(e){return!A.expr.pseudos.visible(e)},A.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},A.ajaxSettings.xhr=function(){try{return new r.XMLHttpRequest}catch(e){}};var Zt={0:200,1223:204},Qt=A.ajaxSettings.xhr();g.cors=!!Qt&&"withCredentials"in Qt,g.ajax=Qt=!!Qt,A.ajaxTransport((function(e){var t,n;if(g.cors||Qt&&!e.crossDomain)return{send:function(o,i){var s,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(s in e.xhrFields)a[s]=e.xhrFields[s];for(s in e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest"),o)a.setRequestHeader(s,o[s]);t=function(e){return function(){t&&(t=n=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?i(0,"error"):i(a.status,a.statusText):i(Zt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=t(),n=a.onerror=a.ontimeout=t("error"),void 0!==a.onabort?a.onabort=n:a.onreadystatechange=function(){4===a.readyState&&r.setTimeout((function(){t&&n()}))},t=t("abort");try{a.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),A.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),A.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return A.globalEval(e),e}}}),A.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),A.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,o){t=A(" +``` + +All you have to do now, is to trigger you notification from anywhere in your application. + +```php +success('User created.'); + + return Redirect::route('users'); + } +} +``` diff --git a/docs/pages/installation.md b/docs/pages/installation.md new file mode 100644 index 00000000..592c4d16 --- /dev/null +++ b/docs/pages/installation.md @@ -0,0 +1,389 @@ +--- +permalink: /installation/ +redirect_from: /docs/installation/ +title: Installation +description: Install only the specific components you need for your project with PHPFlasher, a modular PHP library for displaying flash notification messages. Simply include the library in your composer.json file and run the composer install command to get started. +--- + +{% PHPFlasher %} is modular and consists of multiple libraries, +allowing users to install and use only the specific components they need for their project. + +## Installation + +{% PHPFlasher %} can be installed using composer : + +** Laravel**: +```shell +composer require php-flasher/flasher-laravel +``` + +
+ +** Symfony**: +```shell +composer require php-flasher/flasher-symfony +``` + +--- + +{% PHPFlasher %} includes a default notification style , but users can also install additional adapters to customize the appearance of notifications within their projects such as : + +* **[Toastr](/library/toastr/)** +* **[Noty](/library/noty/)** +* **[Notyf](/library/notyf/)** +* **[Sweet Alert](/library/sweetalert/)** + +--- + +## General Usage + +To display a notification message, you can either use the `flash()` helper method or obtain an instance of `flasher` from the service container. +Then, before returning a view or redirecting, call the `success()` method and pass in the desired message to be displayed. + +{% assign id = '#/ PHPFlasher' %} +{% assign type = 'success' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +class BookController +{ + public function saveBook() + { + // ... + + flash('{{ message }}'); + + flash()->success('{{ site.data.messages["success"] | sample }}'); + + // ... redirect or render the view + } + + /** + * if you prefer to use dependency injection + */ + public function register(FlasherInterface $flasher) + { + // ... + + $flasher->success('{{ site.data.messages["success"] | sample }}'); + + // ... redirect or render the view + } +} +``` + +
+ +It's important to choose a message that is clear and concise, and that accurately reflects the outcome of the operation.
+In this case, `"Book has been created successfully!"` is already a good message, +but you may want to tailor it to fit the specific context and language of your application. + +> Using this package is actually pretty easy. Adding notifications to your application actually require only one line of code. + +{% assign id = '#/ usage success' %} +{% assign type = 'success' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ usage error' %} +{% assign type = 'error' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ usage warning' %} +{% assign type = 'warning' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ usage info' %} +{% assign type = 'info' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->{{ type }}('{{ message }}'); +``` + +--- + +These four methods (`success`, `error`, `warning`, `info`) are simply convenience shortcuts for the `flash` method, +allowing you to specify the `type` and `message` in a single method call rather than having to pass both as separate arguments to the `flash` method. + +```php +flash()->flash(string $type, string $message, string $title = null, array $options = []) +``` + +{% assign id = '#/ usage flash' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +flash()->flash('{{ type }}', '{{ message }}'); +``` + +| param | description | +|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `$type` | Notification type : success, error, warning, info ....etc | +| `$message` | The body of the message you want to deliver to your user. This may contain HTML. If you add links, be sure to add the appropriate classes for the framework you are using. | +| `$title` | The notification title, Can also include HTML | +| `$options` | Custom options for javascript libraries (toastr, noty, notyf ...etc) | | + + +--- + +## Modifiers + +

options

+ +You can specify **custom options** for the flash messages when using a JavaScript library like `toastr`, `noty`, or `notyf`.

+The `options()` method allows you to set multiple options at once by passing an array of `key-value` pairs, +while the `option()` method allows you to set a single option by specifying its name and value as separate arguments.

+The optional `$merge` argument for the `options()` method can be used to specify whether the new options should be merged with any existing options, +or whether they should overwrite them. + +```php +flash()->options(array $options, bool $merge = true); +``` + +> Refer to the documentation for your chosen JavaScript library to see which options are available and how they should be formatted. + +{% assign id = '#/ usage options' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeout": 3000, "position": "top-center"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->options([ + 'timeout' => 3000, // 3 seconds + 'position' => 'top-center', + ]) + ->{{ type }}('{{ message }}'); +``` + +| param | description | +|------------|--------------------------------------------------------------------------------------| +| `$options` | Custom options to be passed to the javascript libraries (toastr, noty, notyf ...etc) | +| `$merge` | Merge options if you call the options method multiple times | + +--- + +

option

+ +Set a single option by specifying its name and value as separate arguments. + +```php +flash()->option(string $option, mixed $value); +``` + +{% assign id = '#/ usage option' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeout": 3000, "position": "top-center"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->option('position', 'top-center') + ->option('timeout', 3000) + ->{{ type }}('{{ message }}'); +``` + +| param | description | +|-----------|--------------| +| `$option` | Option key | +| `$value` | Option value | + +--- + +

priority

+ +Sets the priority of a flash message, the highest priority will be displayed first. + +```php +flash()->priority(int $priority); +``` + +{% assign id = '#/ usage priority' %} +{% assign successMessage = site.data.messages['success'] | sample | prepend: 'Priority 3 → ' %} +{% assign errorMessage = site.data.messages['error'] | sample | prepend: 'Priority 1 → ' %} +{% assign warningMessage = site.data.messages['warning'] | sample | prepend: 'Priority 4 → ' %} +{% assign infoMessage = site.data.messages['info'] | sample | prepend: 'Priority 2 → ' %} + + + +```php +{{ id }} + +flash() + ->priority(3) + ->success('{{ successMessage }}'); + +flash() + ->priority(1) + ->error('{{ errorMessage }}'); + +flash() + ->priority(4) + ->warning('{{ warningMessage }}'); + +flash() + ->priority(2) + ->info('{{ infoMessage }}'); +``` + +| param | description | +|-------------|--------------------------------------------------------------------------------------------| +| `$priority` | The priority of the notification, the higher the priority, the sooner it will be displayed | + +--- + +

hops

+ +This method sets the number of requests that the flash message should persist for. By default, flash messages are only displayed for a single request and are then discarded. By setting the number of hops, the flash message will be persisted for multiple requests. + +As an example, with a multi-page form, you may want to store messages until all pages have been filled. + +{% assign id = '#/ usage hops' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +flash()->hops(int $hops); +``` + +```php +flash() + ->hops(2) + ->{{ type }}('{{ message }}'); +``` + +| param | description | +|---------|---------------------------------------------------------------| +| `$hops` | indicate how many requests the flash message will persist for | + +--- + +

translate

+ +This method sets the `locale` to be used for the translation of the flash message. If a non-null value is provided, +the flash message will be translated into the specified language. If null is provided, the **default** `locale` will be used. + +```php +flash()->translate(string $locale = null); +``` + +{% assign id = '#/ usage translate' %} +{% assign type = 'success' %} +{% assign message = 'تمت العملية بنجاح.' %} +{% assign title = 'تهانينا' %} +{% assign options = '{"rtl": true, "position": "top-right"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->translate('ar') + ->{{ type }}('Your request was processed successfully.', 'Congratulations!'); +``` + +{% assign id = '#/ usage translate with position' %} +{% assign type = 'success' %} +{% assign message = 'تمت العملية بنجاح.' %} +{% assign title = 'تهانينا' %} +{% assign options = '{"rtl": true, "position": "top-left"}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->translate('ar') + ->option('position', 'top-left') + ->{{ type }}('Your request was processed successfully.', 'Congratulations!'); +``` + +| param | description | +|-----------|------------------------------------------------------------------------------| +| `$locale` | The locale to be used for the translation, or null to use the default locale | + +It is **important** to note that the `translate()` method only sets the locale to be used for the translation of the flash message. +It does not actually perform the translation itself. + +In order to translate the flash message, you will need to provide the appropriate translation keys in your translation files. + +In the above example, to translate the flash message into `Arabic`, If you are using ** Laravel** you will need to add the following keys to the `resources/lang/ar/messages.php` file: + +```php +return [ + 'Your request was processed successfully.' => 'تمت العملية بنجاح.', + 'Congratulations!' => 'تهانينا', +]; +``` diff --git a/docs/pages/javascript.md b/docs/pages/javascript.md new file mode 100644 index 00000000..0f374054 --- /dev/null +++ b/docs/pages/javascript.md @@ -0,0 +1,90 @@ +--- +permalink: /javascript/ +redirect_from: /docs/framework/javascript/ +title: JavaScript +description: Easily add flash notification messages to your JavaScript application with PHPFlasher. Follow our step-by-step guide to install the library using npm or include it in your project using CDN links, and start engaging and informing your users with powerful flash messages. +--- + +{% PHPFlasher %} assets can be installed from a cdn or using npm + +## Installation +Quick start guide for installing the {% PHPFlasher %} from cdn or npm. + +--- + +### cdn + +To pull in the {% PHPFlasher %} via CDN, grab the latest version from [jsdelivr](https://www.jsdelivr.com/package/npm/@flasher/flasher) + + + + cdn-jsdelivr + + + + + + +```html + +``` + +--- + +### npm + +To install {% PHPFlasher %} from npm use the following command: + +```shell +npm i @flasher/flasher +``` + +## Usage + + +```javascript +import flasher from "@flasher/flasher"; + +window.flasher = flasher; // only if you want to use it globally + +flasher.error("Oops! Something went wrong!"); +flasher.warning("Are you sure you want to proceed ?"); +flasher.success("Data has been saved successfully!"); +flasher.info("Welcome back"); +``` + +or if you are using a cdn like this: +```html + + +``` + +--- + +### Other adapters + +First grad the cdn for any js library adapter supported by {% PHPFlasher %} or install it with npm +and then call the `create()` method on flasher object : + +```html + + + +``` diff --git a/docs/pages/laravel.md b/docs/pages/laravel.md new file mode 100644 index 00000000..ca228b52 --- /dev/null +++ b/docs/pages/laravel.md @@ -0,0 +1,387 @@ +--- +permalink: /laravel/ +title: Laravel +handler: flasher +description: Easily add flash notification messages to your Laravel application with PHPFlasher. Follow our step-by-step guide to install and use the library in your project, and start engaging and informing your users with powerful flash messages. +framework: laravel +--- + +## {% PHPFlasher %} Laravel + +{% PHPFlasher %} is a trusted and well-supported package +that allows you to easily integrate flash notification messages into your **Laravel** projects. + +To use {% PHPFlasher %} in a **Laravel** application, you need : + +> **PHP** >= 8.2 +> **Laravel** >= 11.0 + +--- + +## Installation + +{% PHPFlasher %} is modular and consists of multiple libraries, +allowing users to install and use only the specific components they need for their project. + +{% PHPFlasher %} can be installed using composer : + +```shell +composer require php-flasher/flasher-laravel +``` + +--- + +{% PHPFlasher %} includes a default notification style , but users can also install additional adapters to customize the appearance of notifications within their projects such as : + +* **[Toastr](/library/toastr/)** +* **[Noty](/library/noty/)** +* **[Notyf](/library/notyf/)** +* **[Sweet Alert](/library/sweetalert/)** + +--- + +{% include _usage.md %} + +--- + +## Configuration + +As optional, if you want to modify the default configuration, you can publish the configuration file: + +```bash +php artisan flasher:install +``` + +The configuration file will be located at `config/flasher.php` and will have the following content: + +```php + 'flasher', + + // Path to the main JavaScript file of PHPFlasher + 'main_script' => '/vendor/flasher/flasher.min.js', + + // Path to the stylesheets for PHPFlasher notifications + 'styles' => [ + '/vendor/flasher/flasher.min.css', + ], + + // Whether to translate PHPFlasher messages using Laravel's translation service + 'translate' => true, + + // Automatically inject PHPFlasher assets into HTML response + 'inject_assets' => true, + + // Configuration for the flash bag (converting Laravel flash messages) + // Map Laravel session keys to PHPFlasher types + 'flash_bag' => [ + 'success' => ['success'], + 'error' => ['error', 'danger'], + 'warning' => ['warning', 'alarm'], + 'info' => ['info', 'notice', 'alert'], + ], + + // Filter criteria for notifications (e.g., limit number, types) + 'filter' => [ + 'limit' => 5, // Limit the number of displayed notifications + ], +]; +``` + +--- + +## Presets + +You can create a preset for a custom notification that you want to reuse in multiple places by adding a presets entry in the configuration file. + +> You can think of a preset as a pre-defined message that you can use in multiple locations.
+ +For example, you can create a preset named `entity_saved` in the configuration file and then use + +{% assign id = '#/ laravel preset' %} +{% assign type = 'success' %} +{% assign message = 'Entity saved successfully' %} +{% assign title = 'Entity saved' %} +{% assign options = '{}' %} +{% include example.html %} + +```php + [ + 'entity_saved' => [ + 'type' => '{{ type }}', + 'message' => '{{ message }}', + 'title' => '{{ title }}', + ], + ], +]; +``` + +To use the preset, you can call the `preset()` method and pass the name of the preset as the first argument: + +```php +{{ id }} + +class BookController +{ + public function save() + { + flash()->preset('entity_saved'); +``` + +This is equivalent to: + +```php +class BookController +{ + public function save() + { + flash()->{{ type }}('{{ message }}', '{{ title }}'); +``` + +

Variables

+ +Presets can also contain variables that can be substituted by using the translation system. Take the following example where you have a preset showing a personalised welcome message to the user. + +```php + [ + 'hello_user' => [ + 'type' => '{{ type }}', + 'message' => 'welcome_back_user', + ], + ], +]; +``` + +In the translations file you can define `welcome_back_user` with the message containing the variable `:username`. + +```php + 'Welcome back :username', +]; +``` + +If you want to substitute the `:username` in the above translation with a username in the controller, you can achieve this by passing an array of values to be substituted as the second argument. + +```php +class BookController +{ + public function save() + { + $username = 'John Doe'; + + flash()->preset('hello_user', ['username' => $username]); +``` + +--- + +## RTL support + +{% PHPFlasher %} makes it easy to incorporate **right-to-left** languages like `Arabic` or `Hebrew`. +it automatically detects the text direction and handles the necessary adjustments for you. + +Simply make sure the translation service is enabled and let {% PHPFlasher %} handle the rest. + +{% assign id = '#/ phpflasher rtl' %} +{% assign type = 'success' %} +{% assign message = 'تمت العملية بنجاح.' %} +{% assign title = 'تهانينا' %} +{% assign options = '{"rtl": true}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->translate('ar') + ->{{ type }}('Your request was processed successfully.', 'Congratulations!'); +``` + +--- + +## Translation + +{% PHPFlasher %} allows you to translate your notification `messages`, `presets`, it comes with `Arabic`, `English` and `French` translations out of the box, but you can easily add your own translations. + +For example, if you need to override the `English` translation strings for {% PHPFlasher %}, you can create a language file at the following location: +**`/resources/lang/vendor/flasher/en/messages.php`**. + +In this file, you should **only** define the translation strings you want to override. Any translation strings that you don't override will still be loaded from {% PHPFlasher %}'s original language files. + +Here is a list of the default translation keys for {% PHPFlasher %}: + +```php + 'نجاح', + 'error' => 'خطأ', + 'warning' => 'تحذير', + 'info' => 'معلومة', + + 'The resource was created' => 'تم إنشاء :resource', + 'The resource was updated' => 'تم تعديل :resource', + 'The resource was saved' => 'تم حفظ :resource', + 'The resource was deleted' => 'تم حذف :resource', + + 'resource' => 'الملف', +]; +``` + +```php + 'Success', + 'error' => 'Error', + 'warning' => 'Warning', + 'info' => 'Info', + + 'The resource was created' => 'The :resource was created', + 'The resource was updated' => 'The :resource was updated', + 'The resource was saved' => 'The :resource was saved', + 'The resource was deleted' => 'The :resource was deleted', + + 'resource' => 'resource', +]; +``` + +```php + 'Succès', + 'error' => 'Erreur', + 'warning' => 'Avertissement', + 'info' => 'Information', + + 'The resource was created' => 'La ressource :resource a été ajoutée', + 'The resource was updated' => 'La ressource :resource a été mise à jour', + 'The resource was saved' => 'La ressource :resource a été enregistrée', + 'The resource was deleted' => 'La ressource :resource a été supprimée', + + 'resource' => '', +]; +``` + +{% assign id = '#/ laravel arabic translations' %} +{% assign successMessage = 'تم إنشاء الملف' %} +{% assign errorMessage = 'حدث خطأ أثناء إرسال طلبك.' %} +{% assign warningMessage = 'يجب إكمال جميع الحقول الإلزامية قبل إرسال النموذج' %} +{% assign infoMessage = 'سيتم تحديث هذه الصفحة في غضون 10 دقائق.' %} + + + +```php +{{ id }} + +use Illuminate\Support\Facades\App; + +// Set the locale to be used for the translation +App::setLocale('ar'); + +// Translate the flash message using the PHPFlasher translation files +flash()->success('The resource was created'); + +flash()->error('{{ errorMessage }}'); +flash()->warning('{{ warningMessage }}'); +flash()->info('{{ infoMessage }}'); +``` + +{% assign id = '#/ laravel french translations' %} +{% assign successMessage = "La ressource a été ajoutée" %} +{% assign errorMessage = "Une erreur s’est produite lors de l’envoi de votre demande." %} +{% assign warningMessage = "Vous devez remplir tous les champs obligatoires avant de soumettre le formulaire." %} +{% assign infoMessage = "Cette page sera mise à jour dans 10 minutes."%} + + + +```php +{{ id }} + +use Illuminate\Support\Facades\App; + +// Set the locale to be used for the translation +App::setLocale('fr'); + +// Translate the flash message using the PHPFlasher translation files +flash()->success('The resource was created'); + +flash()->error('{{ errorMessage }}'); +flash()->warning('{{ warningMessage }}'); +flash()->info('{{ infoMessage }}'); +``` diff --git a/docs/pages/library/noty.md b/docs/pages/library/noty.md new file mode 100644 index 00000000..4abba3ec --- /dev/null +++ b/docs/pages/library/noty.md @@ -0,0 +1,703 @@ +--- +permalink: /library/noty/ +title: Noty +description: Elevate your user experience with Noty, a popular JavaScript library for creating customizable, stylish notification messages. Easy to install and use, Noty is perfect for any project that wants to engage and inform users in a dynamic way. +handler: noty +data-controller: noty +--- + +## Installation + +** Laravel**: + +```shell +composer require php-flasher/flasher-noty-laravel +``` + +
+ +** Symfony**: + +```shell +composer require php-flasher/flasher-noty-symfony +``` + +--- + +## Usage + +{% assign id = '#/ noty' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +namespace App\Controller; + +class AppController +{ + public function save() + { + noty()->{{ type }}('{{ message }}'); + } +} +``` + +--- + +## Modifiers + +For more information on Noty options and usage, please refer to the original documentation at [https://ned.im/noty/](https://ned.im/noty/) + +--- + +> The methods described in the **[Usage](/installation/#-modifiers)** section can also be used with the `noty` adapter. + +--- + +

layout

+ +`top`, `topLeft`, `topCenter`, `topRight`, `center`, `centerLeft`, `centerRight`, `bottom`, `bottomLeft`, `bottomCenter`, `bottomRight`
+ +ClassName generator uses this value → noty_layout__${layout} + +```php +noty()->layout(string $layout); +``` + +{% assign id = '#/ noty layout' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"layout":"topCenter"}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->layout('topCenter') + ->{{ type }}('{{ message }}'); +``` + +--- + +

theme

+ +Possible values: `relax`, `mint`, `metroui`, `light`, `sunset`, `nest`. + +ClassName generator uses this value → noty_theme__${theme} + +```php +noty()->theme(string $theme); +``` + +> Default Theme: **mint** + +
Examples: + +{% assign successMessage = site.data.messages['success'] | sample %} +{% assign errorMessage = site.data.messages['error'] | sample %} +{% assign warningMessage = site.data.messages['warning'] | sample %} +{% assign infoMessage = site.data.messages['info'] | sample %} + + + +```php +#/ noty theme mint + +noty() + ->theme('mint') + ->success('{{ successMessage }}'); + +noty() + ->theme('mint') + ->error('{{ errorMessage }}'); + +noty() + ->theme('mint') + ->warning('{{ warningMessage }}'); + +noty() + ->theme('mint') + ->info('{{ infoMessage }}'); +``` + +{% assign successMessage = site.data.messages['success'] | sample %} +{% assign errorMessage = site.data.messages['error'] | sample %} +{% assign warningMessage = site.data.messages['warning'] | sample %} +{% assign infoMessage = site.data.messages['info'] | sample %} + + + +```php +#/ noty theme relax + +// don't the load the theme css file: https://github.com/needim/noty/blob/master/lib/themes/relax.css + +noty() + ->theme('relax') + ->success('{{ successMessage }}'); + +noty() + ->theme('relax') + ->error('{{ errorMessage }}'); + +noty() + ->theme('relax') + ->warning('{{ warningMessage }}'); + +noty() + ->theme('relax') + ->info('{{ infoMessage }}'); +``` + +{% assign successMessage = site.data.messages['success'] | sample %} +{% assign errorMessage = site.data.messages['error'] | sample %} +{% assign warningMessage = site.data.messages['warning'] | sample %} +{% assign infoMessage = site.data.messages['info'] | sample %} + + + +```php +#/ noty theme metroui + +// Theme: https://github.com/needim/noty/blob/master/lib/themes/metroui.css + +noty() + ->theme('metroui') + ->success('{{ successMessage }}'); + +noty() + ->theme('metroui') + ->error('{{ errorMessage }}'); + +noty() + ->theme('metroui') + ->warning('{{ warningMessage }}'); + +noty() + ->theme('metroui') + ->info('{{ infoMessage }}'); +``` + +{% assign successMessage = site.data.messages['success'] | sample %} +{% assign errorMessage = site.data.messages['error'] | sample %} +{% assign warningMessage = site.data.messages['warning'] | sample %} +{% assign infoMessage = site.data.messages['info'] | sample %} + + + +```php +#/ noty theme light + +// Theme: https://github.com/needim/noty/blob/master/lib/themes/light.css + +noty() + ->theme('light') + ->success('{{ successMessage }}'); + +noty() + ->theme('light') + ->error('{{ errorMessage }}'); + +noty() + ->theme('light') + ->warning('{{ warningMessage }}'); + +noty() + ->theme('light') + ->info('{{ infoMessage }}'); +``` + +{% assign successMessage = site.data.messages['success'] | sample %} +{% assign errorMessage = site.data.messages['error'] | sample %} +{% assign warningMessage = site.data.messages['warning'] | sample %} +{% assign infoMessage = site.data.messages['info'] | sample %} + + + +```php +#/ noty theme sunset +// Theme: https://github.com/needim/noty/blob/master/lib/themes/sunset.css + +noty() + ->theme('sunset') + ->success('{{ successMessage }}'); + +noty() + ->theme('sunset') + ->error('{{ errorMessage }}'); + +noty() + ->theme('sunset') + ->warning('{{ warningMessage }}'); + +noty() + ->theme('sunset') + ->info('{{ infoMessage }}'); +``` + +--- + +

timeout

+ +`false`, `1000`, `3000`, `3500`, etc. Delay for closing event in milliseconds (ms). Set `false` for sticky +notifications. + +```php +noty()->timeout(int|bool $timeout) +``` + +{% assign id = '#/ noty timeout' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeout": 2000}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->timeout(2000) // 2 seconds + ->{{ type }}('{{ message }}'); +``` + +--- + +

progressBar

+ +`true`, `false` - Displays a progress bar if timeout is not false. + +```php +noty()->progressBar(bool $progressBar = false) +``` + +{% assign id = '#/ noty progressBar' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"progressBar": false}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->progressBar(false) + ->{{ type }}('{{ message }}'); +``` + +--- + +

closeWith

+ +`click`, `button` + +Default `click` + +```php +noty()->closeWith(string|array $closeWith) +``` + +{% assign id = '#/ noty closeWith' %} +{% assign type = 'error' %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"closeWith": ["click", "button"]}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->closeWith(['click', 'button']) + ->{{ type }}('{{ message }}'); +``` + +--- + +

animation

+ +If `string`, assumed to be CSS class name.
+If `null`, no animation at all.
+If `function`, runs the function. (v3.0.1+)

+You can use `animate.css` class names or your custom css animations as well. + +```php +noty()->animation(string $animation, string $effect) +``` + +{% assign id = '#/ noty animation' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"animation": null}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->animation(null) + ->{{ type }}('{{ message }}'); +``` + +--- + +

sounds

+ +`sources` : Array of audio sources e.g 'some.wav'
+`volume` : nteger value between 0-1 e.g 0.5
+`conditions` : There are two conditions for now: 'docVisible' & 'docHidden'. You can use one of them or both.
+ +```php +noty()->sounds(string $option, mixed $value) +``` + +{% assign id = '#/ noty sounds' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"sounds": {"sources": ["/static/sounds/notification.wav"], "volume": 0.3, "conditions": ["docVisible", "docHidden"]}}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->sounds('sources', ['/static/sounds/notification.wav']) + ->sounds('volume', 0.3) + ->sounds('conditions', ['docVisible', 'docHidden']) + ->{{ type }}('{{ message }}'); +``` + +--- + +

docTitle

+ +There are two conditions for now: `docVisible` & `docHidden`. You can use one of them or both. + +```php +noty()->docTitle(string $option, mixed $docTitle) +``` + +{% assign id = '#/ noty docTitle' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"docTitle": {"conditions": ["docVisible", "docHidden"]}}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->docTitle('conditions', ['docVisible', 'docHidden']) + ->{{ type }}('{{ message }}'); +``` + +--- + +

modal

+ +```php +noty()->modal(bool $modal = true) +``` + +{% assign id = '#/ noty modal' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"modal": true}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->modal(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

id

+ +You can use this id with querySelectors.
+Generated automatically if false. + +```php +noty()->id(bool|string $id) +``` + +{% assign id = '#/ noty id' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"id": false}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->id(false) + ->{{ type }}('{{ message }}'); +``` + +--- + +

force

+ +DOM insert method depends on this parameter.
+If `false` uses append, if `true` uses prepend. + +```php +noty()->force(bool $force = true) +``` + +{% assign id = '#/ noty force' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"force": false}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->force(false) + ->{{ type }}('{{ message }}'); +``` + +--- + +

queue

+ +NEW Named queue system. Details are [here](https://ned.im/noty/#/api). + +```php +noty()->queue(string $queue) +``` + +Default: `global` + +{% assign id = '#/ noty queue' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"queue":"global"}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->queue('global') + ->{{ type }}('{{ message }}'); +``` + +--- + +

killer

+ +If `true` closes all `visible` notifications and shows itself.
+If `string(queueName)` closes all `visible` notification on this queue and shows itself. + +```php +noty()->killer(bool|string $killer) +``` + +{% assign id = '#/ noty killer' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"killer": true}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->killer(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

container

+ +Custom container selector string. Like `.my-custom-container`.
+Layout parameter will be ignored. + +```php +noty()->container(bool|string $container) +``` + +{% assign id = '#/ noty container' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"container": false}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->container(false) + ->{{ type }}('{{ message }}'); +``` + +--- + +

visibilityControl

+ +If `true` Noty uses PageVisibility API to handle timeout.
+To ensure that users do not miss their notifications. + +```php +noty()->visibilityControl(bool $visibilityControl) +``` + +{% assign id = '#/ noty visibilityControl' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"visibilityControl": true}' %} +{% include example.html %} + +```php +{{ id }} + +noty() + ->visibilityControl(true) + ->{{ type }}('{{ message }}'); +``` diff --git a/docs/pages/library/notyf.md b/docs/pages/library/notyf.md new file mode 100644 index 00000000..d1a2c199 --- /dev/null +++ b/docs/pages/library/notyf.md @@ -0,0 +1,175 @@ +--- +permalink: /library/notyf/ +title: Notyf +description: Add lightweight, customizable notification messages to your web projects with Notyf, a popular JavaScript library. With a focus on simplicity and accessibility, Notyf is easy to install and use, making it a great choice for any project that wants to engage and inform users. +handler: notyf +data-controller: notyf +--- + +## Installation + +** Laravel**: + +```shell +composer require php-flasher/flasher-notyf-laravel +``` + +
+ +** Symfony**: + +```shell +composer require php-flasher/flasher-notyf-symfony +``` + +--- + +## Usage + +{% assign id = '#/ notyf' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +namespace App\Controller; + +class AppController +{ + public function save() + { + notyf()->{{ type }}('{{ message }}'); + } +} +``` + +--- + +## Modifiers + +For more information on Notyf options and usage, please refer to the original documentation at [https://github.com/caroso1222/notyf](https://github.com/caroso1222/notyf) + +--- + +> The methods described in the **[Usage](/installation/#-modifiers)** section can also be used with the `notyf` adapter. + +--- + +

position

+ +Viewport location where notifications are rendered + +position x ⇒ `left`, `center`, `right`
+position y ⇒ `top`, `center`, `bottom` + +Default ⇒ x: `right`, y: `bottom` + +```php +notyf()->position(string $position, string $value); +``` + +{% assign id = '#/ notyf position' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"position": {"x": "center", "y":"top"}}' %} +{% include example.html %} + +```php +{{ id }} + +notyf() + ->position('x', 'center') + ->position('y', 'top') + ->{{ type }}('{{ message }}'); +``` + +--- + +

duration

+ +Number of milliseconds before hiding the notification. Use 0 for infinite duration. + +```php +notyf()->duration(int $duration); +``` + +{% assign id = '#/ notyf duration' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"duration": 2000}' %} +{% include example.html %} + +```php +{{ id }} + +notyf() + ->duration(2000) // 2 seconds + ->{{ type }}('{{ message }}'); +``` + +--- + +

ripple

+ +Whether to show the notification with a ripple effect + +Default ⇒ `true` + +```php +notyf()->ripple(bool $ripple); +``` + +{% assign id = '#/ notyf ripple true' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"ripple": true}' %} +{% include example.html %} + +```php +{{ id }} + +notyf() + ->ripple(true) + ->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ notyf ripple false' %} +{% assign options = '{"ripple": false}' %} +{% include example.html %} + +```php +{{ id }} + +notyf() + ->ripple(false) + ->{{ type }}('{{ message }}'); +``` + +--- + +

dismissible

+ +Whether to allow users to dismiss the notification with a button + +Default ⇒ `false` + +```php +notyf()->dismissible(bool $dismissible); +``` + +{% assign id = '#/ notyf dismissible' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"dismissible": true}' %} +{% include example.html %} + +```php +{{ id }} + +notyf() + ->dismissible(true) + ->{{ type }}('{{ message }}'); +``` diff --git a/docs/pages/library/sweetalert.md b/docs/pages/library/sweetalert.md new file mode 100644 index 00000000..fccfc813 --- /dev/null +++ b/docs/pages/library/sweetalert.md @@ -0,0 +1,231 @@ +--- +permalink: /library/sweetalert/ +title: Sweetalert +description: Add beautiful, customizable alert messages to your web projects with SweetAlert2, a popular JavaScript library. Easy to install and use, SweetAlert2 is perfect for any project that wants to engage and inform users in a visually appealing way. +handler: sweetalert +data-controller: sweetalert +--- + +## Installation + +** Laravel**: + +```shell +composer require php-flasher/flasher-sweetalert-laravel +``` + +
+ +** Symfony**: + +```shell +composer require php-flasher/flasher-sweetalert-symfony +``` + +--- + +## Usage + +{% assign id = '#/ sweetalert' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +namespace App\Controller; + +class AppController +{ + public function save() + { + sweetalert()->{{ type }}('{{ message }}'); + } +} +``` + +--- + +## Modifiers + +For more information on Sweetalert2 alert options and usage, please refer to the original documentation at [https://sweetalert2.github.io](https://sweetalert2.github.io) + +--- + +> The methods described in the **[Usage](/installation/#-modifiers)** section can also be used with the `sweetalert` adapter. + +--- + +

imageUrl

+ +Add a customized icon for the popup. Should contain a string with the path or URL to the image. + +```php +sweetalert()->imageUrl( + string $imageUrl, + int $imageWidth = null, + int $imageHeight = null, + string $imageAlt = null +); +``` + +--- + +

position

+ + Popup window position, can be `top`, `top-start`, `top-end`, `center`, `center-start`, `center-end`, `bottom`, `bottom-start` or `bottom-end`. + +```php +sweetalert()->position(string $position); +``` + +--- + +

toast

+ +Whether or not an alert should be treated as a toast notification. This option is normally coupled with the +position parameter and a timer. Toasts are NEVER autofocused. + +```php +sweetalert()->toast(bool $toast = true, string $position = 'top-end', bool $showConfirmButton = false); +``` + +--- + +

timer

+ +Auto close timer of the popup. Set in ms (milliseconds). + +```php +sweetalert()->timer(int $timer); +``` + +--- + +

timerProgressBar

+ +If set to `true`, the timer will have a progress bar at the bottom of a popup. Mostly, this feature is useful with toasts. + +```php +sweetalert()->timerProgressBar(bool $timerProgressBar = true); +``` + +--- + +

backdrop

+ +Whether or not SweetAlert2 should show a full screen click-to-dismiss backdrop. Can be either a boolean or a +string which will be assigned to the CSS background property. + +```php +sweetalert()->backdrop(bool $backdrop = true); +``` + +--- + +

grow

+ +Paired with window position, sets the direction the popup should grow in, can be set to `row`, `column`, `fullscreen` or `false`. + +```php +sweetalert()->grow(bool|string $grow); +``` + +--- + +

showConfirmButton

+ +If set to `false`, a `Confirm` button will not be shown. + +```php +sweetalert()->showConfirmButton( + bool $showConfirmButton = true, + string $confirmButtonText = null, + string $confirmButtonColor = null, + string $confirmButtonAriaLabel = null +); +``` + +--- + +

showDenyButton

+ +If set to `true`, a `Deny` button will be shown. It can be useful when you want a popup with 3 buttons. + +```php +sweetalert()->showDenyButton( + bool $showDenyButton = true, + string $denyButtonText = null, + string $denyButtonColor = null, + string $denyButtonAriaLabel = null +); +``` + +--- + +

showCancelButton

+ +If set to `true`, a `Cancel` button will be shown, which the user can click on to dismiss the modal. + +```php +sweetalert()->showCancelButton( + bool $showCancelButton = true, + string $cancelButtonText = null, + string $cancelButtonColor = null, + string $cancelButtonAriaLabel = null +); +``` + +--- + +

confirmButtonText

+ +Use this to change the text on the `Confirm` button. + +```php +sweetalert()->confirmButtonText( + string $confirmButtonText, + string $confirmButtonColor = null, + string $confirmButtonAriaLabel = null +); +``` + +--- + +

denyButtonText

+ +Use this to change the text on the `Deny` button. + +```php +sweetalert()->denyButtonText( + string $denyButtonText, + string $denyButtonColor = null, + string $denyButtonAriaLabel = null +); +``` + +--- + +

cancelButtonText

+ +Use this to change the text on the `Cancel` button. + +```php +sweetalert()->cancelButtonText( + string $cancelButtonText, + string $cancelButtonColor = null, + string $cancelButtonAriaLabel = null +); +``` + +--- + +

showCloseButton

+ +Set to `true` to show close button in top right corner of the popup. + +```php +sweetalert()->showCloseButton(bool $showCloseButton = true); +``` diff --git a/docs/pages/library/toastr.md b/docs/pages/library/toastr.md new file mode 100644 index 00000000..611aed82 --- /dev/null +++ b/docs/pages/library/toastr.md @@ -0,0 +1,412 @@ +--- +permalink: /library/toastr/ +title: Toastr +description: Easily add customizable, stylish notification messages to your web projects with Toastr, a popular JavaScript library. With a focus on simplicity and flexibility, Toastr is easy to install and use, making it a great choice for any project that wants to engage and inform users. +handler: toastr +data-controller: toastr +--- + +## Installation + +** Laravel**: + +```shell +composer require php-flasher/flasher-toastr-laravel +``` + +
+ +** Symfony**: + +```shell +composer require php-flasher/flasher-toastr-symfony +``` + +--- + +## Usage + +{% assign id = '#/ toastr' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +namespace App\Controller; + +class AppController +{ + public function save() + { + toastr()->{{ type }}('{{ message }}'); + } +} +``` + +--- + + +## Modifiers + +For more information on Toastr options and usage, please refer to the original documentation at [https://github.com/CodeSeven/toastr](https://github.com/CodeSeven/toastr) + +--- + +> The methods described in the **[Usage](/installation/#-modifiers)** section can also be used with the `toastr` adapter. + +--- + +

persistent

+ +Prevent from Auto Hiding. + +```php +toastr()->persistent(); +``` + +{% assign id = '#/ toastr persistent' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeOut": 0, "extendedTimeOut": 0, "closeButton": true}' %} +{% include example.html %} + + +```php +{{ id }} + +toastr() + ->persistent() + ->closeButton() + ->{{ type }}('{{ message }}'); +``` + +--- + +

closeButton

+ +When set to `true`, a close button is displayed in the toast notification. + +```php +toastr()->closeButton(bool $closeButton = true); +``` + +{% assign id = '#/ toastr closeButton' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"closeButton": true}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->closeButton(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

closeHtml

+ +The HTML content of the close button. + +Default ⇒ `` + +```php +toastr()->closeHtml(string $closeHtml); +``` + +{% assign id = '#/ toastr closeHtml' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"closeButton": true, "closeHtml":""}' %} +{% include example.html %} + + +```php +{{ id }} + +toastr() + ->closeButton(true) + ->closeHtml('⛑') + ->{{ type }}('{{ message }}'); +``` + +--- + +

closeOnHover

+ +When set to `true`, the toast will close when the user hovers over it. + +Default ⇒ `false` + +```php +toastr()->closeOnHover(bool $closeOnHover = true); +``` + +{% assign id = '#/ toastr closeOnHover' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"closeOnHover": true, "closeDuration": 10}' %} +{% include example.html %} + + +```php +{{ id }} + +toastr() + ->closeOnHover(true) + ->closeDuration(10) + ->{{ type }}('{{ message }}'); +``` + +--- + +

escapeHtml

+ +When set to `true`, HTML in the toast message will be escaped. + +Default ⇒ `false` + +```php +toastr()->escapeHtml(bool $escapeHtml = true); +``` + +{% assign id = '#/ toastr escapeHtml false' %} +{% assign type = 'error' %} +{% assign message = 'We’re sorry, but an error occurred.' %} +{% assign options = '{"escapeHtml": false}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->escapeHtml(false) + ->{{ type }}('{{ message }}'); +``` + +{% assign id = '#/ toastr escapeHtml true' %} +{% assign options = '{"escapeHtml": true}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->escapeHtml(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

newestOnTop

+ +When set to `true`, new toast notifications are displayed above older ones. + +Default ⇒ `true` + +```php +toastr()->newestOnTop(bool $newestOnTop = true); +``` + +{% assign id = '#/ toastr newestOnTop' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"newestOnTop": true}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->newestOnTop(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

positionClass

+ +The class applied to the toast container that determines the position of the toast on the screen (e.g. `toast-top-right`, `toast-bottom-left`). + +Default ⇒ `toast-top-right` + +```php +toastr()->positionClass(string $positionClass); +``` + +{% assign id = '#/ toastr positionClass' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"positionClass": "toast-top-center"}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->positionClass('toast-top-center') + ->{{ type }}('{{ message }}'); +``` + +--- + +

preventDuplicates

+ +When set to `true`, prevents the display of multiple toast notifications with the same message. + +Default ⇒ `false` + +```php +toastr()->preventDuplicates(bool $preventDuplicates = true); +``` + +{% assign id = '#/ toastr preventDuplicates' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"preventDuplicates": true}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->preventDuplicates(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

progressBar

+ +When set to `true`, displays a progress bar in the toast. + +Default ⇒ `true` + +```php +toastr()->progressBar(bool $progressBar = true); +``` + +{% assign id = '#/ toastr progressBar' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"progressBar": false}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->progressBar(false) + ->{{ type }}('{{ message }}'); +``` + +--- + +

rtl

+ +When set to `true`, displays the toast notifications in right-to-left mode. + +Default ⇒ `false` + +```php +toastr()->rtl(bool $rtl = true); +``` + +{% assign id = '#/ toastr rtl' %} +{% assign type = 'info' %} +{% assign message = 'تم قفل حسابك وتم إرسال رسالة تأكيد إلكترونية.' %} +{% assign options = '{"rtl": true}' %} +{% include example.html %} + +```php +{{ id }} + +toastr() + ->rtl(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

tapToDismiss

+ +When set to `true`, the toast can be dismissed by tapping on it. + +```php +toastr()->tapToDismiss(bool $tapToDismiss = true); +``` + +{% assign id = '#/ toastr tapToDismiss' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"tapToDismiss": true}' %} +{% include example.html %} + + +```php +{{ id }} + +toastr() + ->tapToDismiss(true) + ->{{ type }}('{{ message }}'); +``` + +--- + +

target

+ +The element that should contain the toast notifications. + +Default ⇒ `body` + +```php +toastr()->target(string $target); +``` + +{% assign id = '#/ toastr target' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"target": "body"}' %} +{% include example.html %} + + +```php +{{ id }} + +toastr() + ->target('body') + ->{{ type }}('{{ message }}'); +``` + +--- + +

timeOut

+ +The time in milliseconds to keep the toast visible before it is automatically closed.
+Set `timeOut` and `extendedTimeOut` to `0` to make it sticky + +Default ⇒ `5000` milliseconds + +```php +toastr()->timeOut(int $timeOut, bool $extendedTimeOut = null); +``` + +{% assign id = '#/ toastr timeOut' %} +{% assign type = site.data.messages.types | sample %} +{% assign message = site.data.messages[type] | sample %} +{% assign options = '{"timeOut": 1000}' %} +{% include example.html %} + + +```php +{{ id }} + +toastr() + ->timeOut(1000) // 1 second + ->{{ type }}('{{ message }}'); +``` diff --git a/docs/pages/livewire.md b/docs/pages/livewire.md new file mode 100644 index 00000000..63e34b9b --- /dev/null +++ b/docs/pages/livewire.md @@ -0,0 +1,134 @@ +--- +permalink: /livewire/ +title: Livewire +description: Learn how to seamlessly integrate flash notification messages into your Livewire application with PHPFlasher. Follow our step-by-step guide to install and use the library in your project, and start engaging and informing your users with powerful flash messages. +adapter: flasher +--- + +{% PHPFlasher %} provides a seamless integration with Livewire v3. + +## Requirements + +> **PHP** >= 8.2 +> **Laravel** >= 11 + +--- + +## Installation + +To integrate {% PHPFlasher %} with Livewire, follow the same installation steps as for the [Laravel Installation](/laravel) package. + +```shell +composer require php-flasher/flasher-laravel +``` + +--- + +## Usage + +Dispatch `notifications` from your components + +{% assign id = '#/ livewire' %} +{% assign type = 'success' %} +{% assign message = 'User saved successfully!' %} +{% assign options = '{}' %} +{% include example.html %} + +```php +{{ id }} + +namespace App\Livewire; + +use Livewire\Component; + +class UserComponent extends Component +{ + public function save() + { + flash()->{{ type }}('{{ message }}'); + } + + public function render() + { + return view('livewire.user'); + } +``` + +--- + +## Events + +For sweetalert you can listen to `sweetalert:confirmed`, `sweetalert:denied` and `sweetalert:dismissed` from withing you component + + + +```php +#/ livewire events + +namespace App\Livewire; + +use Livewire\Attributes\On; +use Livewire\Component; + +class UserComponent extends Component +{ + public function render() + { + return <<<'HTML' +
+ +
+ HTML; + } + + public function deleteUser() + { + sweetalert() + ->showDenyButton() + ->info('Are you sure you want to delete the user ?'); + } + + #[On('sweetalert:confirmed')] + public function onConfirmed(array $payload): void + { + flash()->info('User successfully deleted.'); + } + + #[On('sweetalert:denied')] + public function onDeny(array $payload): void + { + flash()->info('Deletion cancelled.'); + } +} +``` + +### event handlers context + +Every listener method accept an **array $payload** parameter which contain the following data : + +```php +public function sweetalertConfirmed(array $payload) +{ + $promise = $payload['promise']; + $envelope = $payload['envelope']; +} +``` + +> **promise** : the resolved promise from **sweetalert**. + +> **envelope** : the notification where the event happened. diff --git a/docs/pages/symfony.md b/docs/pages/symfony.md new file mode 100644 index 00000000..3e6ac4fb --- /dev/null +++ b/docs/pages/symfony.md @@ -0,0 +1,360 @@ +--- +permalink: /symfony/ +title: Symfony +description: Easily add flash notification messages to your Symfony application with PHPFlasher. Follow our step-by-step guide to install and use the library in your project, and start engaging and informing your users with powerful flash messages. +framework: symfony +--- + +## {% PHPFlasher %} Symfony + +{% PHPFlasher %} is a trusted and well-supported package +that allows you to easily integrate flash notification messages into your **Symfony** projects. + +To use {% PHPFlasher %} in a **Symfony** application, you need : + +> **PHP** >= 8.2 +> **Symfony** >= 7.0 + +--- + +## Installation + +{% PHPFlasher %} is modular and consists of multiple libraries, +allowing users to install and use only the specific components they need for their project. + +{% PHPFlasher %} can be installed using composer : + +```shell +composer require php-flasher/flasher-symfony +``` + +--- + +{% PHPFlasher %} includes a default notification style , but users can also install and use additional adapters to customize the appearance of notifications within their projects such as : + +* **[Toastr](/library/toastr/)** +* **[Noty](/library/noty/)** +* **[Notyf](/library/notyf/)** +* **[Sweet Alert](/library/sweetalert/)** + +--- + +{% include _usage.md %} + +--- + +## Configuration + +As optional, if you want to modify the default configuration, you can publish the configuration file: + +```bash +php bin/console flasher:install +``` + +The configuration file will be located at `config/packages/flasher.yaml` and will have the following content: + +```yaml +# config/packages/flasher.yaml + +flasher: + # Default notification library (e.g., 'flasher', 'toastr', 'noty', etc.) + default: flasher + + # Path to the main JavaScript file of PHPFlasher + main_script: '/vendor/flasher/flasher.min.js' + + # Path to the stylesheets for PHPFlasher notifications + styles: + - '/vendor/flasher/flasher.min.css' + + # Enable translation of PHPFlasher messages using Symfony's service + translate: true + + # Automatically inject PHPFlasher assets in HTML response + inject_assets: true + + # Map Symfony session keys to PHPFlasher notification types + flash_bag: + success: ['success'] + error: ['error', 'danger'] + warning: ['warning', 'alarm'] + info: ['info', 'notice', 'alert'] + + # Criteria to filter displayed notifications (limit, types) + filter: + # Limit number of displayed notifications + limit: 5 +``` + +--- + +## Presets + +You can create a preset for a custom notification that you want to reuse in multiple places by adding a presets entry in the configuration file. + +> You can think of a preset as a pre-defined message that you can use in multiple locations.
+ +For example, you can create a preset named `entity_saved` in the configuration file and then use + +{% assign id = '#/ symfony preset' %} +{% assign type = 'success' %} +{% assign message = 'Entity saved successfully' %} +{% assign title = 'Entity saved' %} +{% assign options = '{}' %} +{% include example.html %} + +```yaml +# config/packages/flasher.yaml + +flasher: + presets: + entity_saved: + type: '{{ type }}' + message: '{{ message }}' + title: '{{ title }}' +``` + +To use the preset, you can call the `preset()` method and pass the name of the preset as the first argument: + +```php +{{ id }} + +class BookController +{ + public function save() + { + flash()->preset('entity_saved'); +``` + +This is equivalent to: + +```php +class BookController +{ + public function save() + { + flash()->{{ type }}('{{ message }}', '{{ title }}'); +``` + +

Variables

+ +Presets can also contain variables that can be substituted by using the translation system. Take the following example where you have a preset showing a personalised welcome message to the user. + +```yaml +# config/packages/flasher.yaml + +flasher: + presets: + hello_user: + type: {{ type }} + message: welcome_back_user +``` + +In the translations file you can define `welcome_back_user` with the message containing the variable `:username`. + +```yaml +# translations/flasher.en.yaml + +welcome_back_user: Welcome back :username +``` + +If you want to substitute the `:username` in the above translation with a username in the controller, you can achieve this by passing an array of values to be substituted as the second argument. + +```php +class BookController +{ + public function save() + { + $username = 'John Doe'; + + flash()->preset('hello_user', ['username' => $username]); +``` + +--- + +--- + +## RTL support + +{% PHPFlasher %} makes it easy to incorporate **right-to-left** languages like `Arabic` or `Hebrew`. +it automatically detects the text direction and handles the necessary adjustments for you. + +Simply make sure the translation service is enabled and let {% PHPFlasher %} handle the rest. + +{% assign id = '#/ phpflasher rtl' %} +{% assign type = 'success' %} +{% assign message = 'تمت العملية بنجاح.' %} +{% assign title = 'تهانينا' %} +{% assign options = '{"rtl": true}' %} +{% include example.html %} + +```php +{{ id }} + +flash() + ->translate('ar') + ->{{ type }}('Your request was processed successfully.', 'Congratulations!'); +``` + +--- + +## Translation + +{% PHPFlasher %} allows you to translate your notification `messages`, `presets`, it comes with `Arabic`, `English` and `French` translations out of the box, but you can easily add your own translations. + +For example, if you need to override the `English` translation strings for {% PHPFlasher %}, you can create a language file at the following location: +**`translations/flasher.en.yaml`**. + +In this file, you should **only** define the translation strings you want to override. Any translation strings that you don't override will still be loaded from {% PHPFlasher %}'s original language files. + +Here is a list of the default translation keys for {% PHPFlasher %}: + +```yaml +# translations/flasher.ar.yaml + +success: 'نجاح' +error: 'خطأ' +warning: 'تحذير' +info: 'معلومة' + +The resource was created: 'تم إنشاء :resource' +The resource was updated: 'تم تعديل :resource' +The resource was saved: 'تم حفظ :resource' +The resource was deleted: 'تم حذف :resource' + +resource: 'الملف' +``` + +```yaml +# translations/flasher.en.yaml + +success: 'Success' +error: 'Error' +warning: 'Warning' +info: 'Info' + +The resource was created: 'The :resource was created' +The resource was updated: 'The :resource was updated' +The resource was saved: 'The :resource was saved' +The resource was deleted: 'The :resource was deleted' + +resource: 'resource' +``` + +```yaml +# translations/flasher.fr.yaml + +success: 'Succès' +error: 'Erreur' +warning: 'Avertissement' +info: 'Information' + +The resource was created: 'La ressource :resource a été ajoutée' +The resource was updated: 'La ressource :resource a été mise à jour' +The resource was saved: 'La ressource :resource a été enregistrée' +The resource was deleted: 'La ressource :resource a été supprimée' + +resource: '' +``` + +{% assign id = '#/ symfony arabic translations' %} +{% assign successMessage = 'تم إنشاء الملف' %} +{% assign errorMessage = 'حدث خطأ أثناء إرسال طلبك.' %} +{% assign warningMessage = 'يجب إكمال جميع الحقول الإلزامية قبل إرسال النموذج' %} +{% assign infoMessage = 'سيتم تحديث هذه الصفحة في غضون 10 دقائق.' %} + + + +```php +{{ id }} + +// Translate the flash message using the PHPFlasher translation files +flash()->success('The resource was created'); + +flash()->error('{{ errorMessage }}'); +flash()->warning('{{ warningMessage }}'); +flash()->info('{{ infoMessage }}'); +``` + +{% assign id = '#/ symfony french translations' %} +{% assign successMessage = "La ressource a été ajoutée" %} +{% assign errorMessage = "Une erreur s’est produite lors de l’envoi de votre demande." %} +{% assign warningMessage = "Vous devez remplir tous les champs obligatoires avant de soumettre le formulaire." %} +{% assign infoMessage = "Cette page sera mise à jour dans 10 minutes."%} + + + +```php +{{ id }} + +// Translate the flash message using the PHPFlasher translation files +flash()->success('The resource was created'); + +flash()->error('{{ errorMessage }}'); +flash()->warning('{{ warningMessage }}'); +flash()->info('{{ infoMessage }}'); +``` diff --git a/docs/postcss.config.js b/docs/postcss.config.js new file mode 100644 index 00000000..5ec7654c --- /dev/null +++ b/docs/postcss.config.js @@ -0,0 +1,9 @@ +module.exports = { + plugins: [ + require('postcss-import'), + require('tailwindcss'), + require('tailwindcss/nesting'), + require('cssnano')(), + require('autoprefixer'), + ], +} diff --git a/docs/static/css/fontawesome.css b/docs/static/css/fontawesome.css new file mode 100644 index 00000000..32543d93 --- /dev/null +++ b/docs/static/css/fontawesome.css @@ -0,0 +1 @@ +.fa {font-family: var(--fa-style-family, "Font Awesome 6 Pro");font-weight: var(--fa-style, 900);}.fa, .fas, .fa-solid, .far, .fa-regular, .fal, .fa-light, .fat, .fa-thin, .fad, .fa-duotone, .fab, .fa-brands {-moz-osx-font-smoothing: grayscale;-webkit-font-smoothing: antialiased;display: var(--fa-display, inline-block);font-style: normal;font-variant: normal;line-height: 1;text-rendering: auto;}.fa-1x {font-size: 1em;}.fa-2x {font-size: 2em;}.fa-3x {font-size: 3em;}.fa-4x {font-size: 4em;}.fa-5x {font-size: 5em;}.fa-6x {font-size: 6em;}.fa-7x {font-size: 7em;}.fa-8x {font-size: 8em;}.fa-9x {font-size: 9em;}.fa-10x {font-size: 10em;}.fa-2xs {font-size: 0.625em;line-height: 0.1em;vertical-align: 0.225em;}.fa-xs {font-size: 0.75em;line-height: 0.08333em;vertical-align: 0.125em;}.fa-sm {font-size: 0.875em;line-height: 0.07143em;vertical-align: 0.05357em;}.fa-lg {font-size: 1.25em;line-height: 0.05em;vertical-align: -0.075em;}.fa-xl {font-size: 1.5em;line-height: 0.04167em;vertical-align: -0.125em;}.fa-2xl {font-size: 2em;line-height: 0.03125em;vertical-align: -0.1875em;}.fa-fw {text-align: center;width: 1.25em;}.fa-ul {list-style-type: none;margin-left: var(--fa-li-margin, 2.5em);padding-left: 0;}.fa-ul > li {position: relative;}.fa-li {left: calc(var(--fa-li-width, 2em) * -1);position: absolute;text-align: center;width: var(--fa-li-width, 2em);line-height: inherit;}.fa-border {border-color: var(--fa-border-color, #eee);border-radius: var(--fa-border-radius, 0.1em);border-style: var(--fa-border-style, solid);border-width: var(--fa-border-width, 0.08em);padding: var(--fa-border-padding, 0.2em 0.25em 0.15em);}.fa-pull-left {float: left;margin-right: var(--fa-pull-margin, 0.3em);}.fa-pull-right {float: right;margin-left: var(--fa-pull-margin, 0.3em);}.fa-beat {-webkit-animation-name: fa-beat;animation-name: fa-beat;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);animation-timing-function: var(--fa-animation-timing, ease-in-out);}.fa-bounce {-webkit-animation-name: fa-bounce;animation-name: fa-bounce;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));}.fa-fade {-webkit-animation-name: fa-fade;animation-name: fa-fade;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));}.fa-beat-fade {-webkit-animation-name: fa-beat-fade;animation-name: fa-beat-fade;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));}.fa-flip {-webkit-animation-name: fa-flip;animation-name: fa-flip;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, ease-in-out);animation-timing-function: var(--fa-animation-timing, ease-in-out);}.fa-shake {-webkit-animation-name: fa-shake;animation-name: fa-shake;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, linear);animation-timing-function: var(--fa-animation-timing, linear);}.fa-spin {-webkit-animation-name: fa-spin;animation-name: fa-spin;-webkit-animation-delay: var(--fa-animation-delay, 0);animation-delay: var(--fa-animation-delay, 0);-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 2s);animation-duration: var(--fa-animation-duration, 2s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, linear);animation-timing-function: var(--fa-animation-timing, linear);}.fa-spin-reverse {--fa-animation-direction: reverse;}.fa-pulse, .fa-spin-pulse {-webkit-animation-name: fa-spin;animation-name: fa-spin;-webkit-animation-direction: var(--fa-animation-direction, normal);animation-direction: var(--fa-animation-direction, normal);-webkit-animation-duration: var(--fa-animation-duration, 1s);animation-duration: var(--fa-animation-duration, 1s);-webkit-animation-iteration-count: var(--fa-animation-iteration-count, infinite);animation-iteration-count: var(--fa-animation-iteration-count, infinite);-webkit-animation-timing-function: var(--fa-animation-timing, steps(8));animation-timing-function: var(--fa-animation-timing, steps(8));}@media (prefers-reduced-motion: reduce) {.fa-beat, .fa-bounce, .fa-fade, .fa-beat-fade, .fa-flip, .fa-pulse, .fa-shake, .fa-spin, .fa-spin-pulse {-webkit-animation-delay: -1ms;animation-delay: -1ms;-webkit-animation-duration: 1ms;animation-duration: 1ms;-webkit-animation-iteration-count: 1;animation-iteration-count: 1;transition-delay: 0s;transition-duration: 0s;}}@-webkit-keyframes fa-beat {0%, 90% {-webkit-transform: scale(1);transform: scale(1);}45% {-webkit-transform: scale(var(--fa-beat-scale, 1.25));transform: scale(var(--fa-beat-scale, 1.25));}}@keyframes fa-beat {0%, 90% {-webkit-transform: scale(1);transform: scale(1);}45% {-webkit-transform: scale(var(--fa-beat-scale, 1.25));transform: scale(var(--fa-beat-scale, 1.25));}}@-webkit-keyframes fa-bounce {0% {-webkit-transform: scale(1, 1) translateY(0);transform: scale(1, 1) translateY(0);}10% {-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);}30% {-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));}50% {-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);}57% {-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));}64% {-webkit-transform: scale(1, 1) translateY(0);transform: scale(1, 1) translateY(0);}100% {-webkit-transform: scale(1, 1) translateY(0);transform: scale(1, 1) translateY(0);}}@keyframes fa-bounce {0% {-webkit-transform: scale(1, 1) translateY(0);transform: scale(1, 1) translateY(0);}10% {-webkit-transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);}30% {-webkit-transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));}50% {-webkit-transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);}57% {-webkit-transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));}64% {-webkit-transform: scale(1, 1) translateY(0);transform: scale(1, 1) translateY(0);}100% {-webkit-transform: scale(1, 1) translateY(0);transform: scale(1, 1) translateY(0);}}@-webkit-keyframes fa-fade {50% {opacity: var(--fa-fade-opacity, 0.4);}}@keyframes fa-fade {50% {opacity: var(--fa-fade-opacity, 0.4);}}@-webkit-keyframes fa-beat-fade {0%, 100% {opacity: var(--fa-beat-fade-opacity, 0.4);-webkit-transform: scale(1);transform: scale(1);}50% {opacity: 1;-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));transform: scale(var(--fa-beat-fade-scale, 1.125));}}@keyframes fa-beat-fade {0%, 100% {opacity: var(--fa-beat-fade-opacity, 0.4);-webkit-transform: scale(1);transform: scale(1);}50% {opacity: 1;-webkit-transform: scale(var(--fa-beat-fade-scale, 1.125));transform: scale(var(--fa-beat-fade-scale, 1.125));}}@-webkit-keyframes fa-flip {50% {-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));}}@keyframes fa-flip {50% {-webkit-transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));}}@-webkit-keyframes fa-shake {0% {-webkit-transform: rotate(-15deg);transform: rotate(-15deg);}4% {-webkit-transform: rotate(15deg);transform: rotate(15deg);}8%, 24% {-webkit-transform: rotate(-18deg);transform: rotate(-18deg);}12%, 28% {-webkit-transform: rotate(18deg);transform: rotate(18deg);}16% {-webkit-transform: rotate(-22deg);transform: rotate(-22deg);}20% {-webkit-transform: rotate(22deg);transform: rotate(22deg);}32% {-webkit-transform: rotate(-12deg);transform: rotate(-12deg);}36% {-webkit-transform: rotate(12deg);transform: rotate(12deg);}40%, 100% {-webkit-transform: rotate(0deg);transform: rotate(0deg);}}@keyframes fa-shake {0% {-webkit-transform: rotate(-15deg);transform: rotate(-15deg);}4% {-webkit-transform: rotate(15deg);transform: rotate(15deg);}8%, 24% {-webkit-transform: rotate(-18deg);transform: rotate(-18deg);}12%, 28% {-webkit-transform: rotate(18deg);transform: rotate(18deg);}16% {-webkit-transform: rotate(-22deg);transform: rotate(-22deg);}20% {-webkit-transform: rotate(22deg);transform: rotate(22deg);}32% {-webkit-transform: rotate(-12deg);transform: rotate(-12deg);}36% {-webkit-transform: rotate(12deg);transform: rotate(12deg);}40%, 100% {-webkit-transform: rotate(0deg);transform: rotate(0deg);}}@-webkit-keyframes fa-spin {0% {-webkit-transform: rotate(0deg);transform: rotate(0deg);}100% {-webkit-transform: rotate(360deg);transform: rotate(360deg);}}@keyframes fa-spin {0% {-webkit-transform: rotate(0deg);transform: rotate(0deg);}100% {-webkit-transform: rotate(360deg);transform: rotate(360deg);}}.fa-rotate-90 {-webkit-transform: rotate(90deg);transform: rotate(90deg);}.fa-rotate-180 {-webkit-transform: rotate(180deg);transform: rotate(180deg);}.fa-rotate-270 {-webkit-transform: rotate(270deg);transform: rotate(270deg);}.fa-flip-horizontal {-webkit-transform: scale(-1, 1);transform: scale(-1, 1);}.fa-flip-vertical {-webkit-transform: scale(1, -1);transform: scale(1, -1);}.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {-webkit-transform: scale(-1, -1);transform: scale(-1, -1);}.fa-rotate-by {-webkit-transform: rotate(var(--fa-rotate-angle, none));transform: rotate(var(--fa-rotate-angle, none));}.fa-stack {display: inline-block;height: 2em;line-height: 2em;position: relative;vertical-align: middle;width: 2.5em;}.fa-stack-1x, .fa-stack-2x {left: 0;position: absolute;text-align: center;width: 100%;z-index: var(--fa-stack-z-index, auto);}.fa-stack-1x {line-height: inherit;}.fa-stack-2x {font-size: 2em;}.fa-inverse {color: var(--fa-inverse, #fff);}.fa-0::before {content: "\30";}.fa-1::before {content: "\31";}.fa-2::before {content: "\32";}.fa-3::before {content: "\33";}.fa-4::before {content: "\34";}.fa-5::before {content: "\35";}.fa-6::before {content: "\36";}.fa-7::before {content: "\37";}.fa-8::before {content: "\38";}.fa-9::before {content: "\39";}.fa-00::before {content: "\e467";}.fa-360-degrees::before {content: "\e2dc";}.fa-a::before {content: "\41";}.fa-abacus::before {content: "\f640";}.fa-accent-grave::before {content: "\60";}.fa-acorn::before {content: "\f6ae";}.fa-address-book::before {content: "\f2b9";}.fa-contact-book::before {content: "\f2b9";}.fa-address-card::before {content: "\f2bb";}.fa-contact-card::before {content: "\f2bb";}.fa-vcard::before {content: "\f2bb";}.fa-air-conditioner::before {content: "\f8f4";}.fa-airplay::before {content: "\e089";}.fa-alarm-clock::before {content: "\f34e";}.fa-alarm-exclamation::before {content: "\f843";}.fa-alarm-plus::before {content: "\f844";}.fa-alarm-snooze::before {content: "\f845";}.fa-album::before {content: "\f89f";}.fa-album-circle-plus::before {content: "\e48c";}.fa-album-circle-user::before {content: "\e48d";}.fa-album-collection::before {content: "\f8a0";}.fa-album-collection-circle-plus::before {content: "\e48e";}.fa-album-collection-circle-user::before {content: "\e48f";}.fa-alicorn::before {content: "\f6b0";}.fa-alien::before {content: "\f8f5";}.fa-alien-8bit::before {content: "\f8f6";}.fa-alien-monster::before {content: "\f8f6";}.fa-align-center::before {content: "\f037";}.fa-align-justify::before {content: "\f039";}.fa-align-left::before {content: "\f036";}.fa-align-right::before {content: "\f038";}.fa-align-slash::before {content: "\f846";}.fa-alt::before {content: "\e08a";}.fa-amp-guitar::before {content: "\f8a1";}.fa-ampersand::before {content: "\26";}.fa-anchor::before {content: "\f13d";}.fa-anchor-circle-check::before {content: "\e4aa";}.fa-anchor-circle-exclamation::before {content: "\e4ab";}.fa-anchor-circle-xmark::before {content: "\e4ac";}.fa-anchor-lock::before {content: "\e4ad";}.fa-angel::before {content: "\f779";}.fa-angle::before {content: "\e08c";}.fa-angle-90::before {content: "\e08d";}.fa-angle-down::before {content: "\f107";}.fa-angle-left::before {content: "\f104";}.fa-angle-right::before {content: "\f105";}.fa-angle-up::before {content: "\f106";}.fa-angles-down::before {content: "\f103";}.fa-angle-double-down::before {content: "\f103";}.fa-angles-left::before {content: "\f100";}.fa-angle-double-left::before {content: "\f100";}.fa-angles-right::before {content: "\f101";}.fa-angle-double-right::before {content: "\f101";}.fa-angles-up::before {content: "\f102";}.fa-angle-double-up::before {content: "\f102";}.fa-ankh::before {content: "\f644";}.fa-apartment::before {content: "\e468";}.fa-aperture::before {content: "\e2df";}.fa-apostrophe::before {content: "\27";}.fa-apple-core::before {content: "\e08f";}.fa-apple-whole::before {content: "\f5d1";}.fa-apple-alt::before {content: "\f5d1";}.fa-archway::before {content: "\f557";}.fa-arrow-down::before {content: "\f063";}.fa-arrow-down-1-9::before {content: "\f162";}.fa-sort-numeric-asc::before {content: "\f162";}.fa-sort-numeric-down::before {content: "\f162";}.fa-arrow-down-9-1::before {content: "\f886";}.fa-sort-numeric-desc::before {content: "\f886";}.fa-sort-numeric-down-alt::before {content: "\f886";}.fa-arrow-down-a-z::before {content: "\f15d";}.fa-sort-alpha-asc::before {content: "\f15d";}.fa-sort-alpha-down::before {content: "\f15d";}.fa-arrow-down-arrow-up::before {content: "\f883";}.fa-sort-alt::before {content: "\f883";}.fa-arrow-down-big-small::before {content: "\f88c";}.fa-sort-size-down::before {content: "\f88c";}.fa-arrow-down-from-dotted-line::before {content: "\e090";}.fa-arrow-down-from-line::before {content: "\f345";}.fa-arrow-from-top::before {content: "\f345";}.fa-arrow-down-left::before {content: "\e091";}.fa-arrow-down-left-and-arrow-up-right-to-center::before {content: "\e092";}.fa-arrow-down-long::before {content: "\f175";}.fa-long-arrow-down::before {content: "\f175";}.fa-arrow-down-right::before {content: "\e093";}.fa-arrow-down-short-wide::before {content: "\f884";}.fa-sort-amount-desc::before {content: "\f884";}.fa-sort-amount-down-alt::before {content: "\f884";}.fa-arrow-down-small-big::before {content: "\f88d";}.fa-sort-size-down-alt::before {content: "\f88d";}.fa-arrow-down-square-triangle::before {content: "\f889";}.fa-sort-shapes-down-alt::before {content: "\f889";}.fa-arrow-down-to-arc::before {content: "\e4ae";}.fa-arrow-down-to-bracket::before {content: "\e094";}.fa-arrow-down-to-dotted-line::before {content: "\e095";}.fa-arrow-down-to-line::before {content: "\f33d";}.fa-arrow-to-bottom::before {content: "\f33d";}.fa-arrow-down-to-square::before {content: "\e096";}.fa-arrow-down-triangle-square::before {content: "\f888";}.fa-sort-shapes-down::before {content: "\f888";}.fa-arrow-down-up-across-line::before {content: "\e4af";}.fa-arrow-down-up-lock::before {content: "\e4b0";}.fa-arrow-down-wide-short::before {content: "\f160";}.fa-sort-amount-asc::before {content: "\f160";}.fa-sort-amount-down::before {content: "\f160";}.fa-arrow-down-z-a::before {content: "\f881";}.fa-sort-alpha-desc::before {content: "\f881";}.fa-sort-alpha-down-alt::before {content: "\f881";}.fa-arrow-left::before {content: "\f060";}.fa-arrow-left-from-line::before {content: "\f344";}.fa-arrow-from-right::before {content: "\f344";}.fa-arrow-left-long::before {content: "\f177";}.fa-long-arrow-left::before {content: "\f177";}.fa-arrow-left-long-to-line::before {content: "\e3d4";}.fa-arrow-left-to-line::before {content: "\f33e";}.fa-arrow-to-left::before {content: "\f33e";}.fa-arrow-pointer::before {content: "\f245";}.fa-mouse-pointer::before {content: "\f245";}.fa-arrow-right::before {content: "\f061";}.fa-arrow-right-arrow-left::before {content: "\f0ec";}.fa-exchange::before {content: "\f0ec";}.fa-arrow-right-from-arc::before {content: "\e4b1";}.fa-arrow-right-from-bracket::before {content: "\f08b";}.fa-sign-out::before {content: "\f08b";}.fa-arrow-right-from-line::before {content: "\f343";}.fa-arrow-from-left::before {content: "\f343";}.fa-arrow-right-long::before {content: "\f178";}.fa-long-arrow-right::before {content: "\f178";}.fa-arrow-right-long-to-line::before {content: "\e3d5";}.fa-arrow-right-to-arc::before {content: "\e4b2";}.fa-arrow-right-to-bracket::before {content: "\f090";}.fa-sign-in::before {content: "\f090";}.fa-arrow-right-to-city::before {content: "\e4b3";}.fa-arrow-right-to-line::before {content: "\f340";}.fa-arrow-to-right::before {content: "\f340";}.fa-arrow-rotate-left::before {content: "\f0e2";}.fa-arrow-left-rotate::before {content: "\f0e2";}.fa-arrow-rotate-back::before {content: "\f0e2";}.fa-arrow-rotate-backward::before {content: "\f0e2";}.fa-undo::before {content: "\f0e2";}.fa-arrow-rotate-right::before {content: "\f01e";}.fa-arrow-right-rotate::before {content: "\f01e";}.fa-arrow-rotate-forward::before {content: "\f01e";}.fa-redo::before {content: "\f01e";}.fa-arrow-trend-down::before {content: "\e097";}.fa-arrow-trend-up::before {content: "\e098";}.fa-arrow-turn-down::before {content: "\f149";}.fa-level-down::before {content: "\f149";}.fa-arrow-turn-down-left::before {content: "\e2e1";}.fa-arrow-turn-down-right::before {content: "\e3d6";}.fa-arrow-turn-up::before {content: "\f148";}.fa-level-up::before {content: "\f148";}.fa-arrow-up::before {content: "\f062";}.fa-arrow-up-1-9::before {content: "\f163";}.fa-sort-numeric-up::before {content: "\f163";}.fa-arrow-up-9-1::before {content: "\f887";}.fa-sort-numeric-up-alt::before {content: "\f887";}.fa-arrow-up-a-z::before {content: "\f15e";}.fa-sort-alpha-up::before {content: "\f15e";}.fa-arrow-up-arrow-down::before {content: "\e099";}.fa-sort-up-down::before {content: "\e099";}.fa-arrow-up-big-small::before {content: "\f88e";}.fa-sort-size-up::before {content: "\f88e";}.fa-arrow-up-from-arc::before {content: "\e4b4";}.fa-arrow-up-from-bracket::before {content: "\e09a";}.fa-arrow-up-from-dotted-line::before {content: "\e09b";}.fa-arrow-up-from-ground-water::before {content: "\e4b5";}.fa-arrow-up-from-line::before {content: "\f342";}.fa-arrow-from-bottom::before {content: "\f342";}.fa-arrow-up-from-square::before {content: "\e09c";}.fa-arrow-up-from-water-pump::before {content: "\e4b6";}.fa-arrow-up-left::before {content: "\e09d";}.fa-arrow-up-left-from-circle::before {content: "\e09e";}.fa-arrow-up-long::before {content: "\f176";}.fa-long-arrow-up::before {content: "\f176";}.fa-arrow-up-right::before {content: "\e09f";}.fa-arrow-up-right-and-arrow-down-left-from-center::before {content: "\e0a0";}.fa-arrow-up-right-dots::before {content: "\e4b7";}.fa-arrow-up-right-from-square::before {content: "\f08e";}.fa-external-link::before {content: "\f08e";}.fa-arrow-up-short-wide::before {content: "\f885";}.fa-sort-amount-up-alt::before {content: "\f885";}.fa-arrow-up-small-big::before {content: "\f88f";}.fa-sort-size-up-alt::before {content: "\f88f";}.fa-arrow-up-square-triangle::before {content: "\f88b";}.fa-sort-shapes-up-alt::before {content: "\f88b";}.fa-arrow-up-to-dotted-line::before {content: "\e0a1";}.fa-arrow-up-to-line::before {content: "\f341";}.fa-arrow-to-top::before {content: "\f341";}.fa-arrow-up-triangle-square::before {content: "\f88a";}.fa-sort-shapes-up::before {content: "\f88a";}.fa-arrow-up-wide-short::before {content: "\f161";}.fa-sort-amount-up::before {content: "\f161";}.fa-arrow-up-z-a::before {content: "\f882";}.fa-sort-alpha-up-alt::before {content: "\f882";}.fa-arrows-cross::before {content: "\e0a2";}.fa-arrows-down-to-line::before {content: "\e4b8";}.fa-arrows-down-to-people::before {content: "\e4b9";}.fa-arrows-from-dotted-line::before {content: "\e0a3";}.fa-arrows-from-line::before {content: "\e0a4";}.fa-arrows-left-right::before {content: "\f07e";}.fa-arrows-h::before {content: "\f07e";}.fa-arrows-left-right-to-line::before {content: "\e4ba";}.fa-arrows-maximize::before {content: "\f31d";}.fa-expand-arrows::before {content: "\f31d";}.fa-arrows-minimize::before {content: "\e0a5";}.fa-compress-arrows::before {content: "\e0a5";}.fa-arrows-repeat::before {content: "\f364";}.fa-repeat-alt::before {content: "\f364";}.fa-arrows-repeat-1::before {content: "\f366";}.fa-repeat-1-alt::before {content: "\f366";}.fa-arrows-retweet::before {content: "\f361";}.fa-retweet-alt::before {content: "\f361";}.fa-arrows-rotate::before {content: "\f021";}.fa-refresh::before {content: "\f021";}.fa-sync::before {content: "\f021";}.fa-arrows-spin::before {content: "\e4bb";}.fa-arrows-split-up-and-left::before {content: "\e4bc";}.fa-arrows-to-circle::before {content: "\e4bd";}.fa-arrows-to-dot::before {content: "\e4be";}.fa-arrows-to-dotted-line::before {content: "\e0a6";}.fa-arrows-to-eye::before {content: "\e4bf";}.fa-arrows-to-line::before {content: "\e0a7";}.fa-arrows-turn-right::before {content: "\e4c0";}.fa-arrows-turn-to-dots::before {content: "\e4c1";}.fa-arrows-up-down::before {content: "\f07d";}.fa-arrows-v::before {content: "\f07d";}.fa-arrows-up-down-left-right::before {content: "\f047";}.fa-arrows::before {content: "\f047";}.fa-arrows-up-to-line::before {content: "\e4c2";}.fa-asterisk::before {content: "\2a";}.fa-at::before {content: "\40";}.fa-atom::before {content: "\f5d2";}.fa-atom-simple::before {content: "\f5d3";}.fa-atom-alt::before {content: "\f5d3";}.fa-audio-description::before {content: "\f29e";}.fa-audio-description-slash::before {content: "\e0a8";}.fa-austral-sign::before {content: "\e0a9";}.fa-avocado::before {content: "\e0aa";}.fa-award::before {content: "\f559";}.fa-award-simple::before {content: "\e0ab";}.fa-axe::before {content: "\f6b2";}.fa-axe-battle::before {content: "\f6b3";}.fa-b::before {content: "\42";}.fa-baby::before {content: "\f77c";}.fa-baby-carriage::before {content: "\f77d";}.fa-carriage-baby::before {content: "\f77d";}.fa-backpack::before {content: "\f5d4";}.fa-backward::before {content: "\f04a";}.fa-backward-fast::before {content: "\f049";}.fa-fast-backward::before {content: "\f049";}.fa-backward-step::before {content: "\f048";}.fa-step-backward::before {content: "\f048";}.fa-bacon::before {content: "\f7e5";}.fa-bacteria::before {content: "\e059";}.fa-bacterium::before {content: "\e05a";}.fa-badge::before {content: "\f335";}.fa-badge-check::before {content: "\f336";}.fa-badge-dollar::before {content: "\f645";}.fa-badge-percent::before {content: "\f646";}.fa-badge-sheriff::before {content: "\f8a2";}.fa-badger-honey::before {content: "\f6b4";}.fa-badminton::before {content: "\e33a";}.fa-bag-shopping::before {content: "\f290";}.fa-shopping-bag::before {content: "\f290";}.fa-bagel::before {content: "\e3d7";}.fa-bags-shopping::before {content: "\f847";}.fa-baguette::before {content: "\e3d8";}.fa-bahai::before {content: "\f666";}.fa-baht-sign::before {content: "\e0ac";}.fa-ball-pile::before {content: "\f77e";}.fa-balloon::before {content: "\e2e3";}.fa-balloons::before {content: "\e2e4";}.fa-ballot::before {content: "\f732";}.fa-ballot-check::before {content: "\f733";}.fa-ban::before {content: "\f05e";}.fa-cancel::before {content: "\f05e";}.fa-ban-bug::before {content: "\f7f9";}.fa-debug::before {content: "\f7f9";}.fa-ban-parking::before {content: "\f616";}.fa-parking-circle-slash::before {content: "\f616";}.fa-ban-smoking::before {content: "\f54d";}.fa-smoking-ban::before {content: "\f54d";}.fa-banana::before {content: "\e2e5";}.fa-bandage::before {content: "\f462";}.fa-band-aid::before {content: "\f462";}.fa-bangladeshi-taka-sign::before {content: "\e2e6";}.fa-banjo::before {content: "\f8a3";}.fa-barcode::before {content: "\f02a";}.fa-barcode-read::before {content: "\f464";}.fa-barcode-scan::before {content: "\f465";}.fa-bars::before {content: "\f0c9";}.fa-navicon::before {content: "\f0c9";}.fa-bars-filter::before {content: "\e0ad";}.fa-bars-progress::before {content: "\f828";}.fa-tasks-alt::before {content: "\f828";}.fa-bars-sort::before {content: "\e0ae";}.fa-bars-staggered::before {content: "\f550";}.fa-reorder::before {content: "\f550";}.fa-stream::before {content: "\f550";}.fa-baseball::before {content: "\f433";}.fa-baseball-ball::before {content: "\f433";}.fa-baseball-bat-ball::before {content: "\f432";}.fa-basket-shopping::before {content: "\f291";}.fa-shopping-basket::before {content: "\f291";}.fa-basket-shopping-simple::before {content: "\e0af";}.fa-shopping-basket-alt::before {content: "\e0af";}.fa-basketball::before {content: "\f434";}.fa-basketball-ball::before {content: "\f434";}.fa-basketball-hoop::before {content: "\f435";}.fa-bat::before {content: "\f6b5";}.fa-bath::before {content: "\f2cd";}.fa-bathtub::before {content: "\f2cd";}.fa-battery-bolt::before {content: "\f376";}.fa-battery-empty::before {content: "\f244";}.fa-battery-0::before {content: "\f244";}.fa-battery-exclamation::before {content: "\e0b0";}.fa-battery-full::before {content: "\f240";}.fa-battery::before {content: "\f240";}.fa-battery-5::before {content: "\f240";}.fa-battery-half::before {content: "\f242";}.fa-battery-3::before {content: "\f242";}.fa-battery-low::before {content: "\e0b1";}.fa-battery-1::before {content: "\e0b1";}.fa-battery-quarter::before {content: "\f243";}.fa-battery-2::before {content: "\f243";}.fa-battery-slash::before {content: "\f377";}.fa-battery-three-quarters::before {content: "\f241";}.fa-battery-4::before {content: "\f241";}.fa-bed::before {content: "\f236";}.fa-bed-bunk::before {content: "\f8f8";}.fa-bed-empty::before {content: "\f8f9";}.fa-bed-front::before {content: "\f8f7";}.fa-bed-alt::before {content: "\f8f7";}.fa-bed-pulse::before {content: "\f487";}.fa-procedures::before {content: "\f487";}.fa-bee::before {content: "\e0b2";}.fa-beer-mug::before {content: "\e0b3";}.fa-beer-foam::before {content: "\e0b3";}.fa-beer-mug-empty::before {content: "\f0fc";}.fa-beer::before {content: "\f0fc";}.fa-bell::before {content: "\f0f3";}.fa-bell-concierge::before {content: "\f562";}.fa-concierge-bell::before {content: "\f562";}.fa-bell-exclamation::before {content: "\f848";}.fa-bell-on::before {content: "\f8fa";}.fa-bell-plus::before {content: "\f849";}.fa-bell-school::before {content: "\f5d5";}.fa-bell-school-slash::before {content: "\f5d6";}.fa-bell-slash::before {content: "\f1f6";}.fa-bells::before {content: "\f77f";}.fa-bench-tree::before {content: "\e2e7";}.fa-bezier-curve::before {content: "\f55b";}.fa-bicycle::before {content: "\f206";}.fa-binary::before {content: "\e33b";}.fa-binary-circle-check::before {content: "\e33c";}.fa-binary-lock::before {content: "\e33d";}.fa-binary-slash::before {content: "\e33e";}.fa-binoculars::before {content: "\f1e5";}.fa-biohazard::before {content: "\f780";}.fa-bird::before {content: "\e469";}.fa-bitcoin-sign::before {content: "\e0b4";}.fa-blanket::before {content: "\f498";}.fa-blanket-fire::before {content: "\e3da";}.fa-blender::before {content: "\f517";}.fa-blender-phone::before {content: "\f6b6";}.fa-blinds::before {content: "\f8fb";}.fa-blinds-open::before {content: "\f8fc";}.fa-blinds-raised::before {content: "\f8fd";}.fa-block::before {content: "\e46a";}.fa-block-brick::before {content: "\e3db";}.fa-wall-brick::before {content: "\e3db";}.fa-block-brick-fire::before {content: "\e3dc";}.fa-firewall::before {content: "\e3dc";}.fa-block-question::before {content: "\e3dd";}.fa-block-quote::before {content: "\e0b5";}.fa-blog::before {content: "\f781";}.fa-blueberries::before {content: "\e2e8";}.fa-bold::before {content: "\f032";}.fa-bolt::before {content: "\f0e7";}.fa-zap::before {content: "\f0e7";}.fa-bolt-auto::before {content: "\e0b6";}.fa-bolt-lightning::before {content: "\e0b7";}.fa-bolt-slash::before {content: "\e0b8";}.fa-bomb::before {content: "\f1e2";}.fa-bone::before {content: "\f5d7";}.fa-bone-break::before {content: "\f5d8";}.fa-bong::before {content: "\f55c";}.fa-book::before {content: "\f02d";}.fa-book-arrow-right::before {content: "\e0b9";}.fa-book-arrow-up::before {content: "\e0ba";}.fa-book-atlas::before {content: "\f558";}.fa-atlas::before {content: "\f558";}.fa-book-bible::before {content: "\f647";}.fa-bible::before {content: "\f647";}.fa-book-blank::before {content: "\f5d9";}.fa-book-alt::before {content: "\f5d9";}.fa-book-bookmark::before {content: "\e0bb";}.fa-book-circle-arrow-right::before {content: "\e0bc";}.fa-book-circle-arrow-up::before {content: "\e0bd";}.fa-book-copy::before {content: "\e0be";}.fa-book-font::before {content: "\e0bf";}.fa-book-heart::before {content: "\f499";}.fa-book-journal-whills::before {content: "\f66a";}.fa-journal-whills::before {content: "\f66a";}.fa-book-medical::before {content: "\f7e6";}.fa-book-open::before {content: "\f518";}.fa-book-open-cover::before {content: "\e0c0";}.fa-book-open-alt::before {content: "\e0c0";}.fa-book-open-reader::before {content: "\f5da";}.fa-book-reader::before {content: "\f5da";}.fa-book-quran::before {content: "\f687";}.fa-quran::before {content: "\f687";}.fa-book-section::before {content: "\e0c1";}.fa-book-law::before {content: "\e0c1";}.fa-book-skull::before {content: "\f6b7";}.fa-book-dead::before {content: "\f6b7";}.fa-book-sparkles::before {content: "\f6b8";}.fa-book-spells::before {content: "\f6b8";}.fa-book-tanakh::before {content: "\f827";}.fa-tanakh::before {content: "\f827";}.fa-book-user::before {content: "\f7e7";}.fa-bookmark::before {content: "\f02e";}.fa-bookmark-slash::before {content: "\e0c2";}.fa-books::before {content: "\f5db";}.fa-books-medical::before {content: "\f7e8";}.fa-boombox::before {content: "\f8a5";}.fa-boot::before {content: "\f782";}.fa-boot-heeled::before {content: "\e33f";}.fa-booth-curtain::before {content: "\f734";}.fa-border-all::before {content: "\f84c";}.fa-border-bottom::before {content: "\f84d";}.fa-border-bottom-right::before {content: "\f854";}.fa-border-style-alt::before {content: "\f854";}.fa-border-center-h::before {content: "\f89c";}.fa-border-center-v::before {content: "\f89d";}.fa-border-inner::before {content: "\f84e";}.fa-border-left::before {content: "\f84f";}.fa-border-none::before {content: "\f850";}.fa-border-outer::before {content: "\f851";}.fa-border-right::before {content: "\f852";}.fa-border-top::before {content: "\f855";}.fa-border-top-left::before {content: "\f853";}.fa-border-style::before {content: "\f853";}.fa-bore-hole::before {content: "\e4c3";}.fa-bottle-droplet::before {content: "\e4c4";}.fa-bottle-water::before {content: "\e4c5";}.fa-bow-arrow::before {content: "\f6b9";}.fa-bowl-chopsticks::before {content: "\e2e9";}.fa-bowl-chopsticks-noodles::before {content: "\e2ea";}.fa-bowl-food::before {content: "\e4c6";}.fa-bowl-hot::before {content: "\f823";}.fa-soup::before {content: "\f823";}.fa-bowl-rice::before {content: "\e2eb";}.fa-bowl-scoop::before {content: "\e3de";}.fa-bowl-shaved-ice::before {content: "\e3de";}.fa-bowl-scoops::before {content: "\e3df";}.fa-bowl-soft-serve::before {content: "\e46b";}.fa-bowl-spoon::before {content: "\e3e0";}.fa-bowling-ball::before {content: "\f436";}.fa-bowling-ball-pin::before {content: "\e0c3";}.fa-bowling-pins::before {content: "\f437";}.fa-box::before {content: "\f466";}.fa-box-archive::before {content: "\f187";}.fa-archive::before {content: "\f187";}.fa-box-ballot::before {content: "\f735";}.fa-box-check::before {content: "\f467";}.fa-box-circle-check::before {content: "\e0c4";}.fa-box-dollar::before {content: "\f4a0";}.fa-box-usd::before {content: "\f4a0";}.fa-box-heart::before {content: "\f49d";}.fa-box-open::before {content: "\f49e";}.fa-box-open-full::before {content: "\f49c";}.fa-box-full::before {content: "\f49c";}.fa-box-taped::before {content: "\f49a";}.fa-box-alt::before {content: "\f49a";}.fa-box-tissue::before {content: "\e05b";}.fa-boxes-packing::before {content: "\e4c7";}.fa-boxes-stacked::before {content: "\f468";}.fa-boxes::before {content: "\f468";}.fa-boxes-alt::before {content: "\f468";}.fa-boxing-glove::before {content: "\f438";}.fa-glove-boxing::before {content: "\f438";}.fa-bracket-curly::before {content: "\7b";}.fa-bracket-curly-left::before {content: "\7b";}.fa-bracket-curly-right::before {content: "\7d";}.fa-bracket-round::before {content: "\28";}.fa-parenthesis::before {content: "\28";}.fa-bracket-round-right::before {content: "\29";}.fa-bracket-square::before {content: "\5b";}.fa-bracket::before {content: "\5b";}.fa-bracket-left::before {content: "\5b";}.fa-bracket-square-right::before {content: "\5d";}.fa-brackets-curly::before {content: "\f7ea";}.fa-brackets-round::before {content: "\e0c5";}.fa-parentheses::before {content: "\e0c5";}.fa-brackets-square::before {content: "\f7e9";}.fa-brackets::before {content: "\f7e9";}.fa-braille::before {content: "\f2a1";}.fa-brain::before {content: "\f5dc";}.fa-brain-arrow-curved-right::before {content: "\f677";}.fa-mind-share::before {content: "\f677";}.fa-brain-circuit::before {content: "\e0c6";}.fa-brake-warning::before {content: "\e0c7";}.fa-brazilian-real-sign::before {content: "\e46c";}.fa-bread-loaf::before {content: "\f7eb";}.fa-bread-slice::before {content: "\f7ec";}.fa-bread-slice-butter::before {content: "\e3e1";}.fa-bridge::before {content: "\e4c8";}.fa-bridge-circle-check::before {content: "\e4c9";}.fa-bridge-circle-exclamation::before {content: "\e4ca";}.fa-bridge-circle-xmark::before {content: "\e4cb";}.fa-bridge-lock::before {content: "\e4cc";}.fa-bridge-suspension::before {content: "\e4cd";}.fa-bridge-water::before {content: "\e4ce";}.fa-briefcase::before {content: "\f0b1";}.fa-briefcase-arrow-right::before {content: "\e2f2";}.fa-briefcase-blank::before {content: "\e0c8";}.fa-briefcase-medical::before {content: "\f469";}.fa-brightness::before {content: "\e0c9";}.fa-brightness-low::before {content: "\e0ca";}.fa-bring-forward::before {content: "\f856";}.fa-bring-front::before {content: "\f857";}.fa-broccoli::before {content: "\e3e2";}.fa-broom::before {content: "\f51a";}.fa-broom-ball::before {content: "\f458";}.fa-quidditch::before {content: "\f458";}.fa-quidditch-broom-ball::before {content: "\f458";}.fa-browser::before {content: "\f37e";}.fa-browsers::before {content: "\e0cb";}.fa-brush::before {content: "\f55d";}.fa-bucket::before {content: "\e4cf";}.fa-bug::before {content: "\f188";}.fa-bug-slash::before {content: "\e490";}.fa-bugs::before {content: "\e4d0";}.fa-building::before {content: "\f1ad";}.fa-building-circle-arrow-right::before {content: "\e4d1";}.fa-building-circle-check::before {content: "\e4d2";}.fa-building-circle-exclamation::before {content: "\e4d3";}.fa-building-circle-xmark::before {content: "\e4d4";}.fa-building-columns::before {content: "\f19c";}.fa-bank::before {content: "\f19c";}.fa-institution::before {content: "\f19c";}.fa-museum::before {content: "\f19c";}.fa-university::before {content: "\f19c";}.fa-building-flag::before {content: "\e4d5";}.fa-building-lock::before {content: "\e4d6";}.fa-building-ngo::before {content: "\e4d7";}.fa-building-shield::before {content: "\e4d8";}.fa-building-un::before {content: "\e4d9";}.fa-building-user::before {content: "\e4da";}.fa-building-wheat::before {content: "\e4db";}.fa-buildings::before {content: "\e0cc";}.fa-bullhorn::before {content: "\f0a1";}.fa-bullseye::before {content: "\f140";}.fa-bullseye-arrow::before {content: "\f648";}.fa-bullseye-pointer::before {content: "\f649";}.fa-burger::before {content: "\f805";}.fa-hamburger::before {content: "\f805";}.fa-burger-cheese::before {content: "\f7f1";}.fa-cheeseburger::before {content: "\f7f1";}.fa-burger-fries::before {content: "\e0cd";}.fa-burger-glass::before {content: "\e0ce";}.fa-burger-lettuce::before {content: "\e3e3";}.fa-burger-soda::before {content: "\f858";}.fa-burrito::before {content: "\f7ed";}.fa-burst::before {content: "\e4dc";}.fa-bus::before {content: "\f207";}.fa-bus-school::before {content: "\f5dd";}.fa-bus-simple::before {content: "\f55e";}.fa-bus-alt::before {content: "\f55e";}.fa-business-time::before {content: "\f64a";}.fa-briefcase-clock::before {content: "\f64a";}.fa-butter::before {content: "\e3e4";}.fa-c::before {content: "\43";}.fa-cabin::before {content: "\e46d";}.fa-cabinet-filing::before {content: "\f64b";}.fa-cable-car::before {content: "\e0cf";}.fa-cactus::before {content: "\f8a7";}.fa-cake-candles::before {content: "\f1fd";}.fa-birthday-cake::before {content: "\f1fd";}.fa-cake::before {content: "\f1fd";}.fa-cake-slice::before {content: "\e3e5";}.fa-shortcake::before {content: "\e3e5";}.fa-calculator::before {content: "\f1ec";}.fa-calculator-simple::before {content: "\f64c";}.fa-calculator-alt::before {content: "\f64c";}.fa-calendar::before {content: "\f133";}.fa-calendar-arrow-down::before {content: "\e0d0";}.fa-calendar-download::before {content: "\e0d0";}.fa-calendar-arrow-up::before {content: "\e0d1";}.fa-calendar-upload::before {content: "\e0d1";}.fa-calendar-check::before {content: "\f274";}.fa-calendar-circle-exclamation::before {content: "\e46e";}.fa-calendar-circle-minus::before {content: "\e46f";}.fa-calendar-circle-plus::before {content: "\e470";}.fa-calendar-circle-user::before {content: "\e471";}.fa-calendar-clock::before {content: "\e0d2";}.fa-calendar-time::before {content: "\e0d2";}.fa-calendar-day::before {content: "\f783";}.fa-calendar-days::before {content: "\f073";}.fa-calendar-alt::before {content: "\f073";}.fa-calendar-exclamation::before {content: "\f334";}.fa-calendar-heart::before {content: "\e0d3";}.fa-calendar-image::before {content: "\e0d4";}.fa-calendar-lines::before {content: "\e0d5";}.fa-calendar-note::before {content: "\e0d5";}.fa-calendar-lines-pen::before {content: "\e472";}.fa-calendar-minus::before {content: "\f272";}.fa-calendar-pen::before {content: "\f333";}.fa-calendar-edit::before {content: "\f333";}.fa-calendar-plus::before {content: "\f271";}.fa-calendar-range::before {content: "\e0d6";}.fa-calendar-star::before {content: "\f736";}.fa-calendar-week::before {content: "\f784";}.fa-calendar-xmark::before {content: "\f273";}.fa-calendar-times::before {content: "\f273";}.fa-calendars::before {content: "\e0d7";}.fa-camcorder::before {content: "\f8a8";}.fa-video-handheld::before {content: "\f8a8";}.fa-camera::before {content: "\f030";}.fa-camera-alt::before {content: "\f030";}.fa-camera-cctv::before {content: "\f8ac";}.fa-cctv::before {content: "\f8ac";}.fa-camera-movie::before {content: "\f8a9";}.fa-camera-polaroid::before {content: "\f8aa";}.fa-camera-retro::before {content: "\f083";}.fa-camera-rotate::before {content: "\e0d8";}.fa-camera-security::before {content: "\f8fe";}.fa-camera-home::before {content: "\f8fe";}.fa-camera-slash::before {content: "\e0d9";}.fa-camera-viewfinder::before {content: "\e0da";}.fa-screenshot::before {content: "\e0da";}.fa-camera-web::before {content: "\f832";}.fa-webcam::before {content: "\f832";}.fa-camera-web-slash::before {content: "\f833";}.fa-webcam-slash::before {content: "\f833";}.fa-campfire::before {content: "\f6ba";}.fa-campground::before {content: "\f6bb";}.fa-can-food::before {content: "\e3e6";}.fa-candle-holder::before {content: "\f6bc";}.fa-candy::before {content: "\e3e7";}.fa-candy-bar::before {content: "\e3e8";}.fa-chocolate-bar::before {content: "\e3e8";}.fa-candy-cane::before {content: "\f786";}.fa-candy-corn::before {content: "\f6bd";}.fa-cannabis::before {content: "\f55f";}.fa-capsules::before {content: "\f46b";}.fa-car::before {content: "\f1b9";}.fa-automobile::before {content: "\f1b9";}.fa-car-battery::before {content: "\f5df";}.fa-battery-car::before {content: "\f5df";}.fa-car-bolt::before {content: "\e341";}.fa-car-building::before {content: "\f859";}.fa-car-bump::before {content: "\f5e0";}.fa-car-burst::before {content: "\f5e1";}.fa-car-crash::before {content: "\f5e1";}.fa-car-bus::before {content: "\f85a";}.fa-car-circle-bolt::before {content: "\e342";}.fa-car-garage::before {content: "\f5e2";}.fa-car-mirrors::before {content: "\e343";}.fa-car-on::before {content: "\e4dd";}.fa-car-rear::before {content: "\f5de";}.fa-car-alt::before {content: "\f5de";}.fa-car-side::before {content: "\f5e4";}.fa-car-side-bolt::before {content: "\e344";}.fa-car-tilt::before {content: "\f5e5";}.fa-car-tunnel::before {content: "\e4de";}.fa-car-wash::before {content: "\f5e6";}.fa-car-wrench::before {content: "\f5e3";}.fa-car-mechanic::before {content: "\f5e3";}.fa-caravan::before {content: "\f8ff";}.fa-caravan-simple::before {content: "\e000";}.fa-caravan-alt::before {content: "\e000";}.fa-card-club::before {content: "\e3e9";}.fa-card-diamond::before {content: "\e3ea";}.fa-card-heart::before {content: "\e3eb";}.fa-card-spade::before {content: "\e3ec";}.fa-cards::before {content: "\e3ed";}.fa-cards-blank::before {content: "\e4df";}.fa-caret-down::before {content: "\f0d7";}.fa-caret-left::before {content: "\f0d9";}.fa-caret-right::before {content: "\f0da";}.fa-caret-up::before {content: "\f0d8";}.fa-carrot::before {content: "\f787";}.fa-cars::before {content: "\f85b";}.fa-cart-arrow-down::before {content: "\f218";}.fa-cart-arrow-up::before {content: "\e3ee";}.fa-cart-circle-arrow-down::before {content: "\e3ef";}.fa-cart-circle-arrow-up::before {content: "\e3f0";}.fa-cart-circle-check::before {content: "\e3f1";}.fa-cart-circle-exclamation::before {content: "\e3f2";}.fa-cart-circle-plus::before {content: "\e3f3";}.fa-cart-circle-xmark::before {content: "\e3f4";}.fa-cart-flatbed::before {content: "\f474";}.fa-dolly-flatbed::before {content: "\f474";}.fa-cart-flatbed-boxes::before {content: "\f475";}.fa-dolly-flatbed-alt::before {content: "\f475";}.fa-cart-flatbed-empty::before {content: "\f476";}.fa-dolly-flatbed-empty::before {content: "\f476";}.fa-cart-flatbed-suitcase::before {content: "\f59d";}.fa-luggage-cart::before {content: "\f59d";}.fa-cart-minus::before {content: "\e0db";}.fa-cart-plus::before {content: "\f217";}.fa-cart-shopping::before {content: "\f07a";}.fa-shopping-cart::before {content: "\f07a";}.fa-cart-shopping-fast::before {content: "\e0dc";}.fa-cart-xmark::before {content: "\e0dd";}.fa-cash-register::before {content: "\f788";}.fa-cassette-betamax::before {content: "\f8a4";}.fa-betamax::before {content: "\f8a4";}.fa-cassette-tape::before {content: "\f8ab";}.fa-cassette-vhs::before {content: "\f8ec";}.fa-vhs::before {content: "\f8ec";}.fa-castle::before {content: "\e0de";}.fa-cat::before {content: "\f6be";}.fa-cat-space::before {content: "\e001";}.fa-cauldron::before {content: "\f6bf";}.fa-cedi-sign::before {content: "\e0df";}.fa-cent-sign::before {content: "\e3f5";}.fa-certificate::before {content: "\f0a3";}.fa-chair::before {content: "\f6c0";}.fa-chair-office::before {content: "\f6c1";}.fa-chalkboard::before {content: "\f51b";}.fa-blackboard::before {content: "\f51b";}.fa-chalkboard-user::before {content: "\f51c";}.fa-chalkboard-teacher::before {content: "\f51c";}.fa-champagne-glass::before {content: "\f79e";}.fa-glass-champagne::before {content: "\f79e";}.fa-champagne-glasses::before {content: "\f79f";}.fa-glass-cheers::before {content: "\f79f";}.fa-charging-station::before {content: "\f5e7";}.fa-chart-area::before {content: "\f1fe";}.fa-area-chart::before {content: "\f1fe";}.fa-chart-bar::before {content: "\f080";}.fa-bar-chart::before {content: "\f080";}.fa-chart-bullet::before {content: "\e0e1";}.fa-chart-candlestick::before {content: "\e0e2";}.fa-chart-column::before {content: "\e0e3";}.fa-chart-gantt::before {content: "\e0e4";}.fa-chart-line::before {content: "\f201";}.fa-line-chart::before {content: "\f201";}.fa-chart-line-down::before {content: "\f64d";}.fa-chart-line-up::before {content: "\e0e5";}.fa-chart-mixed::before {content: "\f643";}.fa-analytics::before {content: "\f643";}.fa-chart-network::before {content: "\f78a";}.fa-chart-pie::before {content: "\f200";}.fa-pie-chart::before {content: "\f200";}.fa-chart-pie-simple::before {content: "\f64e";}.fa-chart-pie-alt::before {content: "\f64e";}.fa-chart-pyramid::before {content: "\e0e6";}.fa-chart-radar::before {content: "\e0e7";}.fa-chart-scatter::before {content: "\f7ee";}.fa-chart-scatter-3d::before {content: "\e0e8";}.fa-chart-scatter-bubble::before {content: "\e0e9";}.fa-chart-simple::before {content: "\e473";}.fa-chart-simple-horizontal::before {content: "\e474";}.fa-chart-tree-map::before {content: "\e0ea";}.fa-chart-user::before {content: "\f6a3";}.fa-user-chart::before {content: "\f6a3";}.fa-chart-waterfall::before {content: "\e0eb";}.fa-check::before {content: "\f00c";}.fa-check-double::before {content: "\f560";}.fa-check-to-slot::before {content: "\f772";}.fa-vote-yea::before {content: "\f772";}.fa-cheese::before {content: "\f7ef";}.fa-cheese-swiss::before {content: "\f7f0";}.fa-cherries::before {content: "\e0ec";}.fa-chess::before {content: "\f439";}.fa-chess-bishop::before {content: "\f43a";}.fa-chess-bishop-piece::before {content: "\f43b";}.fa-chess-bishop-alt::before {content: "\f43b";}.fa-chess-board::before {content: "\f43c";}.fa-chess-clock::before {content: "\f43d";}.fa-chess-clock-flip::before {content: "\f43e";}.fa-chess-clock-alt::before {content: "\f43e";}.fa-chess-king::before {content: "\f43f";}.fa-chess-king-piece::before {content: "\f440";}.fa-chess-king-alt::before {content: "\f440";}.fa-chess-knight::before {content: "\f441";}.fa-chess-knight-piece::before {content: "\f442";}.fa-chess-knight-alt::before {content: "\f442";}.fa-chess-pawn::before {content: "\f443";}.fa-chess-pawn-piece::before {content: "\f444";}.fa-chess-pawn-alt::before {content: "\f444";}.fa-chess-queen::before {content: "\f445";}.fa-chess-queen-piece::before {content: "\f446";}.fa-chess-queen-alt::before {content: "\f446";}.fa-chess-rook::before {content: "\f447";}.fa-chess-rook-piece::before {content: "\f448";}.fa-chess-rook-alt::before {content: "\f448";}.fa-chestnut::before {content: "\e3f6";}.fa-chevron-down::before {content: "\f078";}.fa-chevron-left::before {content: "\f053";}.fa-chevron-right::before {content: "\f054";}.fa-chevron-up::before {content: "\f077";}.fa-chevrons-down::before {content: "\f322";}.fa-chevron-double-down::before {content: "\f322";}.fa-chevrons-left::before {content: "\f323";}.fa-chevron-double-left::before {content: "\f323";}.fa-chevrons-right::before {content: "\f324";}.fa-chevron-double-right::before {content: "\f324";}.fa-chevrons-up::before {content: "\f325";}.fa-chevron-double-up::before {content: "\f325";}.fa-child::before {content: "\f1ae";}.fa-child-dress::before {content: "\e59c";}.fa-child-reaching::before {content: "\e59d";}.fa-child-rifle::before {content: "\e4e0";}.fa-children::before {content: "\e4e1";}.fa-chimney::before {content: "\f78b";}.fa-chopsticks::before {content: "\e3f7";}.fa-church::before {content: "\f51d";}.fa-circle::before {content: "\f111";}.fa-circle-0::before {content: "\e0ed";}.fa-circle-1::before {content: "\e0ee";}.fa-circle-2::before {content: "\e0ef";}.fa-circle-3::before {content: "\e0f0";}.fa-circle-4::before {content: "\e0f1";}.fa-circle-5::before {content: "\e0f2";}.fa-circle-6::before {content: "\e0f3";}.fa-circle-7::before {content: "\e0f4";}.fa-circle-8::before {content: "\e0f5";}.fa-circle-9::before {content: "\e0f6";}.fa-circle-a::before {content: "\e0f7";}.fa-circle-ampersand::before {content: "\e0f8";}.fa-circle-arrow-down::before {content: "\f0ab";}.fa-arrow-circle-down::before {content: "\f0ab";}.fa-circle-arrow-down-left::before {content: "\e0f9";}.fa-circle-arrow-down-right::before {content: "\e0fa";}.fa-circle-arrow-left::before {content: "\f0a8";}.fa-arrow-circle-left::before {content: "\f0a8";}.fa-circle-arrow-right::before {content: "\f0a9";}.fa-arrow-circle-right::before {content: "\f0a9";}.fa-circle-arrow-up::before {content: "\f0aa";}.fa-arrow-circle-up::before {content: "\f0aa";}.fa-circle-arrow-up-left::before {content: "\e0fb";}.fa-circle-arrow-up-right::before {content: "\e0fc";}.fa-circle-b::before {content: "\e0fd";}.fa-circle-bolt::before {content: "\e0fe";}.fa-circle-book-open::before {content: "\e0ff";}.fa-book-circle::before {content: "\e0ff";}.fa-circle-bookmark::before {content: "\e100";}.fa-bookmark-circle::before {content: "\e100";}.fa-circle-c::before {content: "\e101";}.fa-circle-calendar::before {content: "\e102";}.fa-calendar-circle::before {content: "\e102";}.fa-circle-camera::before {content: "\e103";}.fa-camera-circle::before {content: "\e103";}.fa-circle-caret-down::before {content: "\f32d";}.fa-caret-circle-down::before {content: "\f32d";}.fa-circle-caret-left::before {content: "\f32e";}.fa-caret-circle-left::before {content: "\f32e";}.fa-circle-caret-right::before {content: "\f330";}.fa-caret-circle-right::before {content: "\f330";}.fa-circle-caret-up::before {content: "\f331";}.fa-caret-circle-up::before {content: "\f331";}.fa-circle-check::before {content: "\f058";}.fa-check-circle::before {content: "\f058";}.fa-circle-chevron-down::before {content: "\f13a";}.fa-chevron-circle-down::before {content: "\f13a";}.fa-circle-chevron-left::before {content: "\f137";}.fa-chevron-circle-left::before {content: "\f137";}.fa-circle-chevron-right::before {content: "\f138";}.fa-chevron-circle-right::before {content: "\f138";}.fa-circle-chevron-up::before {content: "\f139";}.fa-chevron-circle-up::before {content: "\f139";}.fa-circle-d::before {content: "\e104";}.fa-circle-dashed::before {content: "\e105";}.fa-circle-divide::before {content: "\e106";}.fa-circle-dollar::before {content: "\f2e8";}.fa-dollar-circle::before {content: "\f2e8";}.fa-usd-circle::before {content: "\f2e8";}.fa-circle-dollar-to-slot::before {content: "\f4b9";}.fa-donate::before {content: "\f4b9";}.fa-circle-dot::before {content: "\f192";}.fa-dot-circle::before {content: "\f192";}.fa-circle-down::before {content: "\f358";}.fa-arrow-alt-circle-down::before {content: "\f358";}.fa-circle-down-left::before {content: "\e107";}.fa-circle-down-right::before {content: "\e108";}.fa-circle-e::before {content: "\e109";}.fa-circle-ellipsis::before {content: "\e10a";}.fa-circle-ellipsis-vertical::before {content: "\e10b";}.fa-circle-envelope::before {content: "\e10c";}.fa-envelope-circle::before {content: "\e10c";}.fa-circle-exclamation::before {content: "\f06a";}.fa-exclamation-circle::before {content: "\f06a";}.fa-circle-exclamation-check::before {content: "\e10d";}.fa-circle-f::before {content: "\e10e";}.fa-circle-g::before {content: "\e10f";}.fa-circle-h::before {content: "\f47e";}.fa-hospital-symbol::before {content: "\f47e";}.fa-circle-half::before {content: "\e110";}.fa-circle-half-stroke::before {content: "\f042";}.fa-adjust::before {content: "\f042";}.fa-circle-heart::before {content: "\f4c7";}.fa-heart-circle::before {content: "\f4c7";}.fa-circle-i::before {content: "\e111";}.fa-circle-info::before {content: "\f05a";}.fa-info-circle::before {content: "\f05a";}.fa-circle-j::before {content: "\e112";}.fa-circle-k::before {content: "\e113";}.fa-circle-l::before {content: "\e114";}.fa-circle-left::before {content: "\f359";}.fa-arrow-alt-circle-left::before {content: "\f359";}.fa-circle-location-arrow::before {content: "\f602";}.fa-location-circle::before {content: "\f602";}.fa-circle-m::before {content: "\e115";}.fa-circle-microphone::before {content: "\e116";}.fa-microphone-circle::before {content: "\e116";}.fa-circle-microphone-lines::before {content: "\e117";}.fa-microphone-circle-alt::before {content: "\e117";}.fa-circle-minus::before {content: "\f056";}.fa-minus-circle::before {content: "\f056";}.fa-circle-n::before {content: "\e118";}.fa-circle-nodes::before {content: "\e4e2";}.fa-circle-notch::before {content: "\f1ce";}.fa-circle-o::before {content: "\e119";}.fa-circle-p::before {content: "\e11a";}.fa-circle-parking::before {content: "\f615";}.fa-parking-circle::before {content: "\f615";}.fa-circle-pause::before {content: "\f28b";}.fa-pause-circle::before {content: "\f28b";}.fa-circle-phone::before {content: "\e11b";}.fa-phone-circle::before {content: "\e11b";}.fa-circle-phone-flip::before {content: "\e11c";}.fa-phone-circle-alt::before {content: "\e11c";}.fa-circle-phone-hangup::before {content: "\e11d";}.fa-phone-circle-down::before {content: "\e11d";}.fa-circle-play::before {content: "\f144";}.fa-play-circle::before {content: "\f144";}.fa-circle-plus::before {content: "\f055";}.fa-plus-circle::before {content: "\f055";}.fa-circle-q::before {content: "\e11e";}.fa-circle-quarter::before {content: "\e11f";}.fa-circle-quarters::before {content: "\e3f8";}.fa-circle-question::before {content: "\f059";}.fa-question-circle::before {content: "\f059";}.fa-circle-r::before {content: "\e120";}.fa-circle-radiation::before {content: "\f7ba";}.fa-radiation-alt::before {content: "\f7ba";}.fa-circle-right::before {content: "\f35a";}.fa-arrow-alt-circle-right::before {content: "\f35a";}.fa-circle-s::before {content: "\e121";}.fa-circle-small::before {content: "\e122";}.fa-circle-sort::before {content: "\e030";}.fa-sort-circle::before {content: "\e030";}.fa-circle-sort-down::before {content: "\e031";}.fa-sort-circle-down::before {content: "\e031";}.fa-circle-sort-up::before {content: "\e032";}.fa-sort-circle-up::before {content: "\e032";}.fa-circle-star::before {content: "\e123";}.fa-star-circle::before {content: "\e123";}.fa-circle-stop::before {content: "\f28d";}.fa-stop-circle::before {content: "\f28d";}.fa-circle-t::before {content: "\e124";}.fa-circle-three-quarters::before {content: "\e125";}.fa-circle-trash::before {content: "\e126";}.fa-trash-circle::before {content: "\e126";}.fa-circle-u::before {content: "\e127";}.fa-circle-up::before {content: "\f35b";}.fa-arrow-alt-circle-up::before {content: "\f35b";}.fa-circle-up-left::before {content: "\e128";}.fa-circle-up-right::before {content: "\e129";}.fa-circle-user::before {content: "\f2bd";}.fa-user-circle::before {content: "\f2bd";}.fa-circle-v::before {content: "\e12a";}.fa-circle-video::before {content: "\e12b";}.fa-video-circle::before {content: "\e12b";}.fa-circle-w::before {content: "\e12c";}.fa-circle-waveform-lines::before {content: "\e12d";}.fa-waveform-circle::before {content: "\e12d";}.fa-circle-x::before {content: "\e12e";}.fa-circle-xmark::before {content: "\f057";}.fa-times-circle::before {content: "\f057";}.fa-xmark-circle::before {content: "\f057";}.fa-circle-y::before {content: "\e12f";}.fa-circle-z::before {content: "\e130";}.fa-citrus::before {content: "\e2f4";}.fa-citrus-slice::before {content: "\e2f5";}.fa-city::before {content: "\f64f";}.fa-clapperboard::before {content: "\e131";}.fa-clapperboard-play::before {content: "\e132";}.fa-clarinet::before {content: "\f8ad";}.fa-claw-marks::before {content: "\f6c2";}.fa-clipboard::before {content: "\f328";}.fa-clipboard-check::before {content: "\f46c";}.fa-clipboard-list::before {content: "\f46d";}.fa-clipboard-list-check::before {content: "\f737";}.fa-clipboard-medical::before {content: "\e133";}.fa-clipboard-prescription::before {content: "\f5e8";}.fa-clipboard-question::before {content: "\e4e3";}.fa-clipboard-user::before {content: "\f7f3";}.fa-clock::before {content: "\f017";}.fa-clock-four::before {content: "\f017";}.fa-clock-desk::before {content: "\e134";}.fa-clock-eight::before {content: "\e345";}.fa-clock-eight-thirty::before {content: "\e346";}.fa-clock-eleven::before {content: "\e347";}.fa-clock-eleven-thirty::before {content: "\e348";}.fa-clock-five::before {content: "\e349";}.fa-clock-five-thirty::before {content: "\e34a";}.fa-clock-four-thirty::before {content: "\e34b";}.fa-clock-nine::before {content: "\e34c";}.fa-clock-nine-thirty::before {content: "\e34d";}.fa-clock-one::before {content: "\e34e";}.fa-clock-one-thirty::before {content: "\e34f";}.fa-clock-rotate-left::before {content: "\f1da";}.fa-history::before {content: "\f1da";}.fa-clock-seven::before {content: "\e350";}.fa-clock-seven-thirty::before {content: "\e351";}.fa-clock-six::before {content: "\e352";}.fa-clock-six-thirty::before {content: "\e353";}.fa-clock-ten::before {content: "\e354";}.fa-clock-ten-thirty::before {content: "\e355";}.fa-clock-three::before {content: "\e356";}.fa-clock-three-thirty::before {content: "\e357";}.fa-clock-twelve::before {content: "\e358";}.fa-clock-twelve-thirty::before {content: "\e359";}.fa-clock-two::before {content: "\e35a";}.fa-clock-two-thirty::before {content: "\e35b";}.fa-clone::before {content: "\f24d";}.fa-closed-captioning::before {content: "\f20a";}.fa-closed-captioning-slash::before {content: "\e135";}.fa-clothes-hanger::before {content: "\e136";}.fa-cloud::before {content: "\f0c2";}.fa-cloud-arrow-down::before {content: "\f0ed";}.fa-cloud-download::before {content: "\f0ed";}.fa-cloud-download-alt::before {content: "\f0ed";}.fa-cloud-arrow-up::before {content: "\f0ee";}.fa-cloud-upload::before {content: "\f0ee";}.fa-cloud-upload-alt::before {content: "\f0ee";}.fa-cloud-bolt::before {content: "\f76c";}.fa-thunderstorm::before {content: "\f76c";}.fa-cloud-bolt-moon::before {content: "\f76d";}.fa-thunderstorm-moon::before {content: "\f76d";}.fa-cloud-bolt-sun::before {content: "\f76e";}.fa-thunderstorm-sun::before {content: "\f76e";}.fa-cloud-check::before {content: "\e35c";}.fa-cloud-drizzle::before {content: "\f738";}.fa-cloud-exclamation::before {content: "\e491";}.fa-cloud-fog::before {content: "\f74e";}.fa-fog::before {content: "\f74e";}.fa-cloud-hail::before {content: "\f739";}.fa-cloud-hail-mixed::before {content: "\f73a";}.fa-cloud-meatball::before {content: "\f73b";}.fa-cloud-minus::before {content: "\e35d";}.fa-cloud-moon::before {content: "\f6c3";}.fa-cloud-moon-rain::before {content: "\f73c";}.fa-cloud-music::before {content: "\f8ae";}.fa-cloud-plus::before {content: "\e35e";}.fa-cloud-question::before {content: "\e492";}.fa-cloud-rain::before {content: "\f73d";}.fa-cloud-rainbow::before {content: "\f73e";}.fa-cloud-showers::before {content: "\f73f";}.fa-cloud-showers-heavy::before {content: "\f740";}.fa-cloud-showers-water::before {content: "\e4e4";}.fa-cloud-slash::before {content: "\e137";}.fa-cloud-sleet::before {content: "\f741";}.fa-cloud-snow::before {content: "\f742";}.fa-cloud-sun::before {content: "\f6c4";}.fa-cloud-sun-rain::before {content: "\f743";}.fa-cloud-word::before {content: "\e138";}.fa-cloud-xmark::before {content: "\e35f";}.fa-clouds::before {content: "\f744";}.fa-clouds-moon::before {content: "\f745";}.fa-clouds-sun::before {content: "\f746";}.fa-clover::before {content: "\e139";}.fa-club::before {content: "\f327";}.fa-coconut::before {content: "\e2f6";}.fa-code::before {content: "\f121";}.fa-code-branch::before {content: "\f126";}.fa-code-commit::before {content: "\f386";}.fa-code-compare::before {content: "\e13a";}.fa-code-fork::before {content: "\e13b";}.fa-code-merge::before {content: "\f387";}.fa-code-pull-request::before {content: "\e13c";}.fa-code-pull-request-closed::before {content: "\e3f9";}.fa-code-pull-request-draft::before {content: "\e3fa";}.fa-code-simple::before {content: "\e13d";}.fa-coffee-bean::before {content: "\e13e";}.fa-coffee-beans::before {content: "\e13f";}.fa-coffee-pot::before {content: "\e002";}.fa-coffin::before {content: "\f6c6";}.fa-coffin-cross::before {content: "\e051";}.fa-coin::before {content: "\f85c";}.fa-coin-blank::before {content: "\e3fb";}.fa-coin-front::before {content: "\e3fc";}.fa-coin-vertical::before {content: "\e3fd";}.fa-coins::before {content: "\f51e";}.fa-colon::before {content: "\3a";}.fa-colon-sign::before {content: "\e140";}.fa-columns-3::before {content: "\e361";}.fa-comet::before {content: "\e003";}.fa-comma::before {content: "\2c";}.fa-command::before {content: "\e142";}.fa-comment::before {content: "\f075";}.fa-comment-arrow-down::before {content: "\e143";}.fa-comment-arrow-up::before {content: "\e144";}.fa-comment-arrow-up-right::before {content: "\e145";}.fa-comment-captions::before {content: "\e146";}.fa-comment-check::before {content: "\f4ac";}.fa-comment-code::before {content: "\e147";}.fa-comment-dollar::before {content: "\f651";}.fa-comment-dots::before {content: "\f4ad";}.fa-commenting::before {content: "\f4ad";}.fa-comment-exclamation::before {content: "\f4af";}.fa-comment-image::before {content: "\e148";}.fa-comment-lines::before {content: "\f4b0";}.fa-comment-medical::before {content: "\f7f5";}.fa-comment-middle::before {content: "\e149";}.fa-comment-middle-top::before {content: "\e14a";}.fa-comment-minus::before {content: "\f4b1";}.fa-comment-music::before {content: "\f8b0";}.fa-comment-pen::before {content: "\f4ae";}.fa-comment-edit::before {content: "\f4ae";}.fa-comment-plus::before {content: "\f4b2";}.fa-comment-question::before {content: "\e14b";}.fa-comment-quote::before {content: "\e14c";}.fa-comment-slash::before {content: "\f4b3";}.fa-comment-smile::before {content: "\f4b4";}.fa-comment-sms::before {content: "\f7cd";}.fa-sms::before {content: "\f7cd";}.fa-comment-text::before {content: "\e14d";}.fa-comment-xmark::before {content: "\f4b5";}.fa-comment-times::before {content: "\f4b5";}.fa-comments::before {content: "\f086";}.fa-comments-dollar::before {content: "\f653";}.fa-comments-question::before {content: "\e14e";}.fa-comments-question-check::before {content: "\e14f";}.fa-compact-disc::before {content: "\f51f";}.fa-compass::before {content: "\f14e";}.fa-compass-drafting::before {content: "\f568";}.fa-drafting-compass::before {content: "\f568";}.fa-compass-slash::before {content: "\f5e9";}.fa-compress::before {content: "\f066";}.fa-compress-wide::before {content: "\f326";}.fa-computer::before {content: "\e4e5";}.fa-computer-classic::before {content: "\f8b1";}.fa-computer-mouse::before {content: "\f8cc";}.fa-mouse::before {content: "\f8cc";}.fa-computer-mouse-scrollwheel::before {content: "\f8cd";}.fa-mouse-alt::before {content: "\f8cd";}.fa-computer-speaker::before {content: "\f8b2";}.fa-container-storage::before {content: "\f4b7";}.fa-conveyor-belt::before {content: "\f46e";}.fa-conveyor-belt-boxes::before {content: "\f46f";}.fa-conveyor-belt-alt::before {content: "\f46f";}.fa-conveyor-belt-empty::before {content: "\e150";}.fa-cookie::before {content: "\f563";}.fa-cookie-bite::before {content: "\f564";}.fa-copy::before {content: "\f0c5";}.fa-copyright::before {content: "\f1f9";}.fa-corn::before {content: "\f6c7";}.fa-corner::before {content: "\e3fe";}.fa-couch::before {content: "\f4b8";}.fa-cow::before {content: "\f6c8";}.fa-cowbell::before {content: "\f8b3";}.fa-cowbell-circle-plus::before {content: "\f8b4";}.fa-cowbell-more::before {content: "\f8b4";}.fa-crab::before {content: "\e3ff";}.fa-crate-apple::before {content: "\f6b1";}.fa-apple-crate::before {content: "\f6b1";}.fa-crate-empty::before {content: "\e151";}.fa-credit-card::before {content: "\f09d";}.fa-credit-card-alt::before {content: "\f09d";}.fa-credit-card-blank::before {content: "\f389";}.fa-credit-card-front::before {content: "\f38a";}.fa-cricket-bat-ball::before {content: "\f449";}.fa-cricket::before {content: "\f449";}.fa-croissant::before {content: "\f7f6";}.fa-crop::before {content: "\f125";}.fa-crop-simple::before {content: "\f565";}.fa-crop-alt::before {content: "\f565";}.fa-cross::before {content: "\f654";}.fa-crosshairs::before {content: "\f05b";}.fa-crow::before {content: "\f520";}.fa-crown::before {content: "\f521";}.fa-crutch::before {content: "\f7f7";}.fa-crutches::before {content: "\f7f8";}.fa-cruzeiro-sign::before {content: "\e152";}.fa-crystal-ball::before {content: "\e362";}.fa-cube::before {content: "\f1b2";}.fa-cubes::before {content: "\f1b3";}.fa-cubes-stacked::before {content: "\e4e6";}.fa-cucumber::before {content: "\e401";}.fa-cup-straw::before {content: "\e363";}.fa-cup-straw-swoosh::before {content: "\e364";}.fa-cup-togo::before {content: "\f6c5";}.fa-coffee-togo::before {content: "\f6c5";}.fa-cupcake::before {content: "\e402";}.fa-curling-stone::before {content: "\f44a";}.fa-curling::before {content: "\f44a";}.fa-custard::before {content: "\e403";}.fa-d::before {content: "\44";}.fa-dagger::before {content: "\f6cb";}.fa-dash::before {content: "\e404";}.fa-minus-large::before {content: "\e404";}.fa-database::before {content: "\f1c0";}.fa-deer::before {content: "\f78e";}.fa-deer-rudolph::before {content: "\f78f";}.fa-delete-left::before {content: "\f55a";}.fa-backspace::before {content: "\f55a";}.fa-delete-right::before {content: "\e154";}.fa-democrat::before {content: "\f747";}.fa-desktop::before {content: "\f390";}.fa-desktop-alt::before {content: "\f390";}.fa-desktop-arrow-down::before {content: "\e155";}.fa-dharmachakra::before {content: "\f655";}.fa-diagram-cells::before {content: "\e475";}.fa-diagram-lean-canvas::before {content: "\e156";}.fa-diagram-nested::before {content: "\e157";}.fa-diagram-next::before {content: "\e476";}.fa-diagram-predecessor::before {content: "\e477";}.fa-diagram-previous::before {content: "\e478";}.fa-diagram-project::before {content: "\f542";}.fa-project-diagram::before {content: "\f542";}.fa-diagram-sankey::before {content: "\e158";}.fa-diagram-subtask::before {content: "\e479";}.fa-diagram-successor::before {content: "\e47a";}.fa-diagram-venn::before {content: "\e15a";}.fa-dial::before {content: "\e15b";}.fa-dial-med-high::before {content: "\e15b";}.fa-dial-high::before {content: "\e15c";}.fa-dial-low::before {content: "\e15d";}.fa-dial-max::before {content: "\e15e";}.fa-dial-med::before {content: "\e15f";}.fa-dial-med-low::before {content: "\e160";}.fa-dial-min::before {content: "\e161";}.fa-dial-off::before {content: "\e162";}.fa-diamond::before {content: "\f219";}.fa-diamond-exclamation::before {content: "\e405";}.fa-diamond-turn-right::before {content: "\f5eb";}.fa-directions::before {content: "\f5eb";}.fa-dice::before {content: "\f522";}.fa-dice-d10::before {content: "\f6cd";}.fa-dice-d12::before {content: "\f6ce";}.fa-dice-d20::before {content: "\f6cf";}.fa-dice-d4::before {content: "\f6d0";}.fa-dice-d6::before {content: "\f6d1";}.fa-dice-d8::before {content: "\f6d2";}.fa-dice-five::before {content: "\f523";}.fa-dice-four::before {content: "\f524";}.fa-dice-one::before {content: "\f525";}.fa-dice-six::before {content: "\f526";}.fa-dice-three::before {content: "\f527";}.fa-dice-two::before {content: "\f528";}.fa-diploma::before {content: "\f5ea";}.fa-scroll-ribbon::before {content: "\f5ea";}.fa-disc-drive::before {content: "\f8b5";}.fa-disease::before {content: "\f7fa";}.fa-display::before {content: "\e163";}.fa-display-arrow-down::before {content: "\e164";}.fa-display-code::before {content: "\e165";}.fa-desktop-code::before {content: "\e165";}.fa-display-medical::before {content: "\e166";}.fa-desktop-medical::before {content: "\e166";}.fa-display-slash::before {content: "\e2fa";}.fa-desktop-slash::before {content: "\e2fa";}.fa-distribute-spacing-horizontal::before {content: "\e365";}.fa-distribute-spacing-vertical::before {content: "\e366";}.fa-ditto::before {content: "\22";}.fa-divide::before {content: "\f529";}.fa-dna::before {content: "\f471";}.fa-do-not-enter::before {content: "\f5ec";}.fa-dog::before {content: "\f6d3";}.fa-dog-leashed::before {content: "\f6d4";}.fa-dollar-sign::before {content: "\24";}.fa-dollar::before {content: "\24";}.fa-usd::before {content: "\24";}.fa-dolly::before {content: "\f472";}.fa-dolly-box::before {content: "\f472";}.fa-dolly-empty::before {content: "\f473";}.fa-dolphin::before {content: "\e168";}.fa-dong-sign::before {content: "\e169";}.fa-donut::before {content: "\e406";}.fa-doughnut::before {content: "\e406";}.fa-door-closed::before {content: "\f52a";}.fa-door-open::before {content: "\f52b";}.fa-dove::before {content: "\f4ba";}.fa-down::before {content: "\f354";}.fa-arrow-alt-down::before {content: "\f354";}.fa-down-from-dotted-line::before {content: "\e407";}.fa-down-from-line::before {content: "\f349";}.fa-arrow-alt-from-top::before {content: "\f349";}.fa-down-left::before {content: "\e16a";}.fa-down-left-and-up-right-to-center::before {content: "\f422";}.fa-compress-alt::before {content: "\f422";}.fa-down-long::before {content: "\f309";}.fa-long-arrow-alt-down::before {content: "\f309";}.fa-down-right::before {content: "\e16b";}.fa-down-to-bracket::before {content: "\e4e7";}.fa-down-to-dotted-line::before {content: "\e408";}.fa-down-to-line::before {content: "\f34a";}.fa-arrow-alt-to-bottom::before {content: "\f34a";}.fa-download::before {content: "\f019";}.fa-dragon::before {content: "\f6d5";}.fa-draw-circle::before {content: "\f5ed";}.fa-draw-polygon::before {content: "\f5ee";}.fa-draw-square::before {content: "\f5ef";}.fa-dreidel::before {content: "\f792";}.fa-drone::before {content: "\f85f";}.fa-drone-front::before {content: "\f860";}.fa-drone-alt::before {content: "\f860";}.fa-droplet::before {content: "\f043";}.fa-tint::before {content: "\f043";}.fa-droplet-degree::before {content: "\f748";}.fa-dewpoint::before {content: "\f748";}.fa-droplet-percent::before {content: "\f750";}.fa-humidity::before {content: "\f750";}.fa-droplet-slash::before {content: "\f5c7";}.fa-tint-slash::before {content: "\f5c7";}.fa-drum::before {content: "\f569";}.fa-drum-steelpan::before {content: "\f56a";}.fa-drumstick::before {content: "\f6d6";}.fa-drumstick-bite::before {content: "\f6d7";}.fa-dryer::before {content: "\f861";}.fa-dryer-heat::before {content: "\f862";}.fa-dryer-alt::before {content: "\f862";}.fa-duck::before {content: "\f6d8";}.fa-dumbbell::before {content: "\f44b";}.fa-dumpster::before {content: "\f793";}.fa-dumpster-fire::before {content: "\f794";}.fa-dungeon::before {content: "\f6d9";}.fa-e::before {content: "\45";}.fa-ear::before {content: "\f5f0";}.fa-ear-deaf::before {content: "\f2a4";}.fa-deaf::before {content: "\f2a4";}.fa-deafness::before {content: "\f2a4";}.fa-hard-of-hearing::before {content: "\f2a4";}.fa-ear-listen::before {content: "\f2a2";}.fa-assistive-listening-systems::before {content: "\f2a2";}.fa-ear-muffs::before {content: "\f795";}.fa-earth-africa::before {content: "\f57c";}.fa-globe-africa::before {content: "\f57c";}.fa-earth-americas::before {content: "\f57d";}.fa-earth::before {content: "\f57d";}.fa-earth-america::before {content: "\f57d";}.fa-globe-americas::before {content: "\f57d";}.fa-earth-asia::before {content: "\f57e";}.fa-globe-asia::before {content: "\f57e";}.fa-earth-europe::before {content: "\f7a2";}.fa-globe-europe::before {content: "\f7a2";}.fa-earth-oceania::before {content: "\e47b";}.fa-globe-oceania::before {content: "\e47b";}.fa-eclipse::before {content: "\f749";}.fa-egg::before {content: "\f7fb";}.fa-egg-fried::before {content: "\f7fc";}.fa-eggplant::before {content: "\e16c";}.fa-eject::before {content: "\f052";}.fa-elephant::before {content: "\f6da";}.fa-elevator::before {content: "\e16d";}.fa-ellipsis::before {content: "\f141";}.fa-ellipsis-h::before {content: "\f141";}.fa-ellipsis-stroke::before {content: "\f39b";}.fa-ellipsis-h-alt::before {content: "\f39b";}.fa-ellipsis-stroke-vertical::before {content: "\f39c";}.fa-ellipsis-v-alt::before {content: "\f39c";}.fa-ellipsis-vertical::before {content: "\f142";}.fa-ellipsis-v::before {content: "\f142";}.fa-empty-set::before {content: "\f656";}.fa-engine::before {content: "\e16e";}.fa-engine-warning::before {content: "\f5f2";}.fa-engine-exclamation::before {content: "\f5f2";}.fa-envelope::before {content: "\f0e0";}.fa-envelope-circle-check::before {content: "\e4e8";}.fa-envelope-dot::before {content: "\e16f";}.fa-envelope-badge::before {content: "\e16f";}.fa-envelope-open::before {content: "\f2b6";}.fa-envelope-open-dollar::before {content: "\f657";}.fa-envelope-open-text::before {content: "\f658";}.fa-envelopes::before {content: "\e170";}.fa-envelopes-bulk::before {content: "\f674";}.fa-mail-bulk::before {content: "\f674";}.fa-equals::before {content: "\3d";}.fa-eraser::before {content: "\f12d";}.fa-escalator::before {content: "\e171";}.fa-ethernet::before {content: "\f796";}.fa-euro-sign::before {content: "\f153";}.fa-eur::before {content: "\f153";}.fa-euro::before {content: "\f153";}.fa-exclamation::before {content: "\21";}.fa-expand::before {content: "\f065";}.fa-expand-wide::before {content: "\f320";}.fa-explosion::before {content: "\e4e9";}.fa-eye::before {content: "\f06e";}.fa-eye-dropper::before {content: "\f1fb";}.fa-eye-dropper-empty::before {content: "\f1fb";}.fa-eyedropper::before {content: "\f1fb";}.fa-eye-dropper-full::before {content: "\e172";}.fa-eye-dropper-half::before {content: "\e173";}.fa-eye-evil::before {content: "\f6db";}.fa-eye-low-vision::before {content: "\f2a8";}.fa-low-vision::before {content: "\f2a8";}.fa-eye-slash::before {content: "\f070";}.fa-eyes::before {content: "\e367";}.fa-f::before {content: "\46";}.fa-face-angry::before {content: "\f556";}.fa-angry::before {content: "\f556";}.fa-face-angry-horns::before {content: "\e368";}.fa-face-anguished::before {content: "\e369";}.fa-face-anxious-sweat::before {content: "\e36a";}.fa-face-astonished::before {content: "\e36b";}.fa-face-awesome::before {content: "\e409";}.fa-gave-dandy::before {content: "\e409";}.fa-face-beam-hand-over-mouth::before {content: "\e47c";}.fa-face-clouds::before {content: "\e47d";}.fa-face-confounded::before {content: "\e36c";}.fa-face-confused::before {content: "\e36d";}.fa-face-cowboy-hat::before {content: "\e36e";}.fa-face-diagonal-mouth::before {content: "\e47e";}.fa-face-disappointed::before {content: "\e36f";}.fa-face-disguise::before {content: "\e370";}.fa-face-dizzy::before {content: "\f567";}.fa-dizzy::before {content: "\f567";}.fa-face-dotted::before {content: "\e47f";}.fa-face-downcast-sweat::before {content: "\e371";}.fa-face-drooling::before {content: "\e372";}.fa-face-exhaling::before {content: "\e480";}.fa-face-explode::before {content: "\e2fe";}.fa-exploding-head::before {content: "\e2fe";}.fa-face-expressionless::before {content: "\e373";}.fa-face-eyes-xmarks::before {content: "\e374";}.fa-face-fearful::before {content: "\e375";}.fa-face-flushed::before {content: "\f579";}.fa-flushed::before {content: "\f579";}.fa-face-frown::before {content: "\f119";}.fa-frown::before {content: "\f119";}.fa-face-frown-open::before {content: "\f57a";}.fa-frown-open::before {content: "\f57a";}.fa-face-frown-slight::before {content: "\e376";}.fa-face-glasses::before {content: "\e377";}.fa-face-grimace::before {content: "\f57f";}.fa-grimace::before {content: "\f57f";}.fa-face-grin::before {content: "\f580";}.fa-grin::before {content: "\f580";}.fa-face-grin-beam::before {content: "\f582";}.fa-grin-beam::before {content: "\f582";}.fa-face-grin-beam-sweat::before {content: "\f583";}.fa-grin-beam-sweat::before {content: "\f583";}.fa-face-grin-hearts::before {content: "\f584";}.fa-grin-hearts::before {content: "\f584";}.fa-face-grin-squint::before {content: "\f585";}.fa-grin-squint::before {content: "\f585";}.fa-face-grin-squint-tears::before {content: "\f586";}.fa-grin-squint-tears::before {content: "\f586";}.fa-face-grin-stars::before {content: "\f587";}.fa-grin-stars::before {content: "\f587";}.fa-face-grin-tears::before {content: "\f588";}.fa-grin-tears::before {content: "\f588";}.fa-face-grin-tongue::before {content: "\f589";}.fa-grin-tongue::before {content: "\f589";}.fa-face-grin-tongue-squint::before {content: "\f58a";}.fa-grin-tongue-squint::before {content: "\f58a";}.fa-face-grin-tongue-wink::before {content: "\f58b";}.fa-grin-tongue-wink::before {content: "\f58b";}.fa-face-grin-wide::before {content: "\f581";}.fa-grin-alt::before {content: "\f581";}.fa-face-grin-wink::before {content: "\f58c";}.fa-grin-wink::before {content: "\f58c";}.fa-face-hand-over-mouth::before {content: "\e378";}.fa-face-hand-peeking::before {content: "\e481";}.fa-face-hand-yawn::before {content: "\e379";}.fa-face-head-bandage::before {content: "\e37a";}.fa-face-holding-back-tears::before {content: "\e482";}.fa-face-hushed::before {content: "\e37b";}.fa-face-icicles::before {content: "\e37c";}.fa-face-kiss::before {content: "\f596";}.fa-kiss::before {content: "\f596";}.fa-face-kiss-beam::before {content: "\f597";}.fa-kiss-beam::before {content: "\f597";}.fa-face-kiss-closed-eyes::before {content: "\e37d";}.fa-face-kiss-wink-heart::before {content: "\f598";}.fa-kiss-wink-heart::before {content: "\f598";}.fa-face-laugh::before {content: "\f599";}.fa-laugh::before {content: "\f599";}.fa-face-laugh-beam::before {content: "\f59a";}.fa-laugh-beam::before {content: "\f59a";}.fa-face-laugh-squint::before {content: "\f59b";}.fa-laugh-squint::before {content: "\f59b";}.fa-face-laugh-wink::before {content: "\f59c";}.fa-laugh-wink::before {content: "\f59c";}.fa-face-lying::before {content: "\e37e";}.fa-face-mask::before {content: "\e37f";}.fa-face-meh::before {content: "\f11a";}.fa-meh::before {content: "\f11a";}.fa-face-meh-blank::before {content: "\f5a4";}.fa-meh-blank::before {content: "\f5a4";}.fa-face-melting::before {content: "\e483";}.fa-face-monocle::before {content: "\e380";}.fa-face-nauseated::before {content: "\e381";}.fa-face-nose-steam::before {content: "\e382";}.fa-face-party::before {content: "\e383";}.fa-face-pensive::before {content: "\e384";}.fa-face-persevering::before {content: "\e385";}.fa-face-pleading::before {content: "\e386";}.fa-face-pouting::before {content: "\e387";}.fa-face-raised-eyebrow::before {content: "\e388";}.fa-face-relieved::before {content: "\e389";}.fa-face-rolling-eyes::before {content: "\f5a5";}.fa-meh-rolling-eyes::before {content: "\f5a5";}.fa-face-sad-cry::before {content: "\f5b3";}.fa-sad-cry::before {content: "\f5b3";}.fa-face-sad-sweat::before {content: "\e38a";}.fa-face-sad-tear::before {content: "\f5b4";}.fa-sad-tear::before {content: "\f5b4";}.fa-face-saluting::before {content: "\e484";}.fa-face-scream::before {content: "\e38b";}.fa-face-shush::before {content: "\e38c";}.fa-face-sleeping::before {content: "\e38d";}.fa-face-sleepy::before {content: "\e38e";}.fa-face-smile::before {content: "\f118";}.fa-smile::before {content: "\f118";}.fa-face-smile-beam::before {content: "\f5b8";}.fa-smile-beam::before {content: "\f5b8";}.fa-face-smile-halo::before {content: "\e38f";}.fa-face-smile-hearts::before {content: "\e390";}.fa-face-smile-horns::before {content: "\e391";}.fa-face-smile-plus::before {content: "\f5b9";}.fa-smile-plus::before {content: "\f5b9";}.fa-face-smile-relaxed::before {content: "\e392";}.fa-face-smile-tear::before {content: "\e393";}.fa-face-smile-tongue::before {content: "\e394";}.fa-face-smile-upside-down::before {content: "\e395";}.fa-face-smile-wink::before {content: "\f4da";}.fa-smile-wink::before {content: "\f4da";}.fa-face-smiling-hands::before {content: "\e396";}.fa-face-smirking::before {content: "\e397";}.fa-face-spiral-eyes::before {content: "\e485";}.fa-face-sunglasses::before {content: "\e398";}.fa-face-surprise::before {content: "\f5c2";}.fa-surprise::before {content: "\f5c2";}.fa-face-swear::before {content: "\e399";}.fa-face-thermometer::before {content: "\e39a";}.fa-face-thinking::before {content: "\e39b";}.fa-face-tired::before {content: "\f5c8";}.fa-tired::before {content: "\f5c8";}.fa-face-tissue::before {content: "\e39c";}.fa-face-tongue-money::before {content: "\e39d";}.fa-face-tongue-sweat::before {content: "\e39e";}.fa-face-unamused::before {content: "\e39f";}.fa-face-viewfinder::before {content: "\e2ff";}.fa-face-vomit::before {content: "\e3a0";}.fa-face-weary::before {content: "\e3a1";}.fa-face-woozy::before {content: "\e3a2";}.fa-face-worried::before {content: "\e3a3";}.fa-face-zany::before {content: "\e3a4";}.fa-face-zipper::before {content: "\e3a5";}.fa-falafel::before {content: "\e40a";}.fa-family::before {content: "\e300";}.fa-family-dress::before {content: "\e301";}.fa-family-pants::before {content: "\e302";}.fa-fan::before {content: "\f863";}.fa-fan-table::before {content: "\e004";}.fa-farm::before {content: "\f864";}.fa-barn-silo::before {content: "\f864";}.fa-faucet::before {content: "\e005";}.fa-faucet-drip::before {content: "\e006";}.fa-fax::before {content: "\f1ac";}.fa-feather::before {content: "\f52d";}.fa-feather-pointed::before {content: "\f56b";}.fa-feather-alt::before {content: "\f56b";}.fa-fence::before {content: "\e303";}.fa-ferris-wheel::before {content: "\e174";}.fa-ferry::before {content: "\e4ea";}.fa-field-hockey-stick-ball::before {content: "\f44c";}.fa-field-hockey::before {content: "\f44c";}.fa-file::before {content: "\f15b";}.fa-file-arrow-down::before {content: "\f56d";}.fa-file-download::before {content: "\f56d";}.fa-file-arrow-up::before {content: "\f574";}.fa-file-upload::before {content: "\f574";}.fa-file-audio::before {content: "\f1c7";}.fa-file-binary::before {content: "\e175";}.fa-file-certificate::before {content: "\f5f3";}.fa-file-award::before {content: "\f5f3";}.fa-file-chart-column::before {content: "\f659";}.fa-file-chart-line::before {content: "\f659";}.fa-file-chart-pie::before {content: "\f65a";}.fa-file-check::before {content: "\f316";}.fa-file-circle-check::before {content: "\e493";}.fa-file-circle-exclamation::before {content: "\e4eb";}.fa-file-circle-info::before {content: "\e4ec";}.fa-file-circle-minus::before {content: "\e4ed";}.fa-file-circle-plus::before {content: "\e4ee";}.fa-file-circle-question::before {content: "\e4ef";}.fa-file-circle-xmark::before {content: "\e494";}.fa-file-code::before {content: "\f1c9";}.fa-file-contract::before {content: "\f56c";}.fa-file-csv::before {content: "\f6dd";}.fa-file-dashed-line::before {content: "\f877";}.fa-page-break::before {content: "\f877";}.fa-file-excel::before {content: "\f1c3";}.fa-file-exclamation::before {content: "\f31a";}.fa-file-export::before {content: "\f56e";}.fa-arrow-right-from-file::before {content: "\f56e";}.fa-file-heart::before {content: "\e176";}.fa-file-image::before {content: "\f1c5";}.fa-file-import::before {content: "\f56f";}.fa-arrow-right-to-file::before {content: "\f56f";}.fa-file-invoice::before {content: "\f570";}.fa-file-invoice-dollar::before {content: "\f571";}.fa-file-lines::before {content: "\f15c";}.fa-file-alt::before {content: "\f15c";}.fa-file-text::before {content: "\f15c";}.fa-file-lock::before {content: "\e3a6";}.fa-file-magnifying-glass::before {content: "\f865";}.fa-file-search::before {content: "\f865";}.fa-file-medical::before {content: "\f477";}.fa-file-minus::before {content: "\f318";}.fa-file-music::before {content: "\f8b6";}.fa-file-pdf::before {content: "\f1c1";}.fa-file-pen::before {content: "\f31c";}.fa-file-edit::before {content: "\f31c";}.fa-file-plus::before {content: "\f319";}.fa-file-plus-minus::before {content: "\e177";}.fa-file-powerpoint::before {content: "\f1c4";}.fa-file-prescription::before {content: "\f572";}.fa-file-shield::before {content: "\e4f0";}.fa-file-signature::before {content: "\f573";}.fa-file-slash::before {content: "\e3a7";}.fa-file-spreadsheet::before {content: "\f65b";}.fa-file-user::before {content: "\f65c";}.fa-file-video::before {content: "\f1c8";}.fa-file-waveform::before {content: "\f478";}.fa-file-medical-alt::before {content: "\f478";}.fa-file-word::before {content: "\f1c2";}.fa-file-xmark::before {content: "\f317";}.fa-file-times::before {content: "\f317";}.fa-file-zipper::before {content: "\f1c6";}.fa-file-archive::before {content: "\f1c6";}.fa-files::before {content: "\e178";}.fa-files-medical::before {content: "\f7fd";}.fa-fill::before {content: "\f575";}.fa-fill-drip::before {content: "\f576";}.fa-film::before {content: "\f008";}.fa-film-canister::before {content: "\f8b7";}.fa-film-simple::before {content: "\f3a0";}.fa-film-alt::before {content: "\f3a0";}.fa-film-slash::before {content: "\e179";}.fa-films::before {content: "\e17a";}.fa-filter::before {content: "\f0b0";}.fa-filter-circle-dollar::before {content: "\f662";}.fa-funnel-dollar::before {content: "\f662";}.fa-filter-circle-xmark::before {content: "\e17b";}.fa-filter-list::before {content: "\e17c";}.fa-filter-slash::before {content: "\e17d";}.fa-filters::before {content: "\e17e";}.fa-fingerprint::before {content: "\f577";}.fa-fire::before {content: "\f06d";}.fa-fire-burner::before {content: "\e4f1";}.fa-fire-extinguisher::before {content: "\f134";}.fa-fire-flame::before {content: "\f6df";}.fa-flame::before {content: "\f6df";}.fa-fire-flame-curved::before {content: "\f7e4";}.fa-fire-alt::before {content: "\f7e4";}.fa-fire-flame-simple::before {content: "\f46a";}.fa-burn::before {content: "\f46a";}.fa-fire-hydrant::before {content: "\e17f";}.fa-fire-smoke::before {content: "\f74b";}.fa-fireplace::before {content: "\f79a";}.fa-fish::before {content: "\f578";}.fa-fish-bones::before {content: "\e304";}.fa-fish-cooked::before {content: "\f7fe";}.fa-fish-fins::before {content: "\e4f2";}.fa-fishing-rod::before {content: "\e3a8";}.fa-flag::before {content: "\f024";}.fa-flag-checkered::before {content: "\f11e";}.fa-flag-pennant::before {content: "\f456";}.fa-pennant::before {content: "\f456";}.fa-flag-swallowtail::before {content: "\f74c";}.fa-flag-alt::before {content: "\f74c";}.fa-flag-usa::before {content: "\f74d";}.fa-flashlight::before {content: "\f8b8";}.fa-flask::before {content: "\f0c3";}.fa-flask-round-poison::before {content: "\f6e0";}.fa-flask-poison::before {content: "\f6e0";}.fa-flask-round-potion::before {content: "\f6e1";}.fa-flask-potion::before {content: "\f6e1";}.fa-flask-vial::before {content: "\e4f3";}.fa-flatbread::before {content: "\e40b";}.fa-flatbread-stuffed::before {content: "\e40c";}.fa-floppy-disk::before {content: "\f0c7";}.fa-save::before {content: "\f0c7";}.fa-floppy-disk-circle-arrow-right::before {content: "\e180";}.fa-save-circle-arrow-right::before {content: "\e180";}.fa-floppy-disk-circle-xmark::before {content: "\e181";}.fa-floppy-disk-times::before {content: "\e181";}.fa-save-circle-xmark::before {content: "\e181";}.fa-save-times::before {content: "\e181";}.fa-floppy-disk-pen::before {content: "\e182";}.fa-floppy-disks::before {content: "\e183";}.fa-florin-sign::before {content: "\e184";}.fa-flower::before {content: "\f7ff";}.fa-flower-daffodil::before {content: "\f800";}.fa-flower-tulip::before {content: "\f801";}.fa-flute::before {content: "\f8b9";}.fa-flux-capacitor::before {content: "\f8ba";}.fa-flying-disc::before {content: "\e3a9";}.fa-folder::before {content: "\f07b";}.fa-folder-blank::before {content: "\f07b";}.fa-folder-arrow-down::before {content: "\e053";}.fa-folder-download::before {content: "\e053";}.fa-folder-arrow-up::before {content: "\e054";}.fa-folder-upload::before {content: "\e054";}.fa-folder-bookmark::before {content: "\e186";}.fa-folder-closed::before {content: "\e185";}.fa-folder-gear::before {content: "\e187";}.fa-folder-cog::before {content: "\e187";}.fa-folder-grid::before {content: "\e188";}.fa-folder-heart::before {content: "\e189";}.fa-folder-image::before {content: "\e18a";}.fa-folder-magnifying-glass::before {content: "\e18b";}.fa-folder-search::before {content: "\e18b";}.fa-folder-medical::before {content: "\e18c";}.fa-folder-minus::before {content: "\f65d";}.fa-folder-music::before {content: "\e18d";}.fa-folder-open::before {content: "\f07c";}.fa-folder-plus::before {content: "\f65e";}.fa-folder-tree::before {content: "\f802";}.fa-folder-user::before {content: "\e18e";}.fa-folder-xmark::before {content: "\f65f";}.fa-folder-times::before {content: "\f65f";}.fa-folders::before {content: "\f660";}.fa-fondue-pot::before {content: "\e40d";}.fa-font::before {content: "\f031";}.fa-font-case::before {content: "\f866";}.fa-football::before {content: "\f44e";}.fa-football-ball::before {content: "\f44e";}.fa-football-helmet::before {content: "\f44f";}.fa-fork::before {content: "\f2e3";}.fa-utensil-fork::before {content: "\f2e3";}.fa-fork-knife::before {content: "\f2e6";}.fa-utensils-alt::before {content: "\f2e6";}.fa-forklift::before {content: "\f47a";}.fa-fort::before {content: "\e486";}.fa-forward::before {content: "\f04e";}.fa-forward-fast::before {content: "\f050";}.fa-fast-forward::before {content: "\f050";}.fa-forward-step::before {content: "\f051";}.fa-step-forward::before {content: "\f051";}.fa-frame::before {content: "\e495";}.fa-franc-sign::before {content: "\e18f";}.fa-french-fries::before {content: "\f803";}.fa-frog::before {content: "\f52e";}.fa-function::before {content: "\f661";}.fa-futbol::before {content: "\f1e3";}.fa-futbol-ball::before {content: "\f1e3";}.fa-soccer-ball::before {content: "\f1e3";}.fa-g::before {content: "\47";}.fa-galaxy::before {content: "\e008";}.fa-gallery-thumbnails::before {content: "\e3aa";}.fa-game-board::before {content: "\f867";}.fa-game-board-simple::before {content: "\f868";}.fa-game-board-alt::before {content: "\f868";}.fa-game-console-handheld::before {content: "\f8bb";}.fa-gamepad::before {content: "\f11b";}.fa-gamepad-modern::before {content: "\f8bc";}.fa-gamepad-alt::before {content: "\f8bc";}.fa-garage::before {content: "\e009";}.fa-garage-car::before {content: "\e00a";}.fa-garage-open::before {content: "\e00b";}.fa-garlic::before {content: "\e40e";}.fa-gas-pump::before {content: "\f52f";}.fa-gas-pump-slash::before {content: "\f5f4";}.fa-gauge::before {content: "\f624";}.fa-dashboard::before {content: "\f624";}.fa-gauge-med::before {content: "\f624";}.fa-tachometer-alt-average::before {content: "\f624";}.fa-gauge-circle-bolt::before {content: "\e496";}.fa-gauge-circle-minus::before {content: "\e497";}.fa-gauge-circle-plus::before {content: "\e498";}.fa-gauge-high::before {content: "\f625";}.fa-tachometer-alt::before {content: "\f625";}.fa-tachometer-alt-fast::before {content: "\f625";}.fa-gauge-low::before {content: "\f627";}.fa-tachometer-alt-slow::before {content: "\f627";}.fa-gauge-max::before {content: "\f626";}.fa-tachometer-alt-fastest::before {content: "\f626";}.fa-gauge-min::before {content: "\f628";}.fa-tachometer-alt-slowest::before {content: "\f628";}.fa-gauge-simple::before {content: "\f629";}.fa-gauge-simple-med::before {content: "\f629";}.fa-tachometer-average::before {content: "\f629";}.fa-gauge-simple-high::before {content: "\f62a";}.fa-tachometer::before {content: "\f62a";}.fa-tachometer-fast::before {content: "\f62a";}.fa-gauge-simple-low::before {content: "\f62c";}.fa-tachometer-slow::before {content: "\f62c";}.fa-gauge-simple-max::before {content: "\f62b";}.fa-tachometer-fastest::before {content: "\f62b";}.fa-gauge-simple-min::before {content: "\f62d";}.fa-tachometer-slowest::before {content: "\f62d";}.fa-gavel::before {content: "\f0e3";}.fa-legal::before {content: "\f0e3";}.fa-gear::before {content: "\f013";}.fa-cog::before {content: "\f013";}.fa-gears::before {content: "\f085";}.fa-cogs::before {content: "\f085";}.fa-gem::before {content: "\f3a5";}.fa-genderless::before {content: "\f22d";}.fa-ghost::before {content: "\f6e2";}.fa-gif::before {content: "\e190";}.fa-gift::before {content: "\f06b";}.fa-gift-card::before {content: "\f663";}.fa-gifts::before {content: "\f79c";}.fa-gingerbread-man::before {content: "\f79d";}.fa-glass::before {content: "\f804";}.fa-glass-citrus::before {content: "\f869";}.fa-glass-empty::before {content: "\e191";}.fa-glass-half::before {content: "\e192";}.fa-glass-half-empty::before {content: "\e192";}.fa-glass-half-full::before {content: "\e192";}.fa-glass-water::before {content: "\e4f4";}.fa-glass-water-droplet::before {content: "\e4f5";}.fa-glasses::before {content: "\f530";}.fa-glasses-round::before {content: "\f5f5";}.fa-glasses-alt::before {content: "\f5f5";}.fa-globe::before {content: "\f0ac";}.fa-globe-snow::before {content: "\f7a3";}.fa-globe-stand::before {content: "\f5f6";}.fa-goal-net::before {content: "\e3ab";}.fa-golf-ball-tee::before {content: "\f450";}.fa-golf-ball::before {content: "\f450";}.fa-golf-club::before {content: "\f451";}.fa-golf-flag-hole::before {content: "\e3ac";}.fa-gopuram::before {content: "\f664";}.fa-graduation-cap::before {content: "\f19d";}.fa-mortar-board::before {content: "\f19d";}.fa-gramophone::before {content: "\f8bd";}.fa-grapes::before {content: "\e306";}.fa-grate::before {content: "\e193";}.fa-grate-droplet::before {content: "\e194";}.fa-greater-than::before {content: "\3e";}.fa-greater-than-equal::before {content: "\f532";}.fa-grid::before {content: "\e195";}.fa-grid-3::before {content: "\e195";}.fa-grid-2::before {content: "\e196";}.fa-grid-2-plus::before {content: "\e197";}.fa-grid-4::before {content: "\e198";}.fa-grid-5::before {content: "\e199";}.fa-grid-dividers::before {content: "\e3ad";}.fa-grid-horizontal::before {content: "\e307";}.fa-grip::before {content: "\f58d";}.fa-grip-horizontal::before {content: "\f58d";}.fa-grip-dots::before {content: "\e410";}.fa-grip-dots-vertical::before {content: "\e411";}.fa-grip-lines::before {content: "\f7a4";}.fa-grip-lines-vertical::before {content: "\f7a5";}.fa-grip-vertical::before {content: "\f58e";}.fa-group-arrows-rotate::before {content: "\e4f6";}.fa-guarani-sign::before {content: "\e19a";}.fa-guitar::before {content: "\f7a6";}.fa-guitar-electric::before {content: "\f8be";}.fa-guitars::before {content: "\f8bf";}.fa-gun::before {content: "\e19b";}.fa-gun-slash::before {content: "\e19c";}.fa-gun-squirt::before {content: "\e19d";}.fa-h::before {content: "\48";}.fa-h1::before {content: "\f313";}.fa-h2::before {content: "\f314";}.fa-h3::before {content: "\f315";}.fa-h4::before {content: "\f86a";}.fa-h5::before {content: "\e412";}.fa-h6::before {content: "\e413";}.fa-hammer::before {content: "\f6e3";}.fa-hammer-crash::before {content: "\e414";}.fa-hammer-war::before {content: "\f6e4";}.fa-hamsa::before {content: "\f665";}.fa-hand::before {content: "\f256";}.fa-hand-paper::before {content: "\f256";}.fa-hand-back-fist::before {content: "\f255";}.fa-hand-rock::before {content: "\f255";}.fa-hand-back-point-down::before {content: "\e19e";}.fa-hand-back-point-left::before {content: "\e19f";}.fa-hand-back-point-ribbon::before {content: "\e1a0";}.fa-hand-back-point-right::before {content: "\e1a1";}.fa-hand-back-point-up::before {content: "\e1a2";}.fa-hand-dots::before {content: "\f461";}.fa-allergies::before {content: "\f461";}.fa-hand-fingers-crossed::before {content: "\e1a3";}.fa-hand-fist::before {content: "\f6de";}.fa-fist-raised::before {content: "\f6de";}.fa-hand-heart::before {content: "\f4bc";}.fa-hand-holding::before {content: "\f4bd";}.fa-hand-holding-box::before {content: "\f47b";}.fa-hand-holding-dollar::before {content: "\f4c0";}.fa-hand-holding-usd::before {content: "\f4c0";}.fa-hand-holding-droplet::before {content: "\f4c1";}.fa-hand-holding-water::before {content: "\f4c1";}.fa-hand-holding-hand::before {content: "\e4f7";}.fa-hand-holding-heart::before {content: "\f4be";}.fa-hand-holding-magic::before {content: "\f6e5";}.fa-hand-holding-medical::before {content: "\e05c";}.fa-hand-holding-seedling::before {content: "\f4bf";}.fa-hand-holding-skull::before {content: "\e1a4";}.fa-hand-horns::before {content: "\e1a9";}.fa-hand-lizard::before {content: "\f258";}.fa-hand-love::before {content: "\e1a5";}.fa-hand-middle-finger::before {content: "\f806";}.fa-hand-peace::before {content: "\f25b";}.fa-hand-point-down::before {content: "\f0a7";}.fa-hand-point-left::before {content: "\f0a5";}.fa-hand-point-ribbon::before {content: "\e1a6";}.fa-hand-point-right::before {content: "\f0a4";}.fa-hand-point-up::before {content: "\f0a6";}.fa-hand-pointer::before {content: "\f25a";}.fa-hand-scissors::before {content: "\f257";}.fa-hand-sparkles::before {content: "\e05d";}.fa-hand-spock::before {content: "\f259";}.fa-hand-wave::before {content: "\e1a7";}.fa-handcuffs::before {content: "\e4f8";}.fa-hands::before {content: "\f2a7";}.fa-sign-language::before {content: "\f2a7";}.fa-signing::before {content: "\f2a7";}.fa-hands-asl-interpreting::before {content: "\f2a3";}.fa-american-sign-language-interpreting::before {content: "\f2a3";}.fa-asl-interpreting::before {content: "\f2a3";}.fa-hands-american-sign-language-interpreting::before {content: "\f2a3";}.fa-hands-bound::before {content: "\e4f9";}.fa-hands-bubbles::before {content: "\e05e";}.fa-hands-wash::before {content: "\e05e";}.fa-hands-clapping::before {content: "\e1a8";}.fa-hands-holding::before {content: "\f4c2";}.fa-hands-holding-child::before {content: "\e4fa";}.fa-hands-holding-circle::before {content: "\e4fb";}.fa-hands-holding-diamond::before {content: "\f47c";}.fa-hand-receiving::before {content: "\f47c";}.fa-hands-holding-dollar::before {content: "\f4c5";}.fa-hands-usd::before {content: "\f4c5";}.fa-hands-holding-heart::before {content: "\f4c3";}.fa-hands-heart::before {content: "\f4c3";}.fa-hands-praying::before {content: "\f684";}.fa-praying-hands::before {content: "\f684";}.fa-handshake::before {content: "\f2b5";}.fa-handshake-angle::before {content: "\f4c4";}.fa-hands-helping::before {content: "\f4c4";}.fa-handshake-simple::before {content: "\f4c6";}.fa-handshake-alt::before {content: "\f4c6";}.fa-handshake-simple-slash::before {content: "\e05f";}.fa-handshake-alt-slash::before {content: "\e05f";}.fa-handshake-slash::before {content: "\e060";}.fa-hanukiah::before {content: "\f6e6";}.fa-hard-drive::before {content: "\f0a0";}.fa-hdd::before {content: "\f0a0";}.fa-hashtag::before {content: "\23";}.fa-hashtag-lock::before {content: "\e415";}.fa-hat-chef::before {content: "\f86b";}.fa-hat-cowboy::before {content: "\f8c0";}.fa-hat-cowboy-side::before {content: "\f8c1";}.fa-hat-santa::before {content: "\f7a7";}.fa-hat-winter::before {content: "\f7a8";}.fa-hat-witch::before {content: "\f6e7";}.fa-hat-wizard::before {content: "\f6e8";}.fa-head-side::before {content: "\f6e9";}.fa-head-side-brain::before {content: "\f808";}.fa-head-side-cough::before {content: "\e061";}.fa-head-side-cough-slash::before {content: "\e062";}.fa-head-side-goggles::before {content: "\f6ea";}.fa-head-vr::before {content: "\f6ea";}.fa-head-side-headphones::before {content: "\f8c2";}.fa-head-side-heart::before {content: "\e1aa";}.fa-head-side-mask::before {content: "\e063";}.fa-head-side-medical::before {content: "\f809";}.fa-head-side-virus::before {content: "\e064";}.fa-heading::before {content: "\f1dc";}.fa-header::before {content: "\f1dc";}.fa-headphones::before {content: "\f025";}.fa-headphones-simple::before {content: "\f58f";}.fa-headphones-alt::before {content: "\f58f";}.fa-headset::before {content: "\f590";}.fa-heart::before {content: "\f004";}.fa-heart-circle-bolt::before {content: "\e4fc";}.fa-heart-circle-check::before {content: "\e4fd";}.fa-heart-circle-exclamation::before {content: "\e4fe";}.fa-heart-circle-minus::before {content: "\e4ff";}.fa-heart-circle-plus::before {content: "\e500";}.fa-heart-circle-xmark::before {content: "\e501";}.fa-heart-crack::before {content: "\f7a9";}.fa-heart-broken::before {content: "\f7a9";}.fa-heart-half::before {content: "\e1ab";}.fa-heart-half-stroke::before {content: "\e1ac";}.fa-heart-half-alt::before {content: "\e1ac";}.fa-heart-pulse::before {content: "\f21e";}.fa-heartbeat::before {content: "\f21e";}.fa-heat::before {content: "\e00c";}.fa-helicopter::before {content: "\f533";}.fa-helicopter-symbol::before {content: "\e502";}.fa-helmet-battle::before {content: "\f6eb";}.fa-helmet-safety::before {content: "\f807";}.fa-hard-hat::before {content: "\f807";}.fa-hat-hard::before {content: "\f807";}.fa-helmet-un::before {content: "\e503";}.fa-hexagon::before {content: "\f312";}.fa-hexagon-check::before {content: "\e416";}.fa-hexagon-divide::before {content: "\e1ad";}.fa-hexagon-exclamation::before {content: "\e417";}.fa-hexagon-image::before {content: "\e504";}.fa-hexagon-minus::before {content: "\f307";}.fa-minus-hexagon::before {content: "\f307";}.fa-hexagon-plus::before {content: "\f300";}.fa-plus-hexagon::before {content: "\f300";}.fa-hexagon-vertical-nft::before {content: "\e505";}.fa-hexagon-vertical-nft-slanted::before {content: "\e506";}.fa-hexagon-xmark::before {content: "\f2ee";}.fa-times-hexagon::before {content: "\f2ee";}.fa-xmark-hexagon::before {content: "\f2ee";}.fa-high-definition::before {content: "\e1ae";}.fa-rectangle-hd::before {content: "\e1ae";}.fa-highlighter::before {content: "\f591";}.fa-highlighter-line::before {content: "\e1af";}.fa-hill-avalanche::before {content: "\e507";}.fa-hill-rockslide::before {content: "\e508";}.fa-hippo::before {content: "\f6ed";}.fa-hockey-mask::before {content: "\f6ee";}.fa-hockey-puck::before {content: "\f453";}.fa-hockey-stick-puck::before {content: "\e3ae";}.fa-hockey-sticks::before {content: "\f454";}.fa-holly-berry::before {content: "\f7aa";}.fa-honey-pot::before {content: "\e418";}.fa-hood-cloak::before {content: "\f6ef";}.fa-horizontal-rule::before {content: "\f86c";}.fa-horse::before {content: "\f6f0";}.fa-horse-head::before {content: "\f7ab";}.fa-horse-saddle::before {content: "\f8c3";}.fa-hose::before {content: "\e419";}.fa-hose-reel::before {content: "\e41a";}.fa-hospital::before {content: "\f0f8";}.fa-hospital-alt::before {content: "\f0f8";}.fa-hospital-wide::before {content: "\f0f8";}.fa-hospital-user::before {content: "\f80d";}.fa-hospitals::before {content: "\f80e";}.fa-hot-tub-person::before {content: "\f593";}.fa-hot-tub::before {content: "\f593";}.fa-hotdog::before {content: "\f80f";}.fa-hotel::before {content: "\f594";}.fa-hourglass::before {content: "\f254";}.fa-hourglass-2::before {content: "\f254";}.fa-hourglass-half::before {content: "\f254";}.fa-hourglass-clock::before {content: "\e41b";}.fa-hourglass-empty::before {content: "\f252";}.fa-hourglass-end::before {content: "\f253";}.fa-hourglass-3::before {content: "\f253";}.fa-hourglass-start::before {content: "\f251";}.fa-hourglass-1::before {content: "\f251";}.fa-house::before {content: "\f015";}.fa-home::before {content: "\f015";}.fa-home-alt::before {content: "\f015";}.fa-home-lg-alt::before {content: "\f015";}.fa-house-blank::before {content: "\e487";}.fa-home-blank::before {content: "\e487";}.fa-house-building::before {content: "\e1b1";}.fa-house-chimney::before {content: "\e3af";}.fa-home-lg::before {content: "\e3af";}.fa-house-chimney-blank::before {content: "\e3b0";}.fa-house-chimney-crack::before {content: "\f6f1";}.fa-house-damage::before {content: "\f6f1";}.fa-house-chimney-heart::before {content: "\e1b2";}.fa-house-chimney-medical::before {content: "\f7f2";}.fa-clinic-medical::before {content: "\f7f2";}.fa-house-chimney-user::before {content: "\e065";}.fa-house-chimney-window::before {content: "\e00d";}.fa-house-circle-check::before {content: "\e509";}.fa-house-circle-exclamation::before {content: "\e50a";}.fa-house-circle-xmark::before {content: "\e50b";}.fa-house-crack::before {content: "\e3b1";}.fa-house-day::before {content: "\e00e";}.fa-house-fire::before {content: "\e50c";}.fa-house-flag::before {content: "\e50d";}.fa-house-flood-water::before {content: "\e50e";}.fa-house-flood-water-circle-arrow-right::before {content: "\e50f";}.fa-house-heart::before {content: "\f4c9";}.fa-home-heart::before {content: "\f4c9";}.fa-house-laptop::before {content: "\e066";}.fa-laptop-house::before {content: "\e066";}.fa-house-lock::before {content: "\e510";}.fa-house-medical::before {content: "\e3b2";}.fa-house-medical-circle-check::before {content: "\e511";}.fa-house-medical-circle-exclamation::before {content: "\e512";}.fa-house-medical-circle-xmark::before {content: "\e513";}.fa-house-medical-flag::before {content: "\e514";}.fa-house-night::before {content: "\e010";}.fa-house-person-leave::before {content: "\e00f";}.fa-house-leave::before {content: "\e00f";}.fa-house-person-depart::before {content: "\e00f";}.fa-house-person-return::before {content: "\e011";}.fa-house-person-arrive::before {content: "\e011";}.fa-house-return::before {content: "\e011";}.fa-house-signal::before {content: "\e012";}.fa-house-tree::before {content: "\e1b3";}.fa-house-tsunami::before {content: "\e515";}.fa-house-turret::before {content: "\e1b4";}.fa-house-user::before {content: "\e1b0";}.fa-home-user::before {content: "\e1b0";}.fa-house-water::before {content: "\f74f";}.fa-house-flood::before {content: "\f74f";}.fa-house-window::before {content: "\e3b3";}.fa-hryvnia-sign::before {content: "\f6f2";}.fa-hryvnia::before {content: "\f6f2";}.fa-hundred-points::before {content: "\e41c";}.fa-100::before {content: "\e41c";}.fa-hurricane::before {content: "\f751";}.fa-hyphen::before {content: "\2d";}.fa-i::before {content: "\49";}.fa-i-cursor::before {content: "\f246";}.fa-ice-cream::before {content: "\f810";}.fa-ice-skate::before {content: "\f7ac";}.fa-icicles::before {content: "\f7ad";}.fa-icons::before {content: "\f86d";}.fa-heart-music-camera-bolt::before {content: "\f86d";}.fa-id-badge::before {content: "\f2c1";}.fa-id-card::before {content: "\f2c2";}.fa-drivers-license::before {content: "\f2c2";}.fa-id-card-clip::before {content: "\f47f";}.fa-id-card-alt::before {content: "\f47f";}.fa-igloo::before {content: "\f7ae";}.fa-image::before {content: "\f03e";}.fa-image-landscape::before {content: "\e1b5";}.fa-landscape::before {content: "\e1b5";}.fa-image-polaroid::before {content: "\f8c4";}.fa-image-polaroid-user::before {content: "\e1b6";}.fa-image-portrait::before {content: "\f3e0";}.fa-portrait::before {content: "\f3e0";}.fa-image-slash::before {content: "\e1b7";}.fa-image-user::before {content: "\e1b8";}.fa-images::before {content: "\f302";}.fa-images-user::before {content: "\e1b9";}.fa-inbox::before {content: "\f01c";}.fa-inbox-full::before {content: "\e1ba";}.fa-inbox-in::before {content: "\f310";}.fa-inbox-arrow-down::before {content: "\f310";}.fa-inbox-out::before {content: "\f311";}.fa-inbox-arrow-up::before {content: "\f311";}.fa-inboxes::before {content: "\e1bb";}.fa-indent::before {content: "\f03c";}.fa-indian-rupee-sign::before {content: "\e1bc";}.fa-indian-rupee::before {content: "\e1bc";}.fa-inr::before {content: "\e1bc";}.fa-industry::before {content: "\f275";}.fa-industry-windows::before {content: "\f3b3";}.fa-industry-alt::before {content: "\f3b3";}.fa-infinity::before {content: "\f534";}.fa-info::before {content: "\f129";}.fa-inhaler::before {content: "\f5f9";}.fa-input-numeric::before {content: "\e1bd";}.fa-input-pipe::before {content: "\e1be";}.fa-input-text::before {content: "\e1bf";}.fa-integral::before {content: "\f667";}.fa-intersection::before {content: "\f668";}.fa-island-tropical::before {content: "\f811";}.fa-island-tree-palm::before {content: "\f811";}.fa-italic::before {content: "\f033";}.fa-j::before {content: "\4a";}.fa-jack-o-lantern::before {content: "\f30e";}.fa-jar::before {content: "\e516";}.fa-jar-wheat::before {content: "\e517";}.fa-jedi::before {content: "\f669";}.fa-jet-fighter::before {content: "\f0fb";}.fa-fighter-jet::before {content: "\f0fb";}.fa-jet-fighter-up::before {content: "\e518";}.fa-joint::before {content: "\f595";}.fa-joystick::before {content: "\f8c5";}.fa-jug::before {content: "\f8c6";}.fa-jug-detergent::before {content: "\e519";}.fa-k::before {content: "\4b";}.fa-kaaba::before {content: "\f66b";}.fa-kazoo::before {content: "\f8c7";}.fa-kerning::before {content: "\f86f";}.fa-key::before {content: "\f084";}.fa-key-skeleton::before {content: "\f6f3";}.fa-key-skeleton-left-right::before {content: "\e3b4";}.fa-keyboard::before {content: "\f11c";}.fa-keyboard-brightness::before {content: "\e1c0";}.fa-keyboard-brightness-low::before {content: "\e1c1";}.fa-keyboard-down::before {content: "\e1c2";}.fa-keyboard-left::before {content: "\e1c3";}.fa-keynote::before {content: "\f66c";}.fa-khanda::before {content: "\f66d";}.fa-kidneys::before {content: "\f5fb";}.fa-kip-sign::before {content: "\e1c4";}.fa-kit-medical::before {content: "\f479";}.fa-first-aid::before {content: "\f479";}.fa-kitchen-set::before {content: "\e51a";}.fa-kite::before {content: "\f6f4";}.fa-kiwi-bird::before {content: "\f535";}.fa-kiwi-fruit::before {content: "\e30c";}.fa-knife::before {content: "\f2e4";}.fa-utensil-knife::before {content: "\f2e4";}.fa-knife-kitchen::before {content: "\f6f5";}.fa-l::before {content: "\4c";}.fa-lacrosse-stick::before {content: "\e3b5";}.fa-lacrosse-stick-ball::before {content: "\e3b6";}.fa-lambda::before {content: "\f66e";}.fa-lamp::before {content: "\f4ca";}.fa-lamp-desk::before {content: "\e014";}.fa-lamp-floor::before {content: "\e015";}.fa-lamp-street::before {content: "\e1c5";}.fa-land-mine-on::before {content: "\e51b";}.fa-landmark::before {content: "\f66f";}.fa-landmark-dome::before {content: "\f752";}.fa-landmark-alt::before {content: "\f752";}.fa-landmark-flag::before {content: "\e51c";}.fa-language::before {content: "\f1ab";}.fa-laptop::before {content: "\f109";}.fa-laptop-arrow-down::before {content: "\e1c6";}.fa-laptop-code::before {content: "\f5fc";}.fa-laptop-file::before {content: "\e51d";}.fa-laptop-medical::before {content: "\f812";}.fa-laptop-mobile::before {content: "\f87a";}.fa-phone-laptop::before {content: "\f87a";}.fa-laptop-slash::before {content: "\e1c7";}.fa-lari-sign::before {content: "\e1c8";}.fa-lasso::before {content: "\f8c8";}.fa-lasso-sparkles::before {content: "\e1c9";}.fa-layer-group::before {content: "\f5fd";}.fa-layer-minus::before {content: "\f5fe";}.fa-layer-group-minus::before {content: "\f5fe";}.fa-layer-plus::before {content: "\f5ff";}.fa-layer-group-plus::before {content: "\f5ff";}.fa-leaf::before {content: "\f06c";}.fa-leaf-heart::before {content: "\f4cb";}.fa-leaf-maple::before {content: "\f6f6";}.fa-leaf-oak::before {content: "\f6f7";}.fa-leafy-green::before {content: "\e41d";}.fa-left::before {content: "\f355";}.fa-arrow-alt-left::before {content: "\f355";}.fa-left-from-line::before {content: "\f348";}.fa-arrow-alt-from-right::before {content: "\f348";}.fa-left-long::before {content: "\f30a";}.fa-long-arrow-alt-left::before {content: "\f30a";}.fa-left-long-to-line::before {content: "\e41e";}.fa-left-right::before {content: "\f337";}.fa-arrows-alt-h::before {content: "\f337";}.fa-left-to-line::before {content: "\f34b";}.fa-arrow-alt-to-left::before {content: "\f34b";}.fa-lemon::before {content: "\f094";}.fa-less-than::before {content: "\3c";}.fa-less-than-equal::before {content: "\f537";}.fa-life-ring::before {content: "\f1cd";}.fa-light-ceiling::before {content: "\e016";}.fa-light-emergency::before {content: "\e41f";}.fa-light-emergency-on::before {content: "\e420";}.fa-light-switch::before {content: "\e017";}.fa-light-switch-off::before {content: "\e018";}.fa-light-switch-on::before {content: "\e019";}.fa-lightbulb::before {content: "\f0eb";}.fa-lightbulb-dollar::before {content: "\f670";}.fa-lightbulb-exclamation::before {content: "\f671";}.fa-lightbulb-exclamation-on::before {content: "\e1ca";}.fa-lightbulb-on::before {content: "\f672";}.fa-lightbulb-slash::before {content: "\f673";}.fa-lights-holiday::before {content: "\f7b2";}.fa-line-columns::before {content: "\f870";}.fa-line-height::before {content: "\f871";}.fa-lines-leaning::before {content: "\e51e";}.fa-link::before {content: "\f0c1";}.fa-chain::before {content: "\f0c1";}.fa-link-horizontal::before {content: "\e1cb";}.fa-chain-horizontal::before {content: "\e1cb";}.fa-link-horizontal-slash::before {content: "\e1cc";}.fa-chain-horizontal-slash::before {content: "\e1cc";}.fa-link-simple::before {content: "\e1cd";}.fa-link-simple-slash::before {content: "\e1ce";}.fa-link-slash::before {content: "\f127";}.fa-chain-broken::before {content: "\f127";}.fa-chain-slash::before {content: "\f127";}.fa-unlink::before {content: "\f127";}.fa-lips::before {content: "\f600";}.fa-lira-sign::before {content: "\f195";}.fa-list::before {content: "\f03a";}.fa-list-squares::before {content: "\f03a";}.fa-list-check::before {content: "\f0ae";}.fa-tasks::before {content: "\f0ae";}.fa-list-dropdown::before {content: "\e1cf";}.fa-list-music::before {content: "\f8c9";}.fa-list-ol::before {content: "\f0cb";}.fa-list-1-2::before {content: "\f0cb";}.fa-list-numeric::before {content: "\f0cb";}.fa-list-radio::before {content: "\e1d0";}.fa-list-timeline::before {content: "\e1d1";}.fa-list-tree::before {content: "\e1d2";}.fa-list-ul::before {content: "\f0ca";}.fa-list-dots::before {content: "\f0ca";}.fa-litecoin-sign::before {content: "\e1d3";}.fa-loader::before {content: "\e1d4";}.fa-lobster::before {content: "\e421";}.fa-location-arrow::before {content: "\f124";}.fa-location-check::before {content: "\f606";}.fa-map-marker-check::before {content: "\f606";}.fa-location-crosshairs::before {content: "\f601";}.fa-location::before {content: "\f601";}.fa-location-crosshairs-slash::before {content: "\f603";}.fa-location-slash::before {content: "\f603";}.fa-location-dot::before {content: "\f3c5";}.fa-map-marker-alt::before {content: "\f3c5";}.fa-location-dot-slash::before {content: "\f605";}.fa-map-marker-alt-slash::before {content: "\f605";}.fa-location-exclamation::before {content: "\f608";}.fa-map-marker-exclamation::before {content: "\f608";}.fa-location-minus::before {content: "\f609";}.fa-map-marker-minus::before {content: "\f609";}.fa-location-pen::before {content: "\f607";}.fa-map-marker-edit::before {content: "\f607";}.fa-location-pin::before {content: "\f041";}.fa-map-marker::before {content: "\f041";}.fa-location-pin-lock::before {content: "\e51f";}.fa-location-pin-slash::before {content: "\f60c";}.fa-map-marker-slash::before {content: "\f60c";}.fa-location-plus::before {content: "\f60a";}.fa-map-marker-plus::before {content: "\f60a";}.fa-location-question::before {content: "\f60b";}.fa-map-marker-question::before {content: "\f60b";}.fa-location-smile::before {content: "\f60d";}.fa-map-marker-smile::before {content: "\f60d";}.fa-location-xmark::before {content: "\f60e";}.fa-map-marker-times::before {content: "\f60e";}.fa-map-marker-xmark::before {content: "\f60e";}.fa-lock::before {content: "\f023";}.fa-lock-a::before {content: "\e422";}.fa-lock-hashtag::before {content: "\e423";}.fa-lock-keyhole::before {content: "\f30d";}.fa-lock-alt::before {content: "\f30d";}.fa-lock-keyhole-open::before {content: "\f3c2";}.fa-lock-open-alt::before {content: "\f3c2";}.fa-lock-open::before {content: "\f3c1";}.fa-locust::before {content: "\e520";}.fa-lollipop::before {content: "\e424";}.fa-lollypop::before {content: "\e424";}.fa-loveseat::before {content: "\f4cc";}.fa-couch-small::before {content: "\f4cc";}.fa-luchador-mask::before {content: "\f455";}.fa-luchador::before {content: "\f455";}.fa-mask-luchador::before {content: "\f455";}.fa-lungs::before {content: "\f604";}.fa-lungs-virus::before {content: "\e067";}.fa-m::before {content: "\4d";}.fa-mace::before {content: "\f6f8";}.fa-magnet::before {content: "\f076";}.fa-magnifying-glass::before {content: "\f002";}.fa-search::before {content: "\f002";}.fa-magnifying-glass-arrow-right::before {content: "\e521";}.fa-magnifying-glass-chart::before {content: "\e522";}.fa-magnifying-glass-dollar::before {content: "\f688";}.fa-search-dollar::before {content: "\f688";}.fa-magnifying-glass-location::before {content: "\f689";}.fa-search-location::before {content: "\f689";}.fa-magnifying-glass-minus::before {content: "\f010";}.fa-search-minus::before {content: "\f010";}.fa-magnifying-glass-plus::before {content: "\f00e";}.fa-search-plus::before {content: "\f00e";}.fa-mailbox::before {content: "\f813";}.fa-manat-sign::before {content: "\e1d5";}.fa-mandolin::before {content: "\f6f9";}.fa-mango::before {content: "\e30f";}.fa-manhole::before {content: "\e1d6";}.fa-map::before {content: "\f279";}.fa-map-location::before {content: "\f59f";}.fa-map-marked::before {content: "\f59f";}.fa-map-location-dot::before {content: "\f5a0";}.fa-map-marked-alt::before {content: "\f5a0";}.fa-map-pin::before {content: "\f276";}.fa-marker::before {content: "\f5a1";}.fa-mars::before {content: "\f222";}.fa-mars-and-venus::before {content: "\f224";}.fa-mars-and-venus-burst::before {content: "\e523";}.fa-mars-double::before {content: "\f227";}.fa-mars-stroke::before {content: "\f229";}.fa-mars-stroke-right::before {content: "\f22b";}.fa-mars-stroke-h::before {content: "\f22b";}.fa-mars-stroke-up::before {content: "\f22a";}.fa-mars-stroke-v::before {content: "\f22a";}.fa-martini-glass::before {content: "\f57b";}.fa-glass-martini-alt::before {content: "\f57b";}.fa-martini-glass-citrus::before {content: "\f561";}.fa-cocktail::before {content: "\f561";}.fa-martini-glass-empty::before {content: "\f000";}.fa-glass-martini::before {content: "\f000";}.fa-mask::before {content: "\f6fa";}.fa-mask-face::before {content: "\e1d7";}.fa-mask-snorkel::before {content: "\e3b7";}.fa-mask-ventilator::before {content: "\e524";}.fa-masks-theater::before {content: "\f630";}.fa-theater-masks::before {content: "\f630";}.fa-mattress-pillow::before {content: "\e525";}.fa-maximize::before {content: "\f31e";}.fa-expand-arrows-alt::before {content: "\f31e";}.fa-meat::before {content: "\f814";}.fa-medal::before {content: "\f5a2";}.fa-megaphone::before {content: "\f675";}.fa-melon::before {content: "\e310";}.fa-melon-slice::before {content: "\e311";}.fa-memo::before {content: "\e1d8";}.fa-memo-circle-check::before {content: "\e1d9";}.fa-memo-circle-info::before {content: "\e49a";}.fa-memo-pad::before {content: "\e1da";}.fa-memory::before {content: "\f538";}.fa-menorah::before {content: "\f676";}.fa-mercury::before {content: "\f223";}.fa-merge::before {content: "\e526";}.fa-message::before {content: "\f27a";}.fa-comment-alt::before {content: "\f27a";}.fa-message-arrow-down::before {content: "\e1db";}.fa-comment-alt-arrow-down::before {content: "\e1db";}.fa-message-arrow-up::before {content: "\e1dc";}.fa-comment-alt-arrow-up::before {content: "\e1dc";}.fa-message-arrow-up-right::before {content: "\e1dd";}.fa-message-bot::before {content: "\e3b8";}.fa-message-captions::before {content: "\e1de";}.fa-comment-alt-captions::before {content: "\e1de";}.fa-message-check::before {content: "\f4a2";}.fa-comment-alt-check::before {content: "\f4a2";}.fa-message-code::before {content: "\e1df";}.fa-message-dollar::before {content: "\f650";}.fa-comment-alt-dollar::before {content: "\f650";}.fa-message-dots::before {content: "\f4a3";}.fa-comment-alt-dots::before {content: "\f4a3";}.fa-messaging::before {content: "\f4a3";}.fa-message-exclamation::before {content: "\f4a5";}.fa-comment-alt-exclamation::before {content: "\f4a5";}.fa-message-image::before {content: "\e1e0";}.fa-comment-alt-image::before {content: "\e1e0";}.fa-message-lines::before {content: "\f4a6";}.fa-comment-alt-lines::before {content: "\f4a6";}.fa-message-medical::before {content: "\f7f4";}.fa-comment-alt-medical::before {content: "\f7f4";}.fa-message-middle::before {content: "\e1e1";}.fa-comment-middle-alt::before {content: "\e1e1";}.fa-message-middle-top::before {content: "\e1e2";}.fa-comment-middle-top-alt::before {content: "\e1e2";}.fa-message-minus::before {content: "\f4a7";}.fa-comment-alt-minus::before {content: "\f4a7";}.fa-message-music::before {content: "\f8af";}.fa-comment-alt-music::before {content: "\f8af";}.fa-message-pen::before {content: "\f4a4";}.fa-comment-alt-edit::before {content: "\f4a4";}.fa-message-edit::before {content: "\f4a4";}.fa-message-plus::before {content: "\f4a8";}.fa-comment-alt-plus::before {content: "\f4a8";}.fa-message-question::before {content: "\e1e3";}.fa-message-quote::before {content: "\e1e4";}.fa-comment-alt-quote::before {content: "\e1e4";}.fa-message-slash::before {content: "\f4a9";}.fa-comment-alt-slash::before {content: "\f4a9";}.fa-message-smile::before {content: "\f4aa";}.fa-comment-alt-smile::before {content: "\f4aa";}.fa-message-sms::before {content: "\e1e5";}.fa-message-text::before {content: "\e1e6";}.fa-comment-alt-text::before {content: "\e1e6";}.fa-message-xmark::before {content: "\f4ab";}.fa-comment-alt-times::before {content: "\f4ab";}.fa-message-times::before {content: "\f4ab";}.fa-messages::before {content: "\f4b6";}.fa-comments-alt::before {content: "\f4b6";}.fa-messages-dollar::before {content: "\f652";}.fa-comments-alt-dollar::before {content: "\f652";}.fa-messages-question::before {content: "\e1e7";}.fa-meteor::before {content: "\f753";}.fa-meter::before {content: "\e1e8";}.fa-meter-bolt::before {content: "\e1e9";}.fa-meter-droplet::before {content: "\e1ea";}.fa-meter-fire::before {content: "\e1eb";}.fa-microchip::before {content: "\f2db";}.fa-microchip-ai::before {content: "\e1ec";}.fa-microphone::before {content: "\f130";}.fa-microphone-lines::before {content: "\f3c9";}.fa-microphone-alt::before {content: "\f3c9";}.fa-microphone-lines-slash::before {content: "\f539";}.fa-microphone-alt-slash::before {content: "\f539";}.fa-microphone-slash::before {content: "\f131";}.fa-microphone-stand::before {content: "\f8cb";}.fa-microscope::before {content: "\f610";}.fa-microwave::before {content: "\e01b";}.fa-mill-sign::before {content: "\e1ed";}.fa-minimize::before {content: "\f78c";}.fa-compress-arrows-alt::before {content: "\f78c";}.fa-minus::before {content: "\f068";}.fa-subtract::before {content: "\f068";}.fa-mistletoe::before {content: "\f7b4";}.fa-mitten::before {content: "\f7b5";}.fa-mobile::before {content: "\f3ce";}.fa-mobile-android::before {content: "\f3ce";}.fa-mobile-phone::before {content: "\f3ce";}.fa-mobile-button::before {content: "\f10b";}.fa-mobile-notch::before {content: "\e1ee";}.fa-mobile-iphone::before {content: "\e1ee";}.fa-mobile-retro::before {content: "\e527";}.fa-mobile-screen::before {content: "\f3cf";}.fa-mobile-android-alt::before {content: "\f3cf";}.fa-mobile-screen-button::before {content: "\f3cd";}.fa-mobile-alt::before {content: "\f3cd";}.fa-mobile-signal::before {content: "\e1ef";}.fa-mobile-signal-out::before {content: "\e1f0";}.fa-money-bill::before {content: "\f0d6";}.fa-money-bill-1::before {content: "\f3d1";}.fa-money-bill-alt::before {content: "\f3d1";}.fa-money-bill-1-wave::before {content: "\f53b";}.fa-money-bill-wave-alt::before {content: "\f53b";}.fa-money-bill-simple::before {content: "\e1f1";}.fa-money-bill-simple-wave::before {content: "\e1f2";}.fa-money-bill-transfer::before {content: "\e528";}.fa-money-bill-trend-up::before {content: "\e529";}.fa-money-bill-wave::before {content: "\f53a";}.fa-money-bill-wheat::before {content: "\e52a";}.fa-money-bills::before {content: "\e1f3";}.fa-money-bills-simple::before {content: "\e1f4";}.fa-money-bills-alt::before {content: "\e1f4";}.fa-money-check::before {content: "\f53c";}.fa-money-check-dollar::before {content: "\f53d";}.fa-money-check-alt::before {content: "\f53d";}.fa-money-check-dollar-pen::before {content: "\f873";}.fa-money-check-edit-alt::before {content: "\f873";}.fa-money-check-pen::before {content: "\f872";}.fa-money-check-edit::before {content: "\f872";}.fa-money-from-bracket::before {content: "\e312";}.fa-money-simple-from-bracket::before {content: "\e313";}.fa-monitor-waveform::before {content: "\f611";}.fa-monitor-heart-rate::before {content: "\f611";}.fa-monkey::before {content: "\f6fb";}.fa-monument::before {content: "\f5a6";}.fa-moon::before {content: "\f186";}.fa-moon-cloud::before {content: "\f754";}.fa-moon-over-sun::before {content: "\f74a";}.fa-eclipse-alt::before {content: "\f74a";}.fa-moon-stars::before {content: "\f755";}.fa-moped::before {content: "\e3b9";}.fa-mortar-pestle::before {content: "\f5a7";}.fa-mosque::before {content: "\f678";}.fa-mosquito::before {content: "\e52b";}.fa-mosquito-net::before {content: "\e52c";}.fa-motorcycle::before {content: "\f21c";}.fa-mound::before {content: "\e52d";}.fa-mountain::before {content: "\f6fc";}.fa-mountain-city::before {content: "\e52e";}.fa-mountain-sun::before {content: "\e52f";}.fa-mountains::before {content: "\f6fd";}.fa-mp3-player::before {content: "\f8ce";}.fa-mug::before {content: "\f874";}.fa-mug-hot::before {content: "\f7b6";}.fa-mug-marshmallows::before {content: "\f7b7";}.fa-mug-saucer::before {content: "\f0f4";}.fa-coffee::before {content: "\f0f4";}.fa-mug-tea::before {content: "\f875";}.fa-mug-tea-saucer::before {content: "\e1f5";}.fa-mushroom::before {content: "\e425";}.fa-music::before {content: "\f001";}.fa-music-note::before {content: "\f8cf";}.fa-music-alt::before {content: "\f8cf";}.fa-music-note-slash::before {content: "\f8d0";}.fa-music-alt-slash::before {content: "\f8d0";}.fa-music-slash::before {content: "\f8d1";}.fa-n::before {content: "\4e";}.fa-naira-sign::before {content: "\e1f6";}.fa-narwhal::before {content: "\f6fe";}.fa-nesting-dolls::before {content: "\e3ba";}.fa-network-wired::before {content: "\f6ff";}.fa-neuter::before {content: "\f22c";}.fa-newspaper::before {content: "\f1ea";}.fa-nfc::before {content: "\e1f7";}.fa-nfc-lock::before {content: "\e1f8";}.fa-nfc-magnifying-glass::before {content: "\e1f9";}.fa-nfc-pen::before {content: "\e1fa";}.fa-nfc-signal::before {content: "\e1fb";}.fa-nfc-slash::before {content: "\e1fc";}.fa-nfc-trash::before {content: "\e1fd";}.fa-not-equal::before {content: "\f53e";}.fa-notdef::before {content: "\e1fe";}.fa-note::before {content: "\e1ff";}.fa-note-medical::before {content: "\e200";}.fa-note-sticky::before {content: "\f249";}.fa-sticky-note::before {content: "\f249";}.fa-notebook::before {content: "\e201";}.fa-notes::before {content: "\e202";}.fa-notes-medical::before {content: "\f481";}.fa-o::before {content: "\4f";}.fa-object-exclude::before {content: "\e49c";}.fa-object-group::before {content: "\f247";}.fa-object-intersect::before {content: "\e49d";}.fa-object-subtract::before {content: "\e49e";}.fa-object-ungroup::before {content: "\f248";}.fa-object-union::before {content: "\e49f";}.fa-objects-align-bottom::before {content: "\e3bb";}.fa-objects-align-center-horizontal::before {content: "\e3bc";}.fa-objects-align-center-vertical::before {content: "\e3bd";}.fa-objects-align-left::before {content: "\e3be";}.fa-objects-align-right::before {content: "\e3bf";}.fa-objects-align-top::before {content: "\e3c0";}.fa-objects-column::before {content: "\e3c1";}.fa-octagon::before {content: "\f306";}.fa-octagon-check::before {content: "\e426";}.fa-octagon-divide::before {content: "\e203";}.fa-octagon-exclamation::before {content: "\e204";}.fa-octagon-minus::before {content: "\f308";}.fa-minus-octagon::before {content: "\f308";}.fa-octagon-plus::before {content: "\f301";}.fa-plus-octagon::before {content: "\f301";}.fa-octagon-xmark::before {content: "\f2f0";}.fa-times-octagon::before {content: "\f2f0";}.fa-xmark-octagon::before {content: "\f2f0";}.fa-oil-can::before {content: "\f613";}.fa-oil-can-drip::before {content: "\e205";}.fa-oil-temperature::before {content: "\f614";}.fa-oil-temp::before {content: "\f614";}.fa-oil-well::before {content: "\e532";}.fa-olive::before {content: "\e316";}.fa-olive-branch::before {content: "\e317";}.fa-om::before {content: "\f679";}.fa-omega::before {content: "\f67a";}.fa-onion::before {content: "\e427";}.fa-option::before {content: "\e318";}.fa-ornament::before {content: "\f7b8";}.fa-otter::before {content: "\f700";}.fa-outdent::before {content: "\f03b";}.fa-dedent::before {content: "\f03b";}.fa-outlet::before {content: "\e01c";}.fa-oven::before {content: "\e01d";}.fa-overline::before {content: "\f876";}.fa-p::before {content: "\50";}.fa-page::before {content: "\e428";}.fa-page-caret-down::before {content: "\e429";}.fa-file-caret-down::before {content: "\e429";}.fa-page-caret-up::before {content: "\e42a";}.fa-file-caret-up::before {content: "\e42a";}.fa-pager::before {content: "\f815";}.fa-paint-roller::before {content: "\f5aa";}.fa-paintbrush::before {content: "\f1fc";}.fa-paint-brush::before {content: "\f1fc";}.fa-paintbrush-fine::before {content: "\f5a9";}.fa-paint-brush-alt::before {content: "\f5a9";}.fa-paint-brush-fine::before {content: "\f5a9";}.fa-paintbrush-alt::before {content: "\f5a9";}.fa-paintbrush-pencil::before {content: "\e206";}.fa-palette::before {content: "\f53f";}.fa-pallet::before {content: "\f482";}.fa-pallet-box::before {content: "\e208";}.fa-pallet-boxes::before {content: "\f483";}.fa-palette-boxes::before {content: "\f483";}.fa-pallet-alt::before {content: "\f483";}.fa-pan-food::before {content: "\e42b";}.fa-pan-frying::before {content: "\e42c";}.fa-pancakes::before {content: "\e42d";}.fa-panel-ews::before {content: "\e42e";}.fa-panel-fire::before {content: "\e42f";}.fa-panorama::before {content: "\e209";}.fa-paper-plane::before {content: "\f1d8";}.fa-paper-plane-top::before {content: "\e20a";}.fa-paper-plane-alt::before {content: "\e20a";}.fa-send::before {content: "\e20a";}.fa-paperclip::before {content: "\f0c6";}.fa-paperclip-vertical::before {content: "\e3c2";}.fa-parachute-box::before {content: "\f4cd";}.fa-paragraph::before {content: "\f1dd";}.fa-paragraph-left::before {content: "\f878";}.fa-paragraph-rtl::before {content: "\f878";}.fa-party-bell::before {content: "\e31a";}.fa-party-horn::before {content: "\e31b";}.fa-passport::before {content: "\f5ab";}.fa-paste::before {content: "\f0ea";}.fa-file-clipboard::before {content: "\f0ea";}.fa-pause::before {content: "\f04c";}.fa-paw::before {content: "\f1b0";}.fa-paw-claws::before {content: "\f702";}.fa-paw-simple::before {content: "\f701";}.fa-paw-alt::before {content: "\f701";}.fa-peace::before {content: "\f67c";}.fa-peach::before {content: "\e20b";}.fa-peanut::before {content: "\e430";}.fa-peanuts::before {content: "\e431";}.fa-peapod::before {content: "\e31c";}.fa-pear::before {content: "\e20c";}.fa-pedestal::before {content: "\e20d";}.fa-pegasus::before {content: "\f703";}.fa-pen::before {content: "\f304";}.fa-pen-circle::before {content: "\e20e";}.fa-pen-clip::before {content: "\f305";}.fa-pen-alt::before {content: "\f305";}.fa-pen-clip-slash::before {content: "\e20f";}.fa-pen-alt-slash::before {content: "\e20f";}.fa-pen-fancy::before {content: "\f5ac";}.fa-pen-fancy-slash::before {content: "\e210";}.fa-pen-field::before {content: "\e211";}.fa-pen-line::before {content: "\e212";}.fa-pen-nib::before {content: "\f5ad";}.fa-pen-nib-slash::before {content: "\e4a1";}.fa-pen-paintbrush::before {content: "\f618";}.fa-pencil-paintbrush::before {content: "\f618";}.fa-pen-ruler::before {content: "\f5ae";}.fa-pencil-ruler::before {content: "\f5ae";}.fa-pen-slash::before {content: "\e213";}.fa-pen-swirl::before {content: "\e214";}.fa-pen-to-square::before {content: "\f044";}.fa-edit::before {content: "\f044";}.fa-pencil::before {content: "\f303";}.fa-pencil-alt::before {content: "\f303";}.fa-pencil-slash::before {content: "\e215";}.fa-people::before {content: "\e216";}.fa-people-arrows-left-right::before {content: "\e068";}.fa-people-arrows::before {content: "\e068";}.fa-people-carry-box::before {content: "\f4ce";}.fa-people-carry::before {content: "\f4ce";}.fa-people-dress::before {content: "\e217";}.fa-people-dress-simple::before {content: "\e218";}.fa-people-group::before {content: "\e533";}.fa-people-line::before {content: "\e534";}.fa-people-pants::before {content: "\e219";}.fa-people-pants-simple::before {content: "\e21a";}.fa-people-pulling::before {content: "\e535";}.fa-people-robbery::before {content: "\e536";}.fa-people-roof::before {content: "\e537";}.fa-people-simple::before {content: "\e21b";}.fa-pepper::before {content: "\e432";}.fa-pepper-hot::before {content: "\f816";}.fa-percent::before {content: "\25";}.fa-percentage::before {content: "\25";}.fa-period::before {content: "\2e";}.fa-person::before {content: "\f183";}.fa-male::before {content: "\f183";}.fa-person-arrow-down-to-line::before {content: "\e538";}.fa-person-arrow-up-from-line::before {content: "\e539";}.fa-person-biking::before {content: "\f84a";}.fa-biking::before {content: "\f84a";}.fa-person-biking-mountain::before {content: "\f84b";}.fa-biking-mountain::before {content: "\f84b";}.fa-person-booth::before {content: "\f756";}.fa-person-breastfeeding::before {content: "\e53a";}.fa-person-burst::before {content: "\e53b";}.fa-person-cane::before {content: "\e53c";}.fa-person-carry-box::before {content: "\f4cf";}.fa-person-carry::before {content: "\f4cf";}.fa-person-chalkboard::before {content: "\e53d";}.fa-person-circle-check::before {content: "\e53e";}.fa-person-circle-exclamation::before {content: "\e53f";}.fa-person-circle-minus::before {content: "\e540";}.fa-person-circle-plus::before {content: "\e541";}.fa-person-circle-question::before {content: "\e542";}.fa-person-circle-xmark::before {content: "\e543";}.fa-person-digging::before {content: "\f85e";}.fa-digging::before {content: "\f85e";}.fa-person-dolly::before {content: "\f4d0";}.fa-person-dolly-empty::before {content: "\f4d1";}.fa-person-dots-from-line::before {content: "\f470";}.fa-diagnoses::before {content: "\f470";}.fa-person-dress::before {content: "\f182";}.fa-female::before {content: "\f182";}.fa-person-dress-burst::before {content: "\e544";}.fa-person-dress-simple::before {content: "\e21c";}.fa-person-drowning::before {content: "\e545";}.fa-person-falling::before {content: "\e546";}.fa-person-falling-burst::before {content: "\e547";}.fa-person-from-portal::before {content: "\e023";}.fa-portal-exit::before {content: "\e023";}.fa-person-half-dress::before {content: "\e548";}.fa-person-harassing::before {content: "\e549";}.fa-person-hiking::before {content: "\f6ec";}.fa-hiking::before {content: "\f6ec";}.fa-person-military-pointing::before {content: "\e54a";}.fa-person-military-rifle::before {content: "\e54b";}.fa-person-military-to-person::before {content: "\e54c";}.fa-person-pinball::before {content: "\e21d";}.fa-person-praying::before {content: "\f683";}.fa-pray::before {content: "\f683";}.fa-person-pregnant::before {content: "\e31e";}.fa-person-rays::before {content: "\e54d";}.fa-person-rifle::before {content: "\e54e";}.fa-person-running::before {content: "\f70c";}.fa-running::before {content: "\f70c";}.fa-person-seat::before {content: "\e21e";}.fa-person-seat-reclined::before {content: "\e21f";}.fa-person-shelter::before {content: "\e54f";}.fa-person-sign::before {content: "\f757";}.fa-person-simple::before {content: "\e220";}.fa-person-skating::before {content: "\f7c5";}.fa-skating::before {content: "\f7c5";}.fa-person-ski-jumping::before {content: "\f7c7";}.fa-ski-jump::before {content: "\f7c7";}.fa-person-ski-lift::before {content: "\f7c8";}.fa-ski-lift::before {content: "\f7c8";}.fa-person-skiing::before {content: "\f7c9";}.fa-skiing::before {content: "\f7c9";}.fa-person-skiing-nordic::before {content: "\f7ca";}.fa-skiing-nordic::before {content: "\f7ca";}.fa-person-sledding::before {content: "\f7cb";}.fa-sledding::before {content: "\f7cb";}.fa-person-snowboarding::before {content: "\f7ce";}.fa-snowboarding::before {content: "\f7ce";}.fa-person-snowmobiling::before {content: "\f7d1";}.fa-snowmobile::before {content: "\f7d1";}.fa-person-swimming::before {content: "\f5c4";}.fa-swimmer::before {content: "\f5c4";}.fa-person-through-window::before {content: "\e433";}.fa-person-to-door::before {content: "\e550";}.fa-person-to-portal::before {content: "\e022";}.fa-portal-enter::before {content: "\e022";}.fa-person-walking::before {content: "\f554";}.fa-walking::before {content: "\f554";}.fa-person-walking-arrow-loop-left::before {content: "\e551";}.fa-person-walking-arrow-right::before {content: "\e552";}.fa-person-walking-dashed-line-arrow-right::before {content: "\e553";}.fa-person-walking-luggage::before {content: "\e554";}.fa-person-walking-with-cane::before {content: "\f29d";}.fa-blind::before {content: "\f29d";}.fa-peseta-sign::before {content: "\e221";}.fa-peso-sign::before {content: "\e222";}.fa-phone::before {content: "\f095";}.fa-phone-arrow-down-left::before {content: "\e223";}.fa-phone-arrow-down::before {content: "\e223";}.fa-phone-incoming::before {content: "\e223";}.fa-phone-arrow-up-right::before {content: "\e224";}.fa-phone-arrow-up::before {content: "\e224";}.fa-phone-outgoing::before {content: "\e224";}.fa-phone-flip::before {content: "\f879";}.fa-phone-alt::before {content: "\f879";}.fa-phone-hangup::before {content: "\e225";}.fa-phone-intercom::before {content: "\e434";}.fa-phone-missed::before {content: "\e226";}.fa-phone-office::before {content: "\f67d";}.fa-phone-plus::before {content: "\f4d2";}.fa-phone-rotary::before {content: "\f8d3";}.fa-phone-slash::before {content: "\f3dd";}.fa-phone-volume::before {content: "\f2a0";}.fa-volume-control-phone::before {content: "\f2a0";}.fa-phone-xmark::before {content: "\e227";}.fa-photo-film::before {content: "\f87c";}.fa-photo-video::before {content: "\f87c";}.fa-photo-film-music::before {content: "\e228";}.fa-pi::before {content: "\f67e";}.fa-piano::before {content: "\f8d4";}.fa-piano-keyboard::before {content: "\f8d5";}.fa-pickleball::before {content: "\e435";}.fa-pie::before {content: "\f705";}.fa-pig::before {content: "\f706";}.fa-piggy-bank::before {content: "\f4d3";}.fa-pills::before {content: "\f484";}.fa-pinata::before {content: "\e3c3";}.fa-pinball::before {content: "\e229";}.fa-pineapple::before {content: "\e31f";}.fa-pipe::before {content: "\7c";}.fa-pipe-circle-check::before {content: "\e436";}.fa-pipe-collar::before {content: "\e437";}.fa-pipe-section::before {content: "\e438";}.fa-pipe-smoking::before {content: "\e3c4";}.fa-pipe-valve::before {content: "\e439";}.fa-pizza::before {content: "\f817";}.fa-pizza-slice::before {content: "\f818";}.fa-place-of-worship::before {content: "\f67f";}.fa-plane::before {content: "\f072";}.fa-plane-arrival::before {content: "\f5af";}.fa-plane-circle-check::before {content: "\e555";}.fa-plane-circle-exclamation::before {content: "\e556";}.fa-plane-circle-xmark::before {content: "\e557";}.fa-plane-departure::before {content: "\f5b0";}.fa-plane-engines::before {content: "\f3de";}.fa-plane-alt::before {content: "\f3de";}.fa-plane-lock::before {content: "\e558";}.fa-plane-prop::before {content: "\e22b";}.fa-plane-slash::before {content: "\e069";}.fa-plane-tail::before {content: "\e22c";}.fa-plane-up::before {content: "\e22d";}.fa-plane-up-slash::before {content: "\e22e";}.fa-planet-moon::before {content: "\e01f";}.fa-planet-ringed::before {content: "\e020";}.fa-plant-wilt::before {content: "\e43b";}.fa-plate-utensils::before {content: "\e559";}.fa-plate-wheat::before {content: "\e55a";}.fa-play::before {content: "\f04b";}.fa-play-pause::before {content: "\e22f";}.fa-plug::before {content: "\f1e6";}.fa-plug-circle-bolt::before {content: "\e55b";}.fa-plug-circle-check::before {content: "\e55c";}.fa-plug-circle-exclamation::before {content: "\e55d";}.fa-plug-circle-minus::before {content: "\e55e";}.fa-plug-circle-plus::before {content: "\e55f";}.fa-plug-circle-xmark::before {content: "\e560";}.fa-plus::before {content: "\2b";}.fa-add::before {content: "\2b";}.fa-plus-large::before {content: "\e59e";}.fa-plus-minus::before {content: "\e43c";}.fa-podcast::before {content: "\f2ce";}.fa-podium::before {content: "\f680";}.fa-podium-star::before {content: "\f758";}.fa-police-box::before {content: "\e021";}.fa-poll-people::before {content: "\f759";}.fa-pompebled::before {content: "\e43d";}.fa-poo::before {content: "\f2fe";}.fa-poo-storm::before {content: "\f75a";}.fa-poo-bolt::before {content: "\f75a";}.fa-pool-8-ball::before {content: "\e3c5";}.fa-poop::before {content: "\f619";}.fa-popcorn::before {content: "\f819";}.fa-popsicle::before {content: "\e43e";}.fa-pot-food::before {content: "\e43f";}.fa-potato::before {content: "\e440";}.fa-power-off::before {content: "\f011";}.fa-prescription::before {content: "\f5b1";}.fa-prescription-bottle::before {content: "\f485";}.fa-prescription-bottle-medical::before {content: "\f486";}.fa-prescription-bottle-alt::before {content: "\f486";}.fa-presentation-screen::before {content: "\f685";}.fa-presentation::before {content: "\f685";}.fa-pretzel::before {content: "\e441";}.fa-print::before {content: "\f02f";}.fa-print-magnifying-glass::before {content: "\f81a";}.fa-print-search::before {content: "\f81a";}.fa-print-slash::before {content: "\f686";}.fa-projector::before {content: "\f8d6";}.fa-pump::before {content: "\e442";}.fa-pump-medical::before {content: "\e06a";}.fa-pump-soap::before {content: "\e06b";}.fa-pumpkin::before {content: "\f707";}.fa-puzzle::before {content: "\e443";}.fa-puzzle-piece::before {content: "\f12e";}.fa-puzzle-piece-simple::before {content: "\e231";}.fa-puzzle-piece-alt::before {content: "\e231";}.fa-q::before {content: "\51";}.fa-qrcode::before {content: "\f029";}.fa-question::before {content: "\3f";}.fa-quote-left::before {content: "\f10d";}.fa-quote-left-alt::before {content: "\f10d";}.fa-quote-right::before {content: "\f10e";}.fa-quote-right-alt::before {content: "\f10e";}.fa-quotes::before {content: "\e234";}.fa-r::before {content: "\52";}.fa-rabbit::before {content: "\f708";}.fa-rabbit-running::before {content: "\f709";}.fa-rabbit-fast::before {content: "\f709";}.fa-racquet::before {content: "\f45a";}.fa-radar::before {content: "\e024";}.fa-radiation::before {content: "\f7b9";}.fa-radio::before {content: "\f8d7";}.fa-radio-tuner::before {content: "\f8d8";}.fa-radio-alt::before {content: "\f8d8";}.fa-rainbow::before {content: "\f75b";}.fa-raindrops::before {content: "\f75c";}.fa-ram::before {content: "\f70a";}.fa-ramp-loading::before {content: "\f4d4";}.fa-ranking-star::before {content: "\e561";}.fa-raygun::before {content: "\e025";}.fa-receipt::before {content: "\f543";}.fa-record-vinyl::before {content: "\f8d9";}.fa-rectangle::before {content: "\f2fa";}.fa-rectangle-landscape::before {content: "\f2fa";}.fa-rectangle-ad::before {content: "\f641";}.fa-ad::before {content: "\f641";}.fa-rectangle-barcode::before {content: "\f463";}.fa-barcode-alt::before {content: "\f463";}.fa-rectangle-code::before {content: "\e322";}.fa-rectangle-history::before {content: "\e4a2";}.fa-rectangle-history-circle-plus::before {content: "\e4a3";}.fa-rectangle-history-circle-user::before {content: "\e4a4";}.fa-rectangle-list::before {content: "\f022";}.fa-list-alt::before {content: "\f022";}.fa-rectangle-pro::before {content: "\e235";}.fa-pro::before {content: "\e235";}.fa-rectangle-terminal::before {content: "\e236";}.fa-rectangle-vertical::before {content: "\f2fb";}.fa-rectangle-portrait::before {content: "\f2fb";}.fa-rectangle-vertical-history::before {content: "\e237";}.fa-rectangle-wide::before {content: "\f2fc";}.fa-rectangle-xmark::before {content: "\f410";}.fa-rectangle-times::before {content: "\f410";}.fa-times-rectangle::before {content: "\f410";}.fa-window-close::before {content: "\f410";}.fa-rectangles-mixed::before {content: "\e323";}.fa-recycle::before {content: "\f1b8";}.fa-reel::before {content: "\e238";}.fa-refrigerator::before {content: "\e026";}.fa-registered::before {content: "\f25d";}.fa-repeat::before {content: "\f363";}.fa-repeat-1::before {content: "\f365";}.fa-reply::before {content: "\f3e5";}.fa-mail-reply::before {content: "\f3e5";}.fa-reply-all::before {content: "\f122";}.fa-mail-reply-all::before {content: "\f122";}.fa-reply-clock::before {content: "\e239";}.fa-reply-time::before {content: "\e239";}.fa-republican::before {content: "\f75e";}.fa-restroom::before {content: "\f7bd";}.fa-restroom-simple::before {content: "\e23a";}.fa-retweet::before {content: "\f079";}.fa-rhombus::before {content: "\e23b";}.fa-ribbon::before {content: "\f4d6";}.fa-right::before {content: "\f356";}.fa-arrow-alt-right::before {content: "\f356";}.fa-right-from-bracket::before {content: "\f2f5";}.fa-sign-out-alt::before {content: "\f2f5";}.fa-right-from-line::before {content: "\f347";}.fa-arrow-alt-from-left::before {content: "\f347";}.fa-right-left::before {content: "\f362";}.fa-exchange-alt::before {content: "\f362";}.fa-right-long::before {content: "\f30b";}.fa-long-arrow-alt-right::before {content: "\f30b";}.fa-right-long-to-line::before {content: "\e444";}.fa-right-to-bracket::before {content: "\f2f6";}.fa-sign-in-alt::before {content: "\f2f6";}.fa-right-to-line::before {content: "\f34c";}.fa-arrow-alt-to-right::before {content: "\f34c";}.fa-ring::before {content: "\f70b";}.fa-rings-wedding::before {content: "\f81b";}.fa-road::before {content: "\f018";}.fa-road-barrier::before {content: "\e562";}.fa-road-bridge::before {content: "\e563";}.fa-road-circle-check::before {content: "\e564";}.fa-road-circle-exclamation::before {content: "\e565";}.fa-road-circle-xmark::before {content: "\e566";}.fa-road-lock::before {content: "\e567";}.fa-road-spikes::before {content: "\e568";}.fa-robot::before {content: "\f544";}.fa-robot-astromech::before {content: "\e2d2";}.fa-rocket::before {content: "\f135";}.fa-rocket-launch::before {content: "\e027";}.fa-roller-coaster::before {content: "\e324";}.fa-rotate::before {content: "\f2f1";}.fa-sync-alt::before {content: "\f2f1";}.fa-rotate-exclamation::before {content: "\e23c";}.fa-rotate-left::before {content: "\f2ea";}.fa-rotate-back::before {content: "\f2ea";}.fa-rotate-backward::before {content: "\f2ea";}.fa-undo-alt::before {content: "\f2ea";}.fa-rotate-right::before {content: "\f2f9";}.fa-redo-alt::before {content: "\f2f9";}.fa-rotate-forward::before {content: "\f2f9";}.fa-route::before {content: "\f4d7";}.fa-route-highway::before {content: "\f61a";}.fa-route-interstate::before {content: "\f61b";}.fa-router::before {content: "\f8da";}.fa-rss::before {content: "\f09e";}.fa-feed::before {content: "\f09e";}.fa-ruble-sign::before {content: "\f158";}.fa-rouble::before {content: "\f158";}.fa-rub::before {content: "\f158";}.fa-ruble::before {content: "\f158";}.fa-rug::before {content: "\e569";}.fa-rugby-ball::before {content: "\e3c6";}.fa-ruler::before {content: "\f545";}.fa-ruler-combined::before {content: "\f546";}.fa-ruler-horizontal::before {content: "\f547";}.fa-ruler-triangle::before {content: "\f61c";}.fa-ruler-vertical::before {content: "\f548";}.fa-rupee-sign::before {content: "\f156";}.fa-rupee::before {content: "\f156";}.fa-rupiah-sign::before {content: "\e23d";}.fa-rv::before {content: "\f7be";}.fa-s::before {content: "\53";}.fa-sack::before {content: "\f81c";}.fa-sack-dollar::before {content: "\f81d";}.fa-sack-xmark::before {content: "\e56a";}.fa-sailboat::before {content: "\e445";}.fa-salad::before {content: "\f81e";}.fa-bowl-salad::before {content: "\f81e";}.fa-salt-shaker::before {content: "\e446";}.fa-sandwich::before {content: "\f81f";}.fa-satellite::before {content: "\f7bf";}.fa-satellite-dish::before {content: "\f7c0";}.fa-sausage::before {content: "\f820";}.fa-saxophone::before {content: "\f8dc";}.fa-saxophone-fire::before {content: "\f8db";}.fa-sax-hot::before {content: "\f8db";}.fa-scale-balanced::before {content: "\f24e";}.fa-balance-scale::before {content: "\f24e";}.fa-scale-unbalanced::before {content: "\f515";}.fa-balance-scale-left::before {content: "\f515";}.fa-scale-unbalanced-flip::before {content: "\f516";}.fa-balance-scale-right::before {content: "\f516";}.fa-scalpel::before {content: "\f61d";}.fa-scalpel-line-dashed::before {content: "\f61e";}.fa-scalpel-path::before {content: "\f61e";}.fa-scanner::before {content: "\f8f3";}.fa-scanner-image::before {content: "\f8f3";}.fa-scanner-gun::before {content: "\f488";}.fa-scanner-keyboard::before {content: "\f489";}.fa-scanner-touchscreen::before {content: "\f48a";}.fa-scarecrow::before {content: "\f70d";}.fa-scarf::before {content: "\f7c1";}.fa-school::before {content: "\f549";}.fa-school-circle-check::before {content: "\e56b";}.fa-school-circle-exclamation::before {content: "\e56c";}.fa-school-circle-xmark::before {content: "\e56d";}.fa-school-flag::before {content: "\e56e";}.fa-school-lock::before {content: "\e56f";}.fa-scissors::before {content: "\f0c4";}.fa-cut::before {content: "\f0c4";}.fa-screen-users::before {content: "\f63d";}.fa-users-class::before {content: "\f63d";}.fa-screencast::before {content: "\e23e";}.fa-screwdriver::before {content: "\f54a";}.fa-screwdriver-wrench::before {content: "\f7d9";}.fa-tools::before {content: "\f7d9";}.fa-scribble::before {content: "\e23f";}.fa-scroll::before {content: "\f70e";}.fa-scroll-old::before {content: "\f70f";}.fa-scroll-torah::before {content: "\f6a0";}.fa-torah::before {content: "\f6a0";}.fa-scrubber::before {content: "\f2f8";}.fa-scythe::before {content: "\f710";}.fa-sd-card::before {content: "\f7c2";}.fa-sd-cards::before {content: "\e240";}.fa-seal::before {content: "\e241";}.fa-seal-exclamation::before {content: "\e242";}.fa-seal-question::before {content: "\e243";}.fa-seat-airline::before {content: "\e244";}.fa-section::before {content: "\e447";}.fa-seedling::before {content: "\f4d8";}.fa-sprout::before {content: "\f4d8";}.fa-semicolon::before {content: "\3b";}.fa-send-back::before {content: "\f87e";}.fa-send-backward::before {content: "\f87f";}.fa-sensor::before {content: "\e028";}.fa-sensor-cloud::before {content: "\e02c";}.fa-sensor-smoke::before {content: "\e02c";}.fa-sensor-fire::before {content: "\e02a";}.fa-sensor-on::before {content: "\e02b";}.fa-sensor-triangle-exclamation::before {content: "\e029";}.fa-sensor-alert::before {content: "\e029";}.fa-server::before {content: "\f233";}.fa-shapes::before {content: "\f61f";}.fa-triangle-circle-square::before {content: "\f61f";}.fa-share::before {content: "\f064";}.fa-arrow-turn-right::before {content: "\f064";}.fa-mail-forward::before {content: "\f064";}.fa-share-all::before {content: "\f367";}.fa-share-from-square::before {content: "\f14d";}.fa-share-square::before {content: "\f14d";}.fa-share-nodes::before {content: "\f1e0";}.fa-share-alt::before {content: "\f1e0";}.fa-sheep::before {content: "\f711";}.fa-sheet-plastic::before {content: "\e571";}.fa-shekel-sign::before {content: "\f20b";}.fa-ils::before {content: "\f20b";}.fa-shekel::before {content: "\f20b";}.fa-sheqel::before {content: "\f20b";}.fa-sheqel-sign::before {content: "\f20b";}.fa-shelves::before {content: "\f480";}.fa-inventory::before {content: "\f480";}.fa-shelves-empty::before {content: "\e246";}.fa-shield::before {content: "\f132";}.fa-shield-blank::before {content: "\f132";}.fa-shield-cat::before {content: "\e572";}.fa-shield-check::before {content: "\f2f7";}.fa-shield-cross::before {content: "\f712";}.fa-shield-dog::before {content: "\e573";}.fa-shield-exclamation::before {content: "\e247";}.fa-shield-halved::before {content: "\f3ed";}.fa-shield-alt::before {content: "\f3ed";}.fa-shield-heart::before {content: "\e574";}.fa-shield-keyhole::before {content: "\e248";}.fa-shield-minus::before {content: "\e249";}.fa-shield-plus::before {content: "\e24a";}.fa-shield-quartered::before {content: "\e575";}.fa-shield-slash::before {content: "\e24b";}.fa-shield-virus::before {content: "\e06c";}.fa-shield-xmark::before {content: "\e24c";}.fa-shield-times::before {content: "\e24c";}.fa-ship::before {content: "\f21a";}.fa-shirt::before {content: "\f553";}.fa-t-shirt::before {content: "\f553";}.fa-tshirt::before {content: "\f553";}.fa-shirt-long-sleeve::before {content: "\e3c7";}.fa-shirt-running::before {content: "\e3c8";}.fa-shirt-tank-top::before {content: "\e3c9";}.fa-shish-kebab::before {content: "\f821";}.fa-shoe-prints::before {content: "\f54b";}.fa-shop::before {content: "\f54f";}.fa-store-alt::before {content: "\f54f";}.fa-shop-lock::before {content: "\e4a5";}.fa-shop-slash::before {content: "\e070";}.fa-store-alt-slash::before {content: "\e070";}.fa-shovel::before {content: "\f713";}.fa-shovel-snow::before {content: "\f7c3";}.fa-shower::before {content: "\f2cc";}.fa-shower-down::before {content: "\e24d";}.fa-shower-alt::before {content: "\e24d";}.fa-shredder::before {content: "\f68a";}.fa-shrimp::before {content: "\e448";}.fa-shuffle::before {content: "\f074";}.fa-random::before {content: "\f074";}.fa-shutters::before {content: "\e449";}.fa-shuttle-space::before {content: "\f197";}.fa-space-shuttle::before {content: "\f197";}.fa-shuttlecock::before {content: "\f45b";}.fa-sickle::before {content: "\f822";}.fa-sidebar::before {content: "\e24e";}.fa-sidebar-flip::before {content: "\e24f";}.fa-sigma::before {content: "\f68b";}.fa-sign-hanging::before {content: "\f4d9";}.fa-sign::before {content: "\f4d9";}.fa-signal::before {content: "\f012";}.fa-signal-5::before {content: "\f012";}.fa-signal-perfect::before {content: "\f012";}.fa-signal-bars::before {content: "\f690";}.fa-signal-alt::before {content: "\f690";}.fa-signal-alt-4::before {content: "\f690";}.fa-signal-bars-strong::before {content: "\f690";}.fa-signal-bars-fair::before {content: "\f692";}.fa-signal-alt-2::before {content: "\f692";}.fa-signal-bars-good::before {content: "\f693";}.fa-signal-alt-3::before {content: "\f693";}.fa-signal-bars-slash::before {content: "\f694";}.fa-signal-alt-slash::before {content: "\f694";}.fa-signal-bars-weak::before {content: "\f691";}.fa-signal-alt-1::before {content: "\f691";}.fa-signal-fair::before {content: "\f68d";}.fa-signal-2::before {content: "\f68d";}.fa-signal-good::before {content: "\f68e";}.fa-signal-3::before {content: "\f68e";}.fa-signal-slash::before {content: "\f695";}.fa-signal-stream::before {content: "\f8dd";}.fa-signal-stream-slash::before {content: "\e250";}.fa-signal-strong::before {content: "\f68f";}.fa-signal-4::before {content: "\f68f";}.fa-signal-weak::before {content: "\f68c";}.fa-signal-1::before {content: "\f68c";}.fa-signature::before {content: "\f5b7";}.fa-signature-lock::before {content: "\e3ca";}.fa-signature-slash::before {content: "\e3cb";}.fa-signs-post::before {content: "\f277";}.fa-map-signs::before {content: "\f277";}.fa-sim-card::before {content: "\f7c4";}.fa-sim-cards::before {content: "\e251";}.fa-sink::before {content: "\e06d";}.fa-siren::before {content: "\e02d";}.fa-siren-on::before {content: "\e02e";}.fa-sitemap::before {content: "\f0e8";}.fa-skeleton::before {content: "\f620";}.fa-ski-boot::before {content: "\e3cc";}.fa-ski-boot-ski::before {content: "\e3cd";}.fa-skull::before {content: "\f54c";}.fa-skull-cow::before {content: "\f8de";}.fa-skull-crossbones::before {content: "\f714";}.fa-slash::before {content: "\f715";}.fa-slash-back::before {content: "\5c";}.fa-slash-forward::before {content: "\2f";}.fa-sleigh::before {content: "\f7cc";}.fa-slider::before {content: "\e252";}.fa-sliders::before {content: "\f1de";}.fa-sliders-h::before {content: "\f1de";}.fa-sliders-simple::before {content: "\e253";}.fa-sliders-up::before {content: "\f3f1";}.fa-sliders-v::before {content: "\f3f1";}.fa-slot-machine::before {content: "\e3ce";}.fa-smog::before {content: "\f75f";}.fa-smoke::before {content: "\f760";}.fa-smoking::before {content: "\f48d";}.fa-snake::before {content: "\f716";}.fa-snooze::before {content: "\f880";}.fa-zzz::before {content: "\f880";}.fa-snow-blowing::before {content: "\f761";}.fa-snowflake::before {content: "\f2dc";}.fa-snowflakes::before {content: "\f7cf";}.fa-snowman::before {content: "\f7d0";}.fa-snowman-head::before {content: "\f79b";}.fa-frosty-head::before {content: "\f79b";}.fa-snowplow::before {content: "\f7d2";}.fa-soap::before {content: "\e06e";}.fa-socks::before {content: "\f696";}.fa-soft-serve::before {content: "\e400";}.fa-creemee::before {content: "\e400";}.fa-solar-panel::before {content: "\f5ba";}.fa-solar-system::before {content: "\e02f";}.fa-sort::before {content: "\f0dc";}.fa-unsorted::before {content: "\f0dc";}.fa-sort-down::before {content: "\f0dd";}.fa-sort-desc::before {content: "\f0dd";}.fa-sort-up::before {content: "\f0de";}.fa-sort-asc::before {content: "\f0de";}.fa-spa::before {content: "\f5bb";}.fa-space-station-moon::before {content: "\e033";}.fa-space-station-moon-construction::before {content: "\e034";}.fa-space-station-moon-alt::before {content: "\e034";}.fa-spade::before {content: "\f2f4";}.fa-spaghetti-monster-flying::before {content: "\f67b";}.fa-pastafarianism::before {content: "\f67b";}.fa-sparkles::before {content: "\f890";}.fa-speaker::before {content: "\f8df";}.fa-speakers::before {content: "\f8e0";}.fa-spell-check::before {content: "\f891";}.fa-spider::before {content: "\f717";}.fa-spider-black-widow::before {content: "\f718";}.fa-spider-web::before {content: "\f719";}.fa-spinner::before {content: "\f110";}.fa-spinner-third::before {content: "\f3f4";}.fa-split::before {content: "\e254";}.fa-splotch::before {content: "\f5bc";}.fa-spoon::before {content: "\f2e5";}.fa-utensil-spoon::before {content: "\f2e5";}.fa-sportsball::before {content: "\e44b";}.fa-spray-can::before {content: "\f5bd";}.fa-spray-can-sparkles::before {content: "\f5d0";}.fa-air-freshener::before {content: "\f5d0";}.fa-sprinkler::before {content: "\e035";}.fa-sprinkler-ceiling::before {content: "\e44c";}.fa-square::before {content: "\f0c8";}.fa-square-0::before {content: "\e255";}.fa-square-1::before {content: "\e256";}.fa-square-2::before {content: "\e257";}.fa-square-3::before {content: "\e258";}.fa-square-4::before {content: "\e259";}.fa-square-5::before {content: "\e25a";}.fa-square-6::before {content: "\e25b";}.fa-square-7::before {content: "\e25c";}.fa-square-8::before {content: "\e25d";}.fa-square-9::before {content: "\e25e";}.fa-square-a::before {content: "\e25f";}.fa-square-a-lock::before {content: "\e44d";}.fa-square-ampersand::before {content: "\e260";}.fa-square-arrow-down::before {content: "\f339";}.fa-arrow-square-down::before {content: "\f339";}.fa-square-arrow-down-left::before {content: "\e261";}.fa-square-arrow-down-right::before {content: "\e262";}.fa-square-arrow-left::before {content: "\f33a";}.fa-arrow-square-left::before {content: "\f33a";}.fa-square-arrow-right::before {content: "\f33b";}.fa-arrow-square-right::before {content: "\f33b";}.fa-square-arrow-up::before {content: "\f33c";}.fa-arrow-square-up::before {content: "\f33c";}.fa-square-arrow-up-left::before {content: "\e263";}.fa-square-arrow-up-right::before {content: "\f14c";}.fa-external-link-square::before {content: "\f14c";}.fa-square-b::before {content: "\e264";}.fa-square-bolt::before {content: "\e265";}.fa-square-c::before {content: "\e266";}.fa-square-caret-down::before {content: "\f150";}.fa-caret-square-down::before {content: "\f150";}.fa-square-caret-left::before {content: "\f191";}.fa-caret-square-left::before {content: "\f191";}.fa-square-caret-right::before {content: "\f152";}.fa-caret-square-right::before {content: "\f152";}.fa-square-caret-up::before {content: "\f151";}.fa-caret-square-up::before {content: "\f151";}.fa-square-check::before {content: "\f14a";}.fa-check-square::before {content: "\f14a";}.fa-square-chevron-down::before {content: "\f329";}.fa-chevron-square-down::before {content: "\f329";}.fa-square-chevron-left::before {content: "\f32a";}.fa-chevron-square-left::before {content: "\f32a";}.fa-square-chevron-right::before {content: "\f32b";}.fa-chevron-square-right::before {content: "\f32b";}.fa-square-chevron-up::before {content: "\f32c";}.fa-chevron-square-up::before {content: "\f32c";}.fa-square-code::before {content: "\e267";}.fa-square-d::before {content: "\e268";}.fa-square-dashed::before {content: "\e269";}.fa-square-divide::before {content: "\e26a";}.fa-square-dollar::before {content: "\f2e9";}.fa-dollar-square::before {content: "\f2e9";}.fa-usd-square::before {content: "\f2e9";}.fa-square-down::before {content: "\f350";}.fa-arrow-alt-square-down::before {content: "\f350";}.fa-square-down-left::before {content: "\e26b";}.fa-square-down-right::before {content: "\e26c";}.fa-square-e::before {content: "\e26d";}.fa-square-ellipsis::before {content: "\e26e";}.fa-square-ellipsis-vertical::before {content: "\e26f";}.fa-square-envelope::before {content: "\f199";}.fa-envelope-square::before {content: "\f199";}.fa-square-exclamation::before {content: "\f321";}.fa-exclamation-square::before {content: "\f321";}.fa-square-f::before {content: "\e270";}.fa-square-fragile::before {content: "\f49b";}.fa-box-fragile::before {content: "\f49b";}.fa-square-wine-glass-crack::before {content: "\f49b";}.fa-square-full::before {content: "\f45c";}.fa-square-g::before {content: "\e271";}.fa-square-h::before {content: "\f0fd";}.fa-h-square::before {content: "\f0fd";}.fa-square-heart::before {content: "\f4c8";}.fa-heart-square::before {content: "\f4c8";}.fa-square-i::before {content: "\e272";}.fa-square-info::before {content: "\f30f";}.fa-info-square::before {content: "\f30f";}.fa-square-j::before {content: "\e273";}.fa-square-k::before {content: "\e274";}.fa-square-kanban::before {content: "\e488";}.fa-square-l::before {content: "\e275";}.fa-square-left::before {content: "\f351";}.fa-arrow-alt-square-left::before {content: "\f351";}.fa-square-list::before {content: "\e489";}.fa-square-m::before {content: "\e276";}.fa-square-minus::before {content: "\f146";}.fa-minus-square::before {content: "\f146";}.fa-square-n::before {content: "\e277";}.fa-square-nfi::before {content: "\e576";}.fa-square-o::before {content: "\e278";}.fa-square-p::before {content: "\e279";}.fa-square-parking::before {content: "\f540";}.fa-parking::before {content: "\f540";}.fa-square-parking-slash::before {content: "\f617";}.fa-parking-slash::before {content: "\f617";}.fa-square-pen::before {content: "\f14b";}.fa-pen-square::before {content: "\f14b";}.fa-pencil-square::before {content: "\f14b";}.fa-square-person-confined::before {content: "\e577";}.fa-square-phone::before {content: "\f098";}.fa-phone-square::before {content: "\f098";}.fa-square-phone-flip::before {content: "\f87b";}.fa-phone-square-alt::before {content: "\f87b";}.fa-square-phone-hangup::before {content: "\e27a";}.fa-phone-square-down::before {content: "\e27a";}.fa-square-plus::before {content: "\f0fe";}.fa-plus-square::before {content: "\f0fe";}.fa-square-poll-horizontal::before {content: "\f682";}.fa-poll-h::before {content: "\f682";}.fa-square-poll-vertical::before {content: "\f681";}.fa-poll::before {content: "\f681";}.fa-square-q::before {content: "\e27b";}.fa-square-quarters::before {content: "\e44e";}.fa-square-question::before {content: "\f2fd";}.fa-question-square::before {content: "\f2fd";}.fa-square-quote::before {content: "\e329";}.fa-square-r::before {content: "\e27c";}.fa-square-right::before {content: "\f352";}.fa-arrow-alt-square-right::before {content: "\f352";}.fa-square-ring::before {content: "\e44f";}.fa-square-root::before {content: "\f697";}.fa-square-root-variable::before {content: "\f698";}.fa-square-root-alt::before {content: "\f698";}.fa-square-rss::before {content: "\f143";}.fa-rss-square::before {content: "\f143";}.fa-square-s::before {content: "\e27d";}.fa-square-share-nodes::before {content: "\f1e1";}.fa-share-alt-square::before {content: "\f1e1";}.fa-square-sliders::before {content: "\f3f0";}.fa-sliders-h-square::before {content: "\f3f0";}.fa-square-sliders-vertical::before {content: "\f3f2";}.fa-sliders-v-square::before {content: "\f3f2";}.fa-square-small::before {content: "\e27e";}.fa-square-star::before {content: "\e27f";}.fa-square-t::before {content: "\e280";}.fa-square-terminal::before {content: "\e32a";}.fa-square-this-way-up::before {content: "\f49f";}.fa-box-up::before {content: "\f49f";}.fa-square-u::before {content: "\e281";}.fa-square-up::before {content: "\f353";}.fa-arrow-alt-square-up::before {content: "\f353";}.fa-square-up-left::before {content: "\e282";}.fa-square-up-right::before {content: "\f360";}.fa-external-link-square-alt::before {content: "\f360";}.fa-square-user::before {content: "\e283";}.fa-square-v::before {content: "\e284";}.fa-square-virus::before {content: "\e578";}.fa-square-w::before {content: "\e285";}.fa-square-x::before {content: "\e286";}.fa-square-xmark::before {content: "\f2d3";}.fa-times-square::before {content: "\f2d3";}.fa-xmark-square::before {content: "\f2d3";}.fa-square-y::before {content: "\e287";}.fa-square-z::before {content: "\e288";}.fa-squid::before {content: "\e450";}.fa-squirrel::before {content: "\f71a";}.fa-staff::before {content: "\f71b";}.fa-staff-aesculapius::before {content: "\e579";}.fa-rod-asclepius::before {content: "\e579";}.fa-rod-snake::before {content: "\e579";}.fa-staff-snake::before {content: "\e579";}.fa-stairs::before {content: "\e289";}.fa-stamp::before {content: "\f5bf";}.fa-standard-definition::before {content: "\e28a";}.fa-rectangle-sd::before {content: "\e28a";}.fa-star::before {content: "\f005";}.fa-star-and-crescent::before {content: "\f699";}.fa-star-christmas::before {content: "\f7d4";}.fa-star-exclamation::before {content: "\f2f3";}.fa-star-half::before {content: "\f089";}.fa-star-half-stroke::before {content: "\f5c0";}.fa-star-half-alt::before {content: "\f5c0";}.fa-star-of-david::before {content: "\f69a";}.fa-star-of-life::before {content: "\f621";}.fa-star-sharp::before {content: "\e28b";}.fa-star-sharp-half::before {content: "\e28c";}.fa-star-sharp-half-stroke::before {content: "\e28d";}.fa-star-sharp-half-alt::before {content: "\e28d";}.fa-star-shooting::before {content: "\e036";}.fa-starfighter::before {content: "\e037";}.fa-starfighter-twin-ion-engine::before {content: "\e038";}.fa-starfighter-alt::before {content: "\e038";}.fa-starfighter-twin-ion-engine-advanced::before {content: "\e28e";}.fa-starfighter-alt-advanced::before {content: "\e28e";}.fa-stars::before {content: "\f762";}.fa-starship::before {content: "\e039";}.fa-starship-freighter::before {content: "\e03a";}.fa-steak::before {content: "\f824";}.fa-steering-wheel::before {content: "\f622";}.fa-sterling-sign::before {content: "\f154";}.fa-gbp::before {content: "\f154";}.fa-pound-sign::before {content: "\f154";}.fa-stethoscope::before {content: "\f0f1";}.fa-stocking::before {content: "\f7d5";}.fa-stomach::before {content: "\f623";}.fa-stop::before {content: "\f04d";}.fa-stopwatch::before {content: "\f2f2";}.fa-stopwatch-20::before {content: "\e06f";}.fa-store::before {content: "\f54e";}.fa-store-lock::before {content: "\e4a6";}.fa-store-slash::before {content: "\e071";}.fa-strawberry::before {content: "\e32b";}.fa-street-view::before {content: "\f21d";}.fa-stretcher::before {content: "\f825";}.fa-strikethrough::before {content: "\f0cc";}.fa-stroopwafel::before {content: "\f551";}.fa-subscript::before {content: "\f12c";}.fa-suitcase::before {content: "\f0f2";}.fa-suitcase-medical::before {content: "\f0fa";}.fa-medkit::before {content: "\f0fa";}.fa-suitcase-rolling::before {content: "\f5c1";}.fa-sun::before {content: "\f185";}.fa-sun-bright::before {content: "\e28f";}.fa-sun-alt::before {content: "\e28f";}.fa-sun-cloud::before {content: "\f763";}.fa-sun-dust::before {content: "\f764";}.fa-sun-haze::before {content: "\f765";}.fa-sun-plant-wilt::before {content: "\e57a";}.fa-sunglasses::before {content: "\f892";}.fa-sunrise::before {content: "\f766";}.fa-sunset::before {content: "\f767";}.fa-superscript::before {content: "\f12b";}.fa-sushi::before {content: "\e48a";}.fa-nigiri::before {content: "\e48a";}.fa-sushi-roll::before {content: "\e48b";}.fa-maki-roll::before {content: "\e48b";}.fa-makizushi::before {content: "\e48b";}.fa-swatchbook::before {content: "\f5c3";}.fa-sword::before {content: "\f71c";}.fa-sword-laser::before {content: "\e03b";}.fa-sword-laser-alt::before {content: "\e03c";}.fa-swords::before {content: "\f71d";}.fa-swords-laser::before {content: "\e03d";}.fa-symbols::before {content: "\f86e";}.fa-icons-alt::before {content: "\f86e";}.fa-synagogue::before {content: "\f69b";}.fa-syringe::before {content: "\f48e";}.fa-t::before {content: "\54";}.fa-table::before {content: "\f0ce";}.fa-table-cells::before {content: "\f00a";}.fa-th::before {content: "\f00a";}.fa-table-cells-large::before {content: "\f009";}.fa-th-large::before {content: "\f009";}.fa-table-columns::before {content: "\f0db";}.fa-columns::before {content: "\f0db";}.fa-table-layout::before {content: "\e290";}.fa-table-list::before {content: "\f00b";}.fa-th-list::before {content: "\f00b";}.fa-table-picnic::before {content: "\e32d";}.fa-table-pivot::before {content: "\e291";}.fa-table-rows::before {content: "\e292";}.fa-rows::before {content: "\e292";}.fa-table-tennis-paddle-ball::before {content: "\f45d";}.fa-ping-pong-paddle-ball::before {content: "\f45d";}.fa-table-tennis::before {content: "\f45d";}.fa-table-tree::before {content: "\e293";}.fa-tablet::before {content: "\f3fb";}.fa-tablet-android::before {content: "\f3fb";}.fa-tablet-button::before {content: "\f10a";}.fa-tablet-rugged::before {content: "\f48f";}.fa-tablet-screen::before {content: "\f3fc";}.fa-tablet-android-alt::before {content: "\f3fc";}.fa-tablet-screen-button::before {content: "\f3fa";}.fa-tablet-alt::before {content: "\f3fa";}.fa-tablets::before {content: "\f490";}.fa-tachograph-digital::before {content: "\f566";}.fa-digital-tachograph::before {content: "\f566";}.fa-taco::before {content: "\f826";}.fa-tag::before {content: "\f02b";}.fa-tags::before {content: "\f02c";}.fa-tally::before {content: "\f69c";}.fa-tally-5::before {content: "\f69c";}.fa-tally-1::before {content: "\e294";}.fa-tally-2::before {content: "\e295";}.fa-tally-3::before {content: "\e296";}.fa-tally-4::before {content: "\e297";}.fa-tamale::before {content: "\e451";}.fa-tank-water::before {content: "\e452";}.fa-tape::before {content: "\f4db";}.fa-tarp::before {content: "\e57b";}.fa-tarp-droplet::before {content: "\e57c";}.fa-taxi::before {content: "\f1ba";}.fa-cab::before {content: "\f1ba";}.fa-taxi-bus::before {content: "\e298";}.fa-teddy-bear::before {content: "\e3cf";}.fa-teeth::before {content: "\f62e";}.fa-teeth-open::before {content: "\f62f";}.fa-telescope::before {content: "\e03e";}.fa-temperature-arrow-down::before {content: "\e03f";}.fa-temperature-down::before {content: "\e03f";}.fa-temperature-arrow-up::before {content: "\e040";}.fa-temperature-up::before {content: "\e040";}.fa-temperature-empty::before {content: "\f2cb";}.fa-temperature-0::before {content: "\f2cb";}.fa-thermometer-0::before {content: "\f2cb";}.fa-thermometer-empty::before {content: "\f2cb";}.fa-temperature-full::before {content: "\f2c7";}.fa-temperature-4::before {content: "\f2c7";}.fa-thermometer-4::before {content: "\f2c7";}.fa-thermometer-full::before {content: "\f2c7";}.fa-temperature-half::before {content: "\f2c9";}.fa-temperature-2::before {content: "\f2c9";}.fa-thermometer-2::before {content: "\f2c9";}.fa-thermometer-half::before {content: "\f2c9";}.fa-temperature-high::before {content: "\f769";}.fa-temperature-list::before {content: "\e299";}.fa-temperature-low::before {content: "\f76b";}.fa-temperature-quarter::before {content: "\f2ca";}.fa-temperature-1::before {content: "\f2ca";}.fa-thermometer-1::before {content: "\f2ca";}.fa-thermometer-quarter::before {content: "\f2ca";}.fa-temperature-snow::before {content: "\f768";}.fa-temperature-frigid::before {content: "\f768";}.fa-temperature-sun::before {content: "\f76a";}.fa-temperature-hot::before {content: "\f76a";}.fa-temperature-three-quarters::before {content: "\f2c8";}.fa-temperature-3::before {content: "\f2c8";}.fa-thermometer-3::before {content: "\f2c8";}.fa-thermometer-three-quarters::before {content: "\f2c8";}.fa-tenge-sign::before {content: "\f7d7";}.fa-tenge::before {content: "\f7d7";}.fa-tennis-ball::before {content: "\f45e";}.fa-tent::before {content: "\e57d";}.fa-tent-arrow-down-to-line::before {content: "\e57e";}.fa-tent-arrow-left-right::before {content: "\e57f";}.fa-tent-arrow-turn-left::before {content: "\e580";}.fa-tent-arrows-down::before {content: "\e581";}.fa-tents::before {content: "\e582";}.fa-terminal::before {content: "\f120";}.fa-text::before {content: "\f893";}.fa-text-height::before {content: "\f034";}.fa-text-size::before {content: "\f894";}.fa-text-slash::before {content: "\f87d";}.fa-remove-format::before {content: "\f87d";}.fa-text-width::before {content: "\f035";}.fa-thermometer::before {content: "\f491";}.fa-theta::before {content: "\f69e";}.fa-thought-bubble::before {content: "\e32e";}.fa-thumbs-down::before {content: "\f165";}.fa-thumbs-up::before {content: "\f164";}.fa-thumbtack::before {content: "\f08d";}.fa-thumb-tack::before {content: "\f08d";}.fa-tick::before {content: "\e32f";}.fa-ticket::before {content: "\f145";}.fa-ticket-airline::before {content: "\e29a";}.fa-ticket-simple::before {content: "\f3ff";}.fa-ticket-alt::before {content: "\f3ff";}.fa-tickets-airline::before {content: "\e29b";}.fa-tilde::before {content: "\7e";}.fa-timeline::before {content: "\e29c";}.fa-timeline-arrow::before {content: "\e29d";}.fa-timer::before {content: "\e29e";}.fa-tire::before {content: "\f631";}.fa-tire-flat::before {content: "\f632";}.fa-tire-pressure-warning::before {content: "\f633";}.fa-tire-rugged::before {content: "\f634";}.fa-toggle-off::before {content: "\f204";}.fa-toggle-on::before {content: "\f205";}.fa-toilet::before {content: "\f7d8";}.fa-toilet-paper::before {content: "\f71e";}.fa-toilet-paper-blank::before {content: "\f71f";}.fa-toilet-paper-alt::before {content: "\f71f";}.fa-toilet-paper-blank-under::before {content: "\e29f";}.fa-toilet-paper-reverse-alt::before {content: "\e29f";}.fa-toilet-paper-slash::before {content: "\e072";}.fa-toilet-paper-under::before {content: "\e2a0";}.fa-toilet-paper-reverse::before {content: "\e2a0";}.fa-toilet-paper-under-slash::before {content: "\e2a1";}.fa-toilet-paper-reverse-slash::before {content: "\e2a1";}.fa-toilet-portable::before {content: "\e583";}.fa-toilets-portable::before {content: "\e584";}.fa-tomato::before {content: "\e330";}.fa-tombstone::before {content: "\f720";}.fa-tombstone-blank::before {content: "\f721";}.fa-tombstone-alt::before {content: "\f721";}.fa-toolbox::before {content: "\f552";}.fa-tooth::before {content: "\f5c9";}.fa-toothbrush::before {content: "\f635";}.fa-torii-gate::before {content: "\f6a1";}.fa-tornado::before {content: "\f76f";}.fa-tower-broadcast::before {content: "\f519";}.fa-broadcast-tower::before {content: "\f519";}.fa-tower-cell::before {content: "\e585";}.fa-tower-control::before {content: "\e2a2";}.fa-tower-observation::before {content: "\e586";}.fa-tractor::before {content: "\f722";}.fa-trademark::before {content: "\f25c";}.fa-traffic-cone::before {content: "\f636";}.fa-traffic-light::before {content: "\f637";}.fa-traffic-light-go::before {content: "\f638";}.fa-traffic-light-slow::before {content: "\f639";}.fa-traffic-light-stop::before {content: "\f63a";}.fa-trailer::before {content: "\e041";}.fa-train::before {content: "\f238";}.fa-train-subway::before {content: "\f239";}.fa-subway::before {content: "\f239";}.fa-train-subway-tunnel::before {content: "\e2a3";}.fa-subway-tunnel::before {content: "\e2a3";}.fa-train-track::before {content: "\e453";}.fa-train-tram::before {content: "\f7da";}.fa-tram::before {content: "\f7da";}.fa-train-tunnel::before {content: "\e454";}.fa-transformer-bolt::before {content: "\e2a4";}.fa-transgender::before {content: "\f225";}.fa-transgender-alt::before {content: "\f225";}.fa-transporter::before {content: "\e042";}.fa-transporter-1::before {content: "\e043";}.fa-transporter-2::before {content: "\e044";}.fa-transporter-3::before {content: "\e045";}.fa-transporter-4::before {content: "\e2a5";}.fa-transporter-5::before {content: "\e2a6";}.fa-transporter-6::before {content: "\e2a7";}.fa-transporter-7::before {content: "\e2a8";}.fa-transporter-empty::before {content: "\e046";}.fa-trash::before {content: "\f1f8";}.fa-trash-arrow-up::before {content: "\f829";}.fa-trash-restore::before {content: "\f829";}.fa-trash-can::before {content: "\f2ed";}.fa-trash-alt::before {content: "\f2ed";}.fa-trash-can-arrow-up::before {content: "\f82a";}.fa-trash-restore-alt::before {content: "\f82a";}.fa-trash-can-check::before {content: "\e2a9";}.fa-trash-can-clock::before {content: "\e2aa";}.fa-trash-can-list::before {content: "\e2ab";}.fa-trash-can-plus::before {content: "\e2ac";}.fa-trash-can-slash::before {content: "\e2ad";}.fa-trash-alt-slash::before {content: "\e2ad";}.fa-trash-can-undo::before {content: "\f896";}.fa-trash-can-arrow-turn-left::before {content: "\f896";}.fa-trash-undo-alt::before {content: "\f896";}.fa-trash-can-xmark::before {content: "\e2ae";}.fa-trash-check::before {content: "\e2af";}.fa-trash-clock::before {content: "\e2b0";}.fa-trash-list::before {content: "\e2b1";}.fa-trash-plus::before {content: "\e2b2";}.fa-trash-slash::before {content: "\e2b3";}.fa-trash-undo::before {content: "\f895";}.fa-trash-arrow-turn-left::before {content: "\f895";}.fa-trash-xmark::before {content: "\e2b4";}.fa-treasure-chest::before {content: "\f723";}.fa-tree::before {content: "\f1bb";}.fa-tree-christmas::before {content: "\f7db";}.fa-tree-city::before {content: "\e587";}.fa-tree-deciduous::before {content: "\f400";}.fa-tree-alt::before {content: "\f400";}.fa-tree-decorated::before {content: "\f7dc";}.fa-tree-large::before {content: "\f7dd";}.fa-tree-palm::before {content: "\f82b";}.fa-trees::before {content: "\f724";}.fa-triangle::before {content: "\f2ec";}.fa-triangle-exclamation::before {content: "\f071";}.fa-exclamation-triangle::before {content: "\f071";}.fa-warning::before {content: "\f071";}.fa-triangle-instrument::before {content: "\f8e2";}.fa-triangle-music::before {content: "\f8e2";}.fa-triangle-person-digging::before {content: "\f85d";}.fa-construction::before {content: "\f85d";}.fa-trillium::before {content: "\e588";}.fa-trophy::before {content: "\f091";}.fa-trophy-star::before {content: "\f2eb";}.fa-trophy-alt::before {content: "\f2eb";}.fa-trowel::before {content: "\e589";}.fa-trowel-bricks::before {content: "\e58a";}.fa-truck::before {content: "\f0d1";}.fa-truck-arrow-right::before {content: "\e58b";}.fa-truck-bolt::before {content: "\e3d0";}.fa-truck-clock::before {content: "\f48c";}.fa-shipping-timed::before {content: "\f48c";}.fa-truck-container::before {content: "\f4dc";}.fa-truck-container-empty::before {content: "\e2b5";}.fa-truck-droplet::before {content: "\e58c";}.fa-truck-fast::before {content: "\f48b";}.fa-shipping-fast::before {content: "\f48b";}.fa-truck-field::before {content: "\e58d";}.fa-truck-field-un::before {content: "\e58e";}.fa-truck-flatbed::before {content: "\e2b6";}.fa-truck-front::before {content: "\e2b7";}.fa-truck-medical::before {content: "\f0f9";}.fa-ambulance::before {content: "\f0f9";}.fa-truck-monster::before {content: "\f63b";}.fa-truck-moving::before {content: "\f4df";}.fa-truck-pickup::before {content: "\f63c";}.fa-truck-plane::before {content: "\e58f";}.fa-truck-plow::before {content: "\f7de";}.fa-truck-ramp::before {content: "\f4e0";}.fa-truck-ramp-box::before {content: "\f4de";}.fa-truck-loading::before {content: "\f4de";}.fa-truck-ramp-couch::before {content: "\f4dd";}.fa-truck-couch::before {content: "\f4dd";}.fa-truck-tow::before {content: "\e2b8";}.fa-trumpet::before {content: "\f8e3";}.fa-tty::before {content: "\f1e4";}.fa-teletype::before {content: "\f1e4";}.fa-tty-answer::before {content: "\e2b9";}.fa-teletype-answer::before {content: "\e2b9";}.fa-tugrik-sign::before {content: "\e2ba";}.fa-turkey::before {content: "\f725";}.fa-turkish-lira-sign::before {content: "\e2bb";}.fa-try::before {content: "\e2bb";}.fa-turkish-lira::before {content: "\e2bb";}.fa-turn-down::before {content: "\f3be";}.fa-level-down-alt::before {content: "\f3be";}.fa-turn-down-left::before {content: "\e331";}.fa-turn-down-right::before {content: "\e455";}.fa-turn-up::before {content: "\f3bf";}.fa-level-up-alt::before {content: "\f3bf";}.fa-turntable::before {content: "\f8e4";}.fa-turtle::before {content: "\f726";}.fa-tv::before {content: "\f26c";}.fa-television::before {content: "\f26c";}.fa-tv-alt::before {content: "\f26c";}.fa-tv-music::before {content: "\f8e6";}.fa-tv-retro::before {content: "\f401";}.fa-typewriter::before {content: "\f8e7";}.fa-u::before {content: "\55";}.fa-ufo::before {content: "\e047";}.fa-ufo-beam::before {content: "\e048";}.fa-umbrella::before {content: "\f0e9";}.fa-umbrella-beach::before {content: "\f5ca";}.fa-umbrella-simple::before {content: "\e2bc";}.fa-umbrella-alt::before {content: "\e2bc";}.fa-underline::before {content: "\f0cd";}.fa-unicorn::before {content: "\f727";}.fa-uniform-martial-arts::before {content: "\e3d1";}.fa-union::before {content: "\f6a2";}.fa-universal-access::before {content: "\f29a";}.fa-unlock::before {content: "\f09c";}.fa-unlock-keyhole::before {content: "\f13e";}.fa-unlock-alt::before {content: "\f13e";}.fa-up::before {content: "\f357";}.fa-arrow-alt-up::before {content: "\f357";}.fa-up-down::before {content: "\f338";}.fa-arrows-alt-v::before {content: "\f338";}.fa-up-down-left-right::before {content: "\f0b2";}.fa-arrows-alt::before {content: "\f0b2";}.fa-up-from-bracket::before {content: "\e590";}.fa-up-from-dotted-line::before {content: "\e456";}.fa-up-from-line::before {content: "\f346";}.fa-arrow-alt-from-bottom::before {content: "\f346";}.fa-up-left::before {content: "\e2bd";}.fa-up-long::before {content: "\f30c";}.fa-long-arrow-alt-up::before {content: "\f30c";}.fa-up-right::before {content: "\e2be";}.fa-up-right-and-down-left-from-center::before {content: "\f424";}.fa-expand-alt::before {content: "\f424";}.fa-up-right-from-square::before {content: "\f35d";}.fa-external-link-alt::before {content: "\f35d";}.fa-up-to-dotted-line::before {content: "\e457";}.fa-up-to-line::before {content: "\f34d";}.fa-arrow-alt-to-top::before {content: "\f34d";}.fa-upload::before {content: "\f093";}.fa-usb-drive::before {content: "\f8e9";}.fa-user::before {content: "\f007";}.fa-user-alien::before {content: "\e04a";}.fa-user-astronaut::before {content: "\f4fb";}.fa-user-bounty-hunter::before {content: "\e2bf";}.fa-user-check::before {content: "\f4fc";}.fa-user-chef::before {content: "\e3d2";}.fa-user-clock::before {content: "\f4fd";}.fa-user-cowboy::before {content: "\f8ea";}.fa-user-crown::before {content: "\f6a4";}.fa-user-doctor::before {content: "\f0f0";}.fa-user-md::before {content: "\f0f0";}.fa-user-doctor-hair::before {content: "\e458";}.fa-user-doctor-hair-long::before {content: "\e459";}.fa-user-doctor-message::before {content: "\f82e";}.fa-user-md-chat::before {content: "\f82e";}.fa-user-gear::before {content: "\f4fe";}.fa-user-cog::before {content: "\f4fe";}.fa-user-graduate::before {content: "\f501";}.fa-user-group::before {content: "\f500";}.fa-user-friends::before {content: "\f500";}.fa-user-group-crown::before {content: "\f6a5";}.fa-users-crown::before {content: "\f6a5";}.fa-user-hair::before {content: "\e45a";}.fa-user-hair-buns::before {content: "\e3d3";}.fa-user-hair-long::before {content: "\e45b";}.fa-user-hair-mullet::before {content: "\e45c";}.fa-business-front::before {content: "\e45c";}.fa-party-back::before {content: "\e45c";}.fa-trian-balbot::before {content: "\e45c";}.fa-user-headset::before {content: "\f82d";}.fa-user-helmet-safety::before {content: "\f82c";}.fa-user-construction::before {content: "\f82c";}.fa-user-hard-hat::before {content: "\f82c";}.fa-user-injured::before {content: "\f728";}.fa-user-large::before {content: "\f406";}.fa-user-alt::before {content: "\f406";}.fa-user-large-slash::before {content: "\f4fa";}.fa-user-alt-slash::before {content: "\f4fa";}.fa-user-lock::before {content: "\f502";}.fa-user-minus::before {content: "\f503";}.fa-user-music::before {content: "\f8eb";}.fa-user-ninja::before {content: "\f504";}.fa-user-nurse::before {content: "\f82f";}.fa-user-nurse-hair::before {content: "\e45d";}.fa-user-nurse-hair-long::before {content: "\e45e";}.fa-user-pen::before {content: "\f4ff";}.fa-user-edit::before {content: "\f4ff";}.fa-user-pilot::before {content: "\e2c0";}.fa-user-pilot-tie::before {content: "\e2c1";}.fa-user-plus::before {content: "\f234";}.fa-user-police::before {content: "\e333";}.fa-user-police-tie::before {content: "\e334";}.fa-user-robot::before {content: "\e04b";}.fa-user-robot-xmarks::before {content: "\e4a7";}.fa-user-secret::before {content: "\f21b";}.fa-user-shakespeare::before {content: "\e2c2";}.fa-user-shield::before {content: "\f505";}.fa-user-slash::before {content: "\f506";}.fa-user-tag::before {content: "\f507";}.fa-user-tie::before {content: "\f508";}.fa-user-tie-hair::before {content: "\e45f";}.fa-user-tie-hair-long::before {content: "\e460";}.fa-user-unlock::before {content: "\e058";}.fa-user-visor::before {content: "\e04c";}.fa-user-vneck::before {content: "\e461";}.fa-user-vneck-hair::before {content: "\e462";}.fa-user-vneck-hair-long::before {content: "\e463";}.fa-user-xmark::before {content: "\f235";}.fa-user-times::before {content: "\f235";}.fa-users::before {content: "\f0c0";}.fa-users-between-lines::before {content: "\e591";}.fa-users-gear::before {content: "\f509";}.fa-users-cog::before {content: "\f509";}.fa-users-line::before {content: "\e592";}.fa-users-medical::before {content: "\f830";}.fa-users-rays::before {content: "\e593";}.fa-users-rectangle::before {content: "\e594";}.fa-users-slash::before {content: "\e073";}.fa-users-viewfinder::before {content: "\e595";}.fa-utensils::before {content: "\f2e7";}.fa-cutlery::before {content: "\f2e7";}.fa-utensils-slash::before {content: "\e464";}.fa-utility-pole::before {content: "\e2c3";}.fa-utility-pole-double::before {content: "\e2c4";}.fa-v::before {content: "\56";}.fa-vacuum::before {content: "\e04d";}.fa-vacuum-robot::before {content: "\e04e";}.fa-value-absolute::before {content: "\f6a6";}.fa-van-shuttle::before {content: "\f5b6";}.fa-shuttle-van::before {content: "\f5b6";}.fa-vault::before {content: "\e2c5";}.fa-vector-circle::before {content: "\e2c6";}.fa-vector-polygon::before {content: "\e2c7";}.fa-vector-square::before {content: "\f5cb";}.fa-vent-damper::before {content: "\e465";}.fa-venus::before {content: "\f221";}.fa-venus-double::before {content: "\f226";}.fa-venus-mars::before {content: "\f228";}.fa-vest::before {content: "\e085";}.fa-vest-patches::before {content: "\e086";}.fa-vial::before {content: "\f492";}.fa-vial-circle-check::before {content: "\e596";}.fa-vial-virus::before {content: "\e597";}.fa-vials::before {content: "\f493";}.fa-video::before {content: "\f03d";}.fa-video-camera::before {content: "\f03d";}.fa-video-arrow-down-left::before {content: "\e2c8";}.fa-video-arrow-up-right::before {content: "\e2c9";}.fa-video-plus::before {content: "\f4e1";}.fa-video-slash::before {content: "\f4e2";}.fa-vihara::before {content: "\f6a7";}.fa-violin::before {content: "\f8ed";}.fa-virus::before {content: "\e074";}.fa-virus-covid::before {content: "\e4a8";}.fa-virus-covid-slash::before {content: "\e4a9";}.fa-virus-slash::before {content: "\e075";}.fa-viruses::before {content: "\e076";}.fa-voicemail::before {content: "\f897";}.fa-volcano::before {content: "\f770";}.fa-volleyball::before {content: "\f45f";}.fa-volleyball-ball::before {content: "\f45f";}.fa-volume::before {content: "\f6a8";}.fa-volume-medium::before {content: "\f6a8";}.fa-volume-high::before {content: "\f028";}.fa-volume-up::before {content: "\f028";}.fa-volume-low::before {content: "\f027";}.fa-volume-down::before {content: "\f027";}.fa-volume-off::before {content: "\f026";}.fa-volume-slash::before {content: "\f2e2";}.fa-volume-xmark::before {content: "\f6a9";}.fa-volume-mute::before {content: "\f6a9";}.fa-volume-times::before {content: "\f6a9";}.fa-vr-cardboard::before {content: "\f729";}.fa-w::before {content: "\57";}.fa-waffle::before {content: "\e466";}.fa-wagon-covered::before {content: "\f8ee";}.fa-walker::before {content: "\f831";}.fa-walkie-talkie::before {content: "\f8ef";}.fa-wallet::before {content: "\f555";}.fa-wand::before {content: "\f72a";}.fa-wand-magic::before {content: "\f0d0";}.fa-magic::before {content: "\f0d0";}.fa-wand-magic-sparkles::before {content: "\e2ca";}.fa-magic-wand-sparkles::before {content: "\e2ca";}.fa-wand-sparkles::before {content: "\f72b";}.fa-warehouse::before {content: "\f494";}.fa-warehouse-full::before {content: "\f495";}.fa-warehouse-alt::before {content: "\f495";}.fa-washing-machine::before {content: "\f898";}.fa-washer::before {content: "\f898";}.fa-watch::before {content: "\f2e1";}.fa-watch-apple::before {content: "\e2cb";}.fa-watch-calculator::before {content: "\f8f0";}.fa-watch-fitness::before {content: "\f63e";}.fa-watch-smart::before {content: "\e2cc";}.fa-water::before {content: "\f773";}.fa-water-arrow-down::before {content: "\f774";}.fa-water-lower::before {content: "\f774";}.fa-water-arrow-up::before {content: "\f775";}.fa-water-rise::before {content: "\f775";}.fa-water-ladder::before {content: "\f5c5";}.fa-ladder-water::before {content: "\f5c5";}.fa-swimming-pool::before {content: "\f5c5";}.fa-watermelon-slice::before {content: "\e337";}.fa-wave-pulse::before {content: "\f5f8";}.fa-heart-rate::before {content: "\f5f8";}.fa-wave-sine::before {content: "\f899";}.fa-wave-square::before {content: "\f83e";}.fa-wave-triangle::before {content: "\f89a";}.fa-waveform::before {content: "\f8f1";}.fa-waveform-lines::before {content: "\f8f2";}.fa-waveform-path::before {content: "\f8f2";}.fa-weight-hanging::before {content: "\f5cd";}.fa-weight-scale::before {content: "\f496";}.fa-weight::before {content: "\f496";}.fa-whale::before {content: "\f72c";}.fa-wheat::before {content: "\f72d";}.fa-wheat-awn::before {content: "\e2cd";}.fa-wheat-alt::before {content: "\e2cd";}.fa-wheat-awn-circle-exclamation::before {content: "\e598";}.fa-wheat-awn-slash::before {content: "\e338";}.fa-wheat-slash::before {content: "\e339";}.fa-wheelchair::before {content: "\f193";}.fa-wheelchair-move::before {content: "\e2ce";}.fa-wheelchair-alt::before {content: "\e2ce";}.fa-whiskey-glass::before {content: "\f7a0";}.fa-glass-whiskey::before {content: "\f7a0";}.fa-whiskey-glass-ice::before {content: "\f7a1";}.fa-glass-whiskey-rocks::before {content: "\f7a1";}.fa-whistle::before {content: "\f460";}.fa-wifi::before {content: "\f1eb";}.fa-wifi-3::before {content: "\f1eb";}.fa-wifi-strong::before {content: "\f1eb";}.fa-wifi-exclamation::before {content: "\e2cf";}.fa-wifi-fair::before {content: "\f6ab";}.fa-wifi-2::before {content: "\f6ab";}.fa-wifi-slash::before {content: "\f6ac";}.fa-wifi-weak::before {content: "\f6aa";}.fa-wifi-1::before {content: "\f6aa";}.fa-wind::before {content: "\f72e";}.fa-wind-turbine::before {content: "\f89b";}.fa-wind-warning::before {content: "\f776";}.fa-wind-circle-exclamation::before {content: "\f776";}.fa-window::before {content: "\f40e";}.fa-window-flip::before {content: "\f40f";}.fa-window-alt::before {content: "\f40f";}.fa-window-frame::before {content: "\e04f";}.fa-window-frame-open::before {content: "\e050";}.fa-window-maximize::before {content: "\f2d0";}.fa-window-minimize::before {content: "\f2d1";}.fa-window-restore::before {content: "\f2d2";}.fa-windsock::before {content: "\f777";}.fa-wine-bottle::before {content: "\f72f";}.fa-wine-glass::before {content: "\f4e3";}.fa-wine-glass-crack::before {content: "\f4bb";}.fa-fragile::before {content: "\f4bb";}.fa-wine-glass-empty::before {content: "\f5ce";}.fa-wine-glass-alt::before {content: "\f5ce";}.fa-won-sign::before {content: "\f159";}.fa-krw::before {content: "\f159";}.fa-won::before {content: "\f159";}.fa-worm::before {content: "\e599";}.fa-wreath::before {content: "\f7e2";}.fa-wrench::before {content: "\f0ad";}.fa-wrench-simple::before {content: "\e2d1";}.fa-x::before {content: "\58";}.fa-x-ray::before {content: "\f497";}.fa-xmark::before {content: "\f00d";}.fa-close::before {content: "\f00d";}.fa-multiply::before {content: "\f00d";}.fa-remove::before {content: "\f00d";}.fa-times::before {content: "\f00d";}.fa-xmark-large::before {content: "\e59b";}.fa-xmark-to-slot::before {content: "\f771";}.fa-times-to-slot::before {content: "\f771";}.fa-vote-nay::before {content: "\f771";}.fa-xmarks-lines::before {content: "\e59a";}.fa-y::before {content: "\59";}.fa-yen-sign::before {content: "\f157";}.fa-cny::before {content: "\f157";}.fa-jpy::before {content: "\f157";}.fa-rmb::before {content: "\f157";}.fa-yen::before {content: "\f157";}.fa-yin-yang::before {content: "\f6ad";}.fa-z::before {content: "\5a";}.sr-only, .fa-sr-only {position: absolute;width: 1px;height: 1px;padding: 0;margin: -1px;overflow: hidden;clip: rect(0, 0, 0, 0);white-space: nowrap;border-width: 0;}.sr-only-focusable:not(:focus), .fa-sr-only-focusable:not(:focus) {position: absolute;width: 1px;height: 1px;padding: 0;margin: -1px;overflow: hidden;clip: rect(0, 0, 0, 0);white-space: nowrap;border-width: 0;}:root, :host {--fa-font-brands: normal 400 1em/1 "Font Awesome 6 Brands";}@font-face {font-family: 'Font Awesome 6 Brands';font-style: normal;font-weight: 400;font-display: block;src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype");}.fab, .fa-brands {font-family: 'Font Awesome 6 Brands';font-weight: 400;}.fa-42-group:before {content: "\e080";}.fa-innosoft:before {content: "\e080";}.fa-500px:before {content: "\f26e";}.fa-accessible-icon:before {content: "\f368";}.fa-accusoft:before {content: "\f369";}.fa-adn:before {content: "\f170";}.fa-adversal:before {content: "\f36a";}.fa-affiliatetheme:before {content: "\f36b";}.fa-airbnb:before {content: "\f834";}.fa-algolia:before {content: "\f36c";}.fa-alipay:before {content: "\f642";}.fa-amazon:before {content: "\f270";}.fa-amazon-pay:before {content: "\f42c";}.fa-amilia:before {content: "\f36d";}.fa-android:before {content: "\f17b";}.fa-angellist:before {content: "\f209";}.fa-angrycreative:before {content: "\f36e";}.fa-angular:before {content: "\f420";}.fa-app-store:before {content: "\f36f";}.fa-app-store-ios:before {content: "\f370";}.fa-apper:before {content: "\f371";}.fa-apple:before {content: "\f179";}.fa-apple-pay:before {content: "\f415";}.fa-artstation:before {content: "\f77a";}.fa-asymmetrik:before {content: "\f372";}.fa-atlassian:before {content: "\f77b";}.fa-audible:before {content: "\f373";}.fa-autoprefixer:before {content: "\f41c";}.fa-avianex:before {content: "\f374";}.fa-aviato:before {content: "\f421";}.fa-aws:before {content: "\f375";}.fa-bandcamp:before {content: "\f2d5";}.fa-battle-net:before {content: "\f835";}.fa-behance:before {content: "\f1b4";}.fa-behance-square:before {content: "\f1b5";}.fa-bilibili:before {content: "\e3d9";}.fa-bimobject:before {content: "\f378";}.fa-bitbucket:before {content: "\f171";}.fa-bitcoin:before {content: "\f379";}.fa-bity:before {content: "\f37a";}.fa-black-tie:before {content: "\f27e";}.fa-blackberry:before {content: "\f37b";}.fa-blogger:before {content: "\f37c";}.fa-blogger-b:before {content: "\f37d";}.fa-bluetooth:before {content: "\f293";}.fa-bluetooth-b:before {content: "\f294";}.fa-bootstrap:before {content: "\f836";}.fa-bots:before {content: "\e340";}.fa-btc:before {content: "\f15a";}.fa-buffer:before {content: "\f837";}.fa-buromobelexperte:before {content: "\f37f";}.fa-buy-n-large:before {content: "\f8a6";}.fa-buysellads:before {content: "\f20d";}.fa-canadian-maple-leaf:before {content: "\f785";}.fa-cc-amazon-pay:before {content: "\f42d";}.fa-cc-amex:before {content: "\f1f3";}.fa-cc-apple-pay:before {content: "\f416";}.fa-cc-diners-club:before {content: "\f24c";}.fa-cc-discover:before {content: "\f1f2";}.fa-cc-jcb:before {content: "\f24b";}.fa-cc-mastercard:before {content: "\f1f1";}.fa-cc-paypal:before {content: "\f1f4";}.fa-cc-stripe:before {content: "\f1f5";}.fa-cc-visa:before {content: "\f1f0";}.fa-centercode:before {content: "\f380";}.fa-centos:before {content: "\f789";}.fa-chrome:before {content: "\f268";}.fa-chromecast:before {content: "\f838";}.fa-cloudflare:before {content: "\e07d";}.fa-cloudscale:before {content: "\f383";}.fa-cloudsmith:before {content: "\f384";}.fa-cloudversify:before {content: "\f385";}.fa-cmplid:before {content: "\e360";}.fa-codepen:before {content: "\f1cb";}.fa-codiepie:before {content: "\f284";}.fa-confluence:before {content: "\f78d";}.fa-connectdevelop:before {content: "\f20e";}.fa-contao:before {content: "\f26d";}.fa-cotton-bureau:before {content: "\f89e";}.fa-cpanel:before {content: "\f388";}.fa-creative-commons:before {content: "\f25e";}.fa-creative-commons-by:before {content: "\f4e7";}.fa-creative-commons-nc:before {content: "\f4e8";}.fa-creative-commons-nc-eu:before {content: "\f4e9";}.fa-creative-commons-nc-jp:before {content: "\f4ea";}.fa-creative-commons-nd:before {content: "\f4eb";}.fa-creative-commons-pd:before {content: "\f4ec";}.fa-creative-commons-pd-alt:before {content: "\f4ed";}.fa-creative-commons-remix:before {content: "\f4ee";}.fa-creative-commons-sa:before {content: "\f4ef";}.fa-creative-commons-sampling:before {content: "\f4f0";}.fa-creative-commons-sampling-plus:before {content: "\f4f1";}.fa-creative-commons-share:before {content: "\f4f2";}.fa-creative-commons-zero:before {content: "\f4f3";}.fa-critical-role:before {content: "\f6c9";}.fa-css3:before {content: "\f13c";}.fa-css3-alt:before {content: "\f38b";}.fa-cuttlefish:before {content: "\f38c";}.fa-d-and-d:before {content: "\f38d";}.fa-d-and-d-beyond:before {content: "\f6ca";}.fa-dailymotion:before {content: "\e052";}.fa-dashcube:before {content: "\f210";}.fa-deezer:before {content: "\e077";}.fa-delicious:before {content: "\f1a5";}.fa-deploydog:before {content: "\f38e";}.fa-deskpro:before {content: "\f38f";}.fa-dev:before {content: "\f6cc";}.fa-deviantart:before {content: "\f1bd";}.fa-dhl:before {content: "\f790";}.fa-diaspora:before {content: "\f791";}.fa-digg:before {content: "\f1a6";}.fa-digital-ocean:before {content: "\f391";}.fa-discord:before {content: "\f392";}.fa-discourse:before {content: "\f393";}.fa-dochub:before {content: "\f394";}.fa-docker:before {content: "\f395";}.fa-draft2digital:before {content: "\f396";}.fa-dribbble:before {content: "\f17d";}.fa-dribbble-square:before {content: "\f397";}.fa-dropbox:before {content: "\f16b";}.fa-drupal:before {content: "\f1a9";}.fa-dyalog:before {content: "\f399";}.fa-earlybirds:before {content: "\f39a";}.fa-ebay:before {content: "\f4f4";}.fa-edge:before {content: "\f282";}.fa-edge-legacy:before {content: "\e078";}.fa-elementor:before {content: "\f430";}.fa-ello:before {content: "\f5f1";}.fa-ember:before {content: "\f423";}.fa-empire:before {content: "\f1d1";}.fa-envira:before {content: "\f299";}.fa-erlang:before {content: "\f39d";}.fa-ethereum:before {content: "\f42e";}.fa-etsy:before {content: "\f2d7";}.fa-evernote:before {content: "\f839";}.fa-expeditedssl:before {content: "\f23e";}.fa-facebook:before {content: "\f09a";}.fa-facebook-f:before {content: "\f39e";}.fa-facebook-messenger:before {content: "\f39f";}.fa-facebook-square:before {content: "\f082";}.fa-fantasy-flight-games:before {content: "\f6dc";}.fa-fedex:before {content: "\f797";}.fa-fedora:before {content: "\f798";}.fa-figma:before {content: "\f799";}.fa-firefox:before {content: "\f269";}.fa-firefox-browser:before {content: "\e007";}.fa-first-order:before {content: "\f2b0";}.fa-first-order-alt:before {content: "\f50a";}.fa-firstdraft:before {content: "\f3a1";}.fa-flickr:before {content: "\f16e";}.fa-flipboard:before {content: "\f44d";}.fa-fly:before {content: "\f417";}.fa-font-awesome:before {content: "\f2b4";}.fa-font-awesome-flag:before {content: "\f2b4";}.fa-font-awesome-logo-full:before {content: "\f2b4";}.fa-fonticons:before {content: "\f280";}.fa-fonticons-fi:before {content: "\f3a2";}.fa-fort-awesome:before {content: "\f286";}.fa-fort-awesome-alt:before {content: "\f3a3";}.fa-forumbee:before {content: "\f211";}.fa-foursquare:before {content: "\f180";}.fa-free-code-camp:before {content: "\f2c5";}.fa-freebsd:before {content: "\f3a4";}.fa-fulcrum:before {content: "\f50b";}.fa-galactic-republic:before {content: "\f50c";}.fa-galactic-senate:before {content: "\f50d";}.fa-get-pocket:before {content: "\f265";}.fa-gg:before {content: "\f260";}.fa-gg-circle:before {content: "\f261";}.fa-git:before {content: "\f1d3";}.fa-git-alt:before {content: "\f841";}.fa-git-square:before {content: "\f1d2";}.fa-github:before {content: "\f09b";}.fa-github-alt:before {content: "\f113";}.fa-github-square:before {content: "\f092";}.fa-gitkraken:before {content: "\f3a6";}.fa-gitlab:before {content: "\f296";}.fa-gitter:before {content: "\f426";}.fa-glide:before {content: "\f2a5";}.fa-glide-g:before {content: "\f2a6";}.fa-gofore:before {content: "\f3a7";}.fa-golang:before {content: "\e40f";}.fa-goodreads:before {content: "\f3a8";}.fa-goodreads-g:before {content: "\f3a9";}.fa-google:before {content: "\f1a0";}.fa-google-drive:before {content: "\f3aa";}.fa-google-pay:before {content: "\e079";}.fa-google-play:before {content: "\f3ab";}.fa-google-plus:before {content: "\f2b3";}.fa-google-plus-g:before {content: "\f0d5";}.fa-google-plus-square:before {content: "\f0d4";}.fa-google-wallet:before {content: "\f1ee";}.fa-gratipay:before {content: "\f184";}.fa-grav:before {content: "\f2d6";}.fa-gripfire:before {content: "\f3ac";}.fa-grunt:before {content: "\f3ad";}.fa-guilded:before {content: "\e07e";}.fa-gulp:before {content: "\f3ae";}.fa-hacker-news:before {content: "\f1d4";}.fa-hacker-news-square:before {content: "\f3af";}.fa-hackerrank:before {content: "\f5f7";}.fa-hashnode:before {content: "\e499";}.fa-hips:before {content: "\f452";}.fa-hire-a-helper:before {content: "\f3b0";}.fa-hive:before {content: "\e07f";}.fa-hooli:before {content: "\f427";}.fa-hornbill:before {content: "\f592";}.fa-hotjar:before {content: "\f3b1";}.fa-houzz:before {content: "\f27c";}.fa-html5:before {content: "\f13b";}.fa-hubspot:before {content: "\f3b2";}.fa-ideal:before {content: "\e013";}.fa-imdb:before {content: "\f2d8";}.fa-instagram:before {content: "\f16d";}.fa-instagram-square:before {content: "\e055";}.fa-instalod:before {content: "\e081";}.fa-intercom:before {content: "\f7af";}.fa-internet-explorer:before {content: "\f26b";}.fa-invision:before {content: "\f7b0";}.fa-ioxhost:before {content: "\f208";}.fa-itch-io:before {content: "\f83a";}.fa-itunes:before {content: "\f3b4";}.fa-itunes-note:before {content: "\f3b5";}.fa-java:before {content: "\f4e4";}.fa-jedi-order:before {content: "\f50e";}.fa-jenkins:before {content: "\f3b6";}.fa-jira:before {content: "\f7b1";}.fa-joget:before {content: "\f3b7";}.fa-joomla:before {content: "\f1aa";}.fa-js:before {content: "\f3b8";}.fa-js-square:before {content: "\f3b9";}.fa-jsfiddle:before {content: "\f1cc";}.fa-kaggle:before {content: "\f5fa";}.fa-keybase:before {content: "\f4f5";}.fa-keycdn:before {content: "\f3ba";}.fa-kickstarter:before {content: "\f3bb";}.fa-kickstarter-k:before {content: "\f3bc";}.fa-korvue:before {content: "\f42f";}.fa-laravel:before {content: "\f3bd";}.fa-lastfm:before {content: "\f202";}.fa-lastfm-square:before {content: "\f203";}.fa-leanpub:before {content: "\f212";}.fa-less:before {content: "\f41d";}.fa-line:before {content: "\f3c0";}.fa-linkedin:before {content: "\f08c";}.fa-linkedin-in:before {content: "\f0e1";}.fa-linode:before {content: "\f2b8";}.fa-linux:before {content: "\f17c";}.fa-lyft:before {content: "\f3c3";}.fa-magento:before {content: "\f3c4";}.fa-mailchimp:before {content: "\f59e";}.fa-mandalorian:before {content: "\f50f";}.fa-markdown:before {content: "\f60f";}.fa-mastodon:before {content: "\f4f6";}.fa-maxcdn:before {content: "\f136";}.fa-mdb:before {content: "\f8ca";}.fa-medapps:before {content: "\f3c6";}.fa-medium:before {content: "\f23a";}.fa-medium-m:before {content: "\f23a";}.fa-medrt:before {content: "\f3c8";}.fa-meetup:before {content: "\f2e0";}.fa-megaport:before {content: "\f5a3";}.fa-mendeley:before {content: "\f7b3";}.fa-meta:before {content: "\e49b";}.fa-microblog:before {content: "\e01a";}.fa-microsoft:before {content: "\f3ca";}.fa-mix:before {content: "\f3cb";}.fa-mixcloud:before {content: "\f289";}.fa-mixer:before {content: "\e056";}.fa-mizuni:before {content: "\f3cc";}.fa-modx:before {content: "\f285";}.fa-monero:before {content: "\f3d0";}.fa-napster:before {content: "\f3d2";}.fa-neos:before {content: "\f612";}.fa-nfc-directional:before {content: "\e530";}.fa-nfc-symbol:before {content: "\e531";}.fa-nimblr:before {content: "\f5a8";}.fa-node:before {content: "\f419";}.fa-node-js:before {content: "\f3d3";}.fa-npm:before {content: "\f3d4";}.fa-ns8:before {content: "\f3d5";}.fa-nutritionix:before {content: "\f3d6";}.fa-octopus-deploy:before {content: "\e082";}.fa-odnoklassniki:before {content: "\f263";}.fa-odnoklassniki-square:before {content: "\f264";}.fa-old-republic:before {content: "\f510";}.fa-opencart:before {content: "\f23d";}.fa-openid:before {content: "\f19b";}.fa-opera:before {content: "\f26a";}.fa-optin-monster:before {content: "\f23c";}.fa-orcid:before {content: "\f8d2";}.fa-osi:before {content: "\f41a";}.fa-padlet:before {content: "\e4a0";}.fa-page4:before {content: "\f3d7";}.fa-pagelines:before {content: "\f18c";}.fa-palfed:before {content: "\f3d8";}.fa-patreon:before {content: "\f3d9";}.fa-paypal:before {content: "\f1ed";}.fa-perbyte:before {content: "\e083";}.fa-periscope:before {content: "\f3da";}.fa-phabricator:before {content: "\f3db";}.fa-phoenix-framework:before {content: "\f3dc";}.fa-phoenix-squadron:before {content: "\f511";}.fa-php:before {content: "\f457";}.fa-pied-piper:before {content: "\f2ae";}.fa-pied-piper-alt:before {content: "\f1a8";}.fa-pied-piper-hat:before {content: "\f4e5";}.fa-pied-piper-pp:before {content: "\f1a7";}.fa-pied-piper-square:before {content: "\e01e";}.fa-pinterest:before {content: "\f0d2";}.fa-pinterest-p:before {content: "\f231";}.fa-pinterest-square:before {content: "\f0d3";}.fa-pix:before {content: "\e43a";}.fa-playstation:before {content: "\f3df";}.fa-product-hunt:before {content: "\f288";}.fa-pushed:before {content: "\f3e1";}.fa-python:before {content: "\f3e2";}.fa-qq:before {content: "\f1d6";}.fa-quinscape:before {content: "\f459";}.fa-quora:before {content: "\f2c4";}.fa-r-project:before {content: "\f4f7";}.fa-raspberry-pi:before {content: "\f7bb";}.fa-ravelry:before {content: "\f2d9";}.fa-react:before {content: "\f41b";}.fa-reacteurope:before {content: "\f75d";}.fa-readme:before {content: "\f4d5";}.fa-rebel:before {content: "\f1d0";}.fa-red-river:before {content: "\f3e3";}.fa-reddit:before {content: "\f1a1";}.fa-reddit-alien:before {content: "\f281";}.fa-reddit-square:before {content: "\f1a2";}.fa-redhat:before {content: "\f7bc";}.fa-renren:before {content: "\f18b";}.fa-replyd:before {content: "\f3e6";}.fa-researchgate:before {content: "\f4f8";}.fa-resolving:before {content: "\f3e7";}.fa-rev:before {content: "\f5b2";}.fa-rocketchat:before {content: "\f3e8";}.fa-rockrms:before {content: "\f3e9";}.fa-rust:before {content: "\e07a";}.fa-safari:before {content: "\f267";}.fa-salesforce:before {content: "\f83b";}.fa-sass:before {content: "\f41e";}.fa-schlix:before {content: "\f3ea";}.fa-screenpal:before {content: "\e570";}.fa-scribd:before {content: "\f28a";}.fa-searchengin:before {content: "\f3eb";}.fa-sellcast:before {content: "\f2da";}.fa-sellsy:before {content: "\f213";}.fa-servicestack:before {content: "\f3ec";}.fa-shirtsinbulk:before {content: "\f214";}.fa-shopify:before {content: "\e057";}.fa-shopware:before {content: "\f5b5";}.fa-simplybuilt:before {content: "\f215";}.fa-sistrix:before {content: "\f3ee";}.fa-sith:before {content: "\f512";}.fa-sitrox:before {content: "\e44a";}.fa-sketch:before {content: "\f7c6";}.fa-skyatlas:before {content: "\f216";}.fa-skype:before {content: "\f17e";}.fa-slack:before {content: "\f198";}.fa-slack-hash:before {content: "\f198";}.fa-slideshare:before {content: "\f1e7";}.fa-snapchat:before {content: "\f2ab";}.fa-snapchat-ghost:before {content: "\f2ab";}.fa-snapchat-square:before {content: "\f2ad";}.fa-soundcloud:before {content: "\f1be";}.fa-sourcetree:before {content: "\f7d3";}.fa-speakap:before {content: "\f3f3";}.fa-speaker-deck:before {content: "\f83c";}.fa-spotify:before {content: "\f1bc";}.fa-square-font-awesome:before {content: "\f425";}.fa-square-font-awesome-stroke:before {content: "\f35c";}.fa-font-awesome-alt:before {content: "\f35c";}.fa-squarespace:before {content: "\f5be";}.fa-stack-exchange:before {content: "\f18d";}.fa-stack-overflow:before {content: "\f16c";}.fa-stackpath:before {content: "\f842";}.fa-staylinked:before {content: "\f3f5";}.fa-steam:before {content: "\f1b6";}.fa-steam-square:before {content: "\f1b7";}.fa-steam-symbol:before {content: "\f3f6";}.fa-sticker-mule:before {content: "\f3f7";}.fa-strava:before {content: "\f428";}.fa-stripe:before {content: "\f429";}.fa-stripe-s:before {content: "\f42a";}.fa-studiovinari:before {content: "\f3f8";}.fa-stumbleupon:before {content: "\f1a4";}.fa-stumbleupon-circle:before {content: "\f1a3";}.fa-superpowers:before {content: "\f2dd";}.fa-supple:before {content: "\f3f9";}.fa-suse:before {content: "\f7d6";}.fa-swift:before {content: "\f8e1";}.fa-symfony:before {content: "\f83d";}.fa-teamspeak:before {content: "\f4f9";}.fa-telegram:before {content: "\f2c6";}.fa-telegram-plane:before {content: "\f2c6";}.fa-tencent-weibo:before {content: "\f1d5";}.fa-the-red-yeti:before {content: "\f69d";}.fa-themeco:before {content: "\f5c6";}.fa-themeisle:before {content: "\f2b2";}.fa-think-peaks:before {content: "\f731";}.fa-tiktok:before {content: "\e07b";}.fa-trade-federation:before {content: "\f513";}.fa-trello:before {content: "\f181";}.fa-tumblr:before {content: "\f173";}.fa-tumblr-square:before {content: "\f174";}.fa-twitch:before {content: "\f1e8";}.fa-twitter:before {content: "\f099";}.fa-twitter-square:before {content: "\f081";}.fa-typo3:before {content: "\f42b";}.fa-uber:before {content: "\f402";}.fa-ubuntu:before {content: "\f7df";}.fa-uikit:before {content: "\f403";}.fa-umbraco:before {content: "\f8e8";}.fa-uncharted:before {content: "\e084";}.fa-uniregistry:before {content: "\f404";}.fa-unity:before {content: "\e049";}.fa-unsplash:before {content: "\e07c";}.fa-untappd:before {content: "\f405";}.fa-ups:before {content: "\f7e0";}.fa-usb:before {content: "\f287";}.fa-usps:before {content: "\f7e1";}.fa-ussunnah:before {content: "\f407";}.fa-vaadin:before {content: "\f408";}.fa-viacoin:before {content: "\f237";}.fa-viadeo:before {content: "\f2a9";}.fa-viadeo-square:before {content: "\f2aa";}.fa-viber:before {content: "\f409";}.fa-vimeo:before {content: "\f40a";}.fa-vimeo-square:before {content: "\f194";}.fa-vimeo-v:before {content: "\f27d";}.fa-vine:before {content: "\f1ca";}.fa-vk:before {content: "\f189";}.fa-vnv:before {content: "\f40b";}.fa-vuejs:before {content: "\f41f";}.fa-watchman-monitoring:before {content: "\e087";}.fa-waze:before {content: "\f83f";}.fa-weebly:before {content: "\f5cc";}.fa-weibo:before {content: "\f18a";}.fa-weixin:before {content: "\f1d7";}.fa-whatsapp:before {content: "\f232";}.fa-whatsapp-square:before {content: "\f40c";}.fa-whmcs:before {content: "\f40d";}.fa-wikipedia-w:before {content: "\f266";}.fa-windows:before {content: "\f17a";}.fa-wirsindhandwerk:before {content: "\e2d0";}.fa-wsh:before {content: "\e2d0";}.fa-wix:before {content: "\f5cf";}.fa-wizards-of-the-coast:before {content: "\f730";}.fa-wodu:before {content: "\e088";}.fa-wolf-pack-battalion:before {content: "\f514";}.fa-wordpress:before {content: "\f19a";}.fa-wordpress-simple:before {content: "\f411";}.fa-wpbeginner:before {content: "\f297";}.fa-wpexplorer:before {content: "\f2de";}.fa-wpforms:before {content: "\f298";}.fa-wpressr:before {content: "\f3e4";}.fa-xbox:before {content: "\f412";}.fa-xing:before {content: "\f168";}.fa-xing-square:before {content: "\f169";}.fa-y-combinator:before {content: "\f23b";}.fa-yahoo:before {content: "\f19e";}.fa-yammer:before {content: "\f840";}.fa-yandex:before {content: "\f413";}.fa-yandex-international:before {content: "\f414";}.fa-yarn:before {content: "\f7e3";}.fa-yelp:before {content: "\f1e9";}.fa-yoast:before {content: "\f2b1";}.fa-youtube:before {content: "\f167";}.fa-youtube-square:before {content: "\f431";}.fa-zhihu:before {content: "\f63f";}:root, :host {--fa-font-duotone: normal 900 1em/1 "Font Awesome 6 Duotone";}@font-face {font-family: 'Font Awesome 6 Duotone';font-style: normal;font-weight: 900;font-display: block;src: url("../webfonts/fa-duotone-900.woff2") format("woff2"), url("../webfonts/fa-duotone-900.ttf") format("truetype");}.fad, .fa-duotone {position: relative;font-family: 'Font Awesome 6 Duotone';font-weight: 900;letter-spacing: normal;}.fad::before, .fa-duotone::before {position: absolute;color: var(--fa-primary-color, inherit);opacity: var(--fa-primary-opacity, 1);}.fad::after, .fa-duotone::after {color: var(--fa-secondary-color, inherit);opacity: var(--fa-secondary-opacity, 0.4);}.fa-swap-opacity .fad::before, .fa-swap-opacity .fa-duotone::before, .fad.fa-swap-opacity::before, .fa-duotone.fa-swap-opacity::before {opacity: var(--fa-secondary-opacity, 0.4);}.fa-swap-opacity .fad::after, .fa-swap-opacity .fa-duotone::after, .fad.fa-swap-opacity::after, .fa-duotone.fa-swap-opacity::after {opacity: var(--fa-primary-opacity, 1);}.fad.fa-inverse, .fa-duotone.fa-inverse {color: var(--fa-inverse, #fff);}.fad.fa-stack-1x, .fad.fa-stack-2x, .fa-duotone.fa-stack-1x, .fa-duotone.fa-stack-2x {position: absolute;}.fad.fa-stack-1x::before, .fa-duotone.fa-stack-1x::before, .fad.fa-stack-2x::before, .fa-duotone.fa-stack-2x::before, .fad.fa-fw::before, .fa-duotone.fa-fw::before {left: 50%;-webkit-transform: translateX(-50%);transform: translateX(-50%);}.fad.fa-0::after, .fa-duotone.fa-0::after {content: "\30\30";}.fad.fa-1::after, .fa-duotone.fa-1::after {content: "\31\31";}.fad.fa-2::after, .fa-duotone.fa-2::after {content: "\32\32";}.fad.fa-3::after, .fa-duotone.fa-3::after {content: "\33\33";}.fad.fa-4::after, .fa-duotone.fa-4::after {content: "\34\34";}.fad.fa-5::after, .fa-duotone.fa-5::after {content: "\35\35";}.fad.fa-6::after, .fa-duotone.fa-6::after {content: "\36\36";}.fad.fa-7::after, .fa-duotone.fa-7::after {content: "\37\37";}.fad.fa-8::after, .fa-duotone.fa-8::after {content: "\38\38";}.fad.fa-9::after, .fa-duotone.fa-9::after {content: "\39\39";}.fad.fa-00::after, .fa-duotone.fa-00::after {content: "\e467\e467";}.fad.fa-360-degrees::after, .fa-duotone.fa-360-degrees::after {content: "\e2dc\e2dc";}.fad.fa-a::after, .fa-duotone.fa-a::after {content: "\41\41";}.fad.fa-abacus::after, .fa-duotone.fa-abacus::after {content: "\f640\f640";}.fad.fa-accent-grave::after, .fa-duotone.fa-accent-grave::after {content: "\60\60";}.fad.fa-acorn::after, .fa-duotone.fa-acorn::after {content: "\f6ae\f6ae";}.fad.fa-address-book::after, .fa-duotone.fa-address-book::after {content: "\f2b9\f2b9";}.fad.fa-contact-book::after, .fa-duotone.fa-contact-book::after {content: "\f2b9\f2b9";}.fad.fa-address-card::after, .fa-duotone.fa-address-card::after {content: "\f2bb\f2bb";}.fad.fa-contact-card::after, .fa-duotone.fa-contact-card::after {content: "\f2bb\f2bb";}.fad.fa-vcard::after, .fa-duotone.fa-vcard::after {content: "\f2bb\f2bb";}.fad.fa-air-conditioner::after, .fa-duotone.fa-air-conditioner::after {content: "\f8f4\f8f4";}.fad.fa-airplay::after, .fa-duotone.fa-airplay::after {content: "\e089\e089";}.fad.fa-alarm-clock::after, .fa-duotone.fa-alarm-clock::after {content: "\f34e\f34e";}.fad.fa-alarm-exclamation::after, .fa-duotone.fa-alarm-exclamation::after {content: "\f843\f843";}.fad.fa-alarm-plus::after, .fa-duotone.fa-alarm-plus::after {content: "\f844\f844";}.fad.fa-alarm-snooze::after, .fa-duotone.fa-alarm-snooze::after {content: "\f845\f845";}.fad.fa-album::after, .fa-duotone.fa-album::after {content: "\f89f\f89f";}.fad.fa-album-circle-plus::after, .fa-duotone.fa-album-circle-plus::after {content: "\e48c\e48c";}.fad.fa-album-circle-user::after, .fa-duotone.fa-album-circle-user::after {content: "\e48d\e48d";}.fad.fa-album-collection::after, .fa-duotone.fa-album-collection::after {content: "\f8a0\f8a0";}.fad.fa-album-collection-circle-plus::after, .fa-duotone.fa-album-collection-circle-plus::after {content: "\e48e\e48e";}.fad.fa-album-collection-circle-user::after, .fa-duotone.fa-album-collection-circle-user::after {content: "\e48f\e48f";}.fad.fa-alicorn::after, .fa-duotone.fa-alicorn::after {content: "\f6b0\f6b0";}.fad.fa-alien::after, .fa-duotone.fa-alien::after {content: "\f8f5\f8f5";}.fad.fa-alien-8bit::after, .fa-duotone.fa-alien-8bit::after {content: "\f8f6\f8f6";}.fad.fa-alien-monster::after, .fa-duotone.fa-alien-monster::after {content: "\f8f6\f8f6";}.fad.fa-align-center::after, .fa-duotone.fa-align-center::after {content: "\f037\f037";}.fad.fa-align-justify::after, .fa-duotone.fa-align-justify::after {content: "\f039\f039";}.fad.fa-align-left::after, .fa-duotone.fa-align-left::after {content: "\f036\f036";}.fad.fa-align-right::after, .fa-duotone.fa-align-right::after {content: "\f038\f038";}.fad.fa-align-slash::after, .fa-duotone.fa-align-slash::after {content: "\f846\f846";}.fad.fa-alt::after, .fa-duotone.fa-alt::after {content: "\e08a\e08a";}.fad.fa-amp-guitar::after, .fa-duotone.fa-amp-guitar::after {content: "\f8a1\f8a1";}.fad.fa-ampersand::after, .fa-duotone.fa-ampersand::after {content: "\26\26";}.fad.fa-anchor::after, .fa-duotone.fa-anchor::after {content: "\f13d\f13d";}.fad.fa-anchor-circle-check::after, .fa-duotone.fa-anchor-circle-check::after {content: "\e4aa\e4aa";}.fad.fa-anchor-circle-exclamation::after, .fa-duotone.fa-anchor-circle-exclamation::after {content: "\e4ab\e4ab";}.fad.fa-anchor-circle-xmark::after, .fa-duotone.fa-anchor-circle-xmark::after {content: "\e4ac\e4ac";}.fad.fa-anchor-lock::after, .fa-duotone.fa-anchor-lock::after {content: "\e4ad\e4ad";}.fad.fa-angel::after, .fa-duotone.fa-angel::after {content: "\f779\f779";}.fad.fa-angle::after, .fa-duotone.fa-angle::after {content: "\e08c\e08c";}.fad.fa-angle-90::after, .fa-duotone.fa-angle-90::after {content: "\e08d\e08d";}.fad.fa-angle-down::after, .fa-duotone.fa-angle-down::after {content: "\f107\f107";}.fad.fa-angle-left::after, .fa-duotone.fa-angle-left::after {content: "\f104\f104";}.fad.fa-angle-right::after, .fa-duotone.fa-angle-right::after {content: "\f105\f105";}.fad.fa-angle-up::after, .fa-duotone.fa-angle-up::after {content: "\f106\f106";}.fad.fa-angles-down::after, .fa-duotone.fa-angles-down::after {content: "\f103\f103";}.fad.fa-angle-double-down::after, .fa-duotone.fa-angle-double-down::after {content: "\f103\f103";}.fad.fa-angles-left::after, .fa-duotone.fa-angles-left::after {content: "\f100\f100";}.fad.fa-angle-double-left::after, .fa-duotone.fa-angle-double-left::after {content: "\f100\f100";}.fad.fa-angles-right::after, .fa-duotone.fa-angles-right::after {content: "\f101\f101";}.fad.fa-angle-double-right::after, .fa-duotone.fa-angle-double-right::after {content: "\f101\f101";}.fad.fa-angles-up::after, .fa-duotone.fa-angles-up::after {content: "\f102\f102";}.fad.fa-angle-double-up::after, .fa-duotone.fa-angle-double-up::after {content: "\f102\f102";}.fad.fa-ankh::after, .fa-duotone.fa-ankh::after {content: "\f644\f644";}.fad.fa-apartment::after, .fa-duotone.fa-apartment::after {content: "\e468\e468";}.fad.fa-aperture::after, .fa-duotone.fa-aperture::after {content: "\e2df\e2df";}.fad.fa-apostrophe::after, .fa-duotone.fa-apostrophe::after {content: "\27\27";}.fad.fa-apple-core::after, .fa-duotone.fa-apple-core::after {content: "\e08f\e08f";}.fad.fa-apple-whole::after, .fa-duotone.fa-apple-whole::after {content: "\f5d1\f5d1";}.fad.fa-apple-alt::after, .fa-duotone.fa-apple-alt::after {content: "\f5d1\f5d1";}.fad.fa-archway::after, .fa-duotone.fa-archway::after {content: "\f557\f557";}.fad.fa-arrow-down::after, .fa-duotone.fa-arrow-down::after {content: "\f063\f063";}.fad.fa-arrow-down-1-9::after, .fa-duotone.fa-arrow-down-1-9::after {content: "\f162\f162";}.fad.fa-sort-numeric-asc::after, .fa-duotone.fa-sort-numeric-asc::after {content: "\f162\f162";}.fad.fa-sort-numeric-down::after, .fa-duotone.fa-sort-numeric-down::after {content: "\f162\f162";}.fad.fa-arrow-down-9-1::after, .fa-duotone.fa-arrow-down-9-1::after {content: "\f886\f886";}.fad.fa-sort-numeric-desc::after, .fa-duotone.fa-sort-numeric-desc::after {content: "\f886\f886";}.fad.fa-sort-numeric-down-alt::after, .fa-duotone.fa-sort-numeric-down-alt::after {content: "\f886\f886";}.fad.fa-arrow-down-a-z::after, .fa-duotone.fa-arrow-down-a-z::after {content: "\f15d\f15d";}.fad.fa-sort-alpha-asc::after, .fa-duotone.fa-sort-alpha-asc::after {content: "\f15d\f15d";}.fad.fa-sort-alpha-down::after, .fa-duotone.fa-sort-alpha-down::after {content: "\f15d\f15d";}.fad.fa-arrow-down-arrow-up::after, .fa-duotone.fa-arrow-down-arrow-up::after {content: "\f883\f883";}.fad.fa-sort-alt::after, .fa-duotone.fa-sort-alt::after {content: "\f883\f883";}.fad.fa-arrow-down-big-small::after, .fa-duotone.fa-arrow-down-big-small::after {content: "\f88c\f88c";}.fad.fa-sort-size-down::after, .fa-duotone.fa-sort-size-down::after {content: "\f88c\f88c";}.fad.fa-arrow-down-from-dotted-line::after, .fa-duotone.fa-arrow-down-from-dotted-line::after {content: "\e090\e090";}.fad.fa-arrow-down-from-line::after, .fa-duotone.fa-arrow-down-from-line::after {content: "\f345\f345";}.fad.fa-arrow-from-top::after, .fa-duotone.fa-arrow-from-top::after {content: "\f345\f345";}.fad.fa-arrow-down-left::after, .fa-duotone.fa-arrow-down-left::after {content: "\e091\e091";}.fad.fa-arrow-down-left-and-arrow-up-right-to-center::after, .fa-duotone.fa-arrow-down-left-and-arrow-up-right-to-center::after {content: "\e092\e092";}.fad.fa-arrow-down-long::after, .fa-duotone.fa-arrow-down-long::after {content: "\f175\f175";}.fad.fa-long-arrow-down::after, .fa-duotone.fa-long-arrow-down::after {content: "\f175\f175";}.fad.fa-arrow-down-right::after, .fa-duotone.fa-arrow-down-right::after {content: "\e093\e093";}.fad.fa-arrow-down-short-wide::after, .fa-duotone.fa-arrow-down-short-wide::after {content: "\f884\f884";}.fad.fa-sort-amount-desc::after, .fa-duotone.fa-sort-amount-desc::after {content: "\f884\f884";}.fad.fa-sort-amount-down-alt::after, .fa-duotone.fa-sort-amount-down-alt::after {content: "\f884\f884";}.fad.fa-arrow-down-small-big::after, .fa-duotone.fa-arrow-down-small-big::after {content: "\f88d\f88d";}.fad.fa-sort-size-down-alt::after, .fa-duotone.fa-sort-size-down-alt::after {content: "\f88d\f88d";}.fad.fa-arrow-down-square-triangle::after, .fa-duotone.fa-arrow-down-square-triangle::after {content: "\f889\f889";}.fad.fa-sort-shapes-down-alt::after, .fa-duotone.fa-sort-shapes-down-alt::after {content: "\f889\f889";}.fad.fa-arrow-down-to-arc::after, .fa-duotone.fa-arrow-down-to-arc::after {content: "\e4ae\e4ae";}.fad.fa-arrow-down-to-bracket::after, .fa-duotone.fa-arrow-down-to-bracket::after {content: "\e094\e094";}.fad.fa-arrow-down-to-dotted-line::after, .fa-duotone.fa-arrow-down-to-dotted-line::after {content: "\e095\e095";}.fad.fa-arrow-down-to-line::after, .fa-duotone.fa-arrow-down-to-line::after {content: "\f33d\f33d";}.fad.fa-arrow-to-bottom::after, .fa-duotone.fa-arrow-to-bottom::after {content: "\f33d\f33d";}.fad.fa-arrow-down-to-square::after, .fa-duotone.fa-arrow-down-to-square::after {content: "\e096\e096";}.fad.fa-arrow-down-triangle-square::after, .fa-duotone.fa-arrow-down-triangle-square::after {content: "\f888\f888";}.fad.fa-sort-shapes-down::after, .fa-duotone.fa-sort-shapes-down::after {content: "\f888\f888";}.fad.fa-arrow-down-up-across-line::after, .fa-duotone.fa-arrow-down-up-across-line::after {content: "\e4af\e4af";}.fad.fa-arrow-down-up-lock::after, .fa-duotone.fa-arrow-down-up-lock::after {content: "\e4b0\e4b0";}.fad.fa-arrow-down-wide-short::after, .fa-duotone.fa-arrow-down-wide-short::after {content: "\f160\f160";}.fad.fa-sort-amount-asc::after, .fa-duotone.fa-sort-amount-asc::after {content: "\f160\f160";}.fad.fa-sort-amount-down::after, .fa-duotone.fa-sort-amount-down::after {content: "\f160\f160";}.fad.fa-arrow-down-z-a::after, .fa-duotone.fa-arrow-down-z-a::after {content: "\f881\f881";}.fad.fa-sort-alpha-desc::after, .fa-duotone.fa-sort-alpha-desc::after {content: "\f881\f881";}.fad.fa-sort-alpha-down-alt::after, .fa-duotone.fa-sort-alpha-down-alt::after {content: "\f881\f881";}.fad.fa-arrow-left::after, .fa-duotone.fa-arrow-left::after {content: "\f060\f060";}.fad.fa-arrow-left-from-line::after, .fa-duotone.fa-arrow-left-from-line::after {content: "\f344\f344";}.fad.fa-arrow-from-right::after, .fa-duotone.fa-arrow-from-right::after {content: "\f344\f344";}.fad.fa-arrow-left-long::after, .fa-duotone.fa-arrow-left-long::after {content: "\f177\f177";}.fad.fa-long-arrow-left::after, .fa-duotone.fa-long-arrow-left::after {content: "\f177\f177";}.fad.fa-arrow-left-long-to-line::after, .fa-duotone.fa-arrow-left-long-to-line::after {content: "\e3d4\e3d4";}.fad.fa-arrow-left-to-line::after, .fa-duotone.fa-arrow-left-to-line::after {content: "\f33e\f33e";}.fad.fa-arrow-to-left::after, .fa-duotone.fa-arrow-to-left::after {content: "\f33e\f33e";}.fad.fa-arrow-pointer::after, .fa-duotone.fa-arrow-pointer::after {content: "\f245\f245";}.fad.fa-mouse-pointer::after, .fa-duotone.fa-mouse-pointer::after {content: "\f245\f245";}.fad.fa-arrow-right::after, .fa-duotone.fa-arrow-right::after {content: "\f061\f061";}.fad.fa-arrow-right-arrow-left::after, .fa-duotone.fa-arrow-right-arrow-left::after {content: "\f0ec\f0ec";}.fad.fa-exchange::after, .fa-duotone.fa-exchange::after {content: "\f0ec\f0ec";}.fad.fa-arrow-right-from-arc::after, .fa-duotone.fa-arrow-right-from-arc::after {content: "\e4b1\e4b1";}.fad.fa-arrow-right-from-bracket::after, .fa-duotone.fa-arrow-right-from-bracket::after {content: "\f08b\f08b";}.fad.fa-sign-out::after, .fa-duotone.fa-sign-out::after {content: "\f08b\f08b";}.fad.fa-arrow-right-from-line::after, .fa-duotone.fa-arrow-right-from-line::after {content: "\f343\f343";}.fad.fa-arrow-from-left::after, .fa-duotone.fa-arrow-from-left::after {content: "\f343\f343";}.fad.fa-arrow-right-long::after, .fa-duotone.fa-arrow-right-long::after {content: "\f178\f178";}.fad.fa-long-arrow-right::after, .fa-duotone.fa-long-arrow-right::after {content: "\f178\f178";}.fad.fa-arrow-right-long-to-line::after, .fa-duotone.fa-arrow-right-long-to-line::after {content: "\e3d5\e3d5";}.fad.fa-arrow-right-to-arc::after, .fa-duotone.fa-arrow-right-to-arc::after {content: "\e4b2\e4b2";}.fad.fa-arrow-right-to-bracket::after, .fa-duotone.fa-arrow-right-to-bracket::after {content: "\f090\f090";}.fad.fa-sign-in::after, .fa-duotone.fa-sign-in::after {content: "\f090\f090";}.fad.fa-arrow-right-to-city::after, .fa-duotone.fa-arrow-right-to-city::after {content: "\e4b3\e4b3";}.fad.fa-arrow-right-to-line::after, .fa-duotone.fa-arrow-right-to-line::after {content: "\f340\f340";}.fad.fa-arrow-to-right::after, .fa-duotone.fa-arrow-to-right::after {content: "\f340\f340";}.fad.fa-arrow-rotate-left::after, .fa-duotone.fa-arrow-rotate-left::after {content: "\f0e2\f0e2";}.fad.fa-arrow-left-rotate::after, .fa-duotone.fa-arrow-left-rotate::after {content: "\f0e2\f0e2";}.fad.fa-arrow-rotate-back::after, .fa-duotone.fa-arrow-rotate-back::after {content: "\f0e2\f0e2";}.fad.fa-arrow-rotate-backward::after, .fa-duotone.fa-arrow-rotate-backward::after {content: "\f0e2\f0e2";}.fad.fa-undo::after, .fa-duotone.fa-undo::after {content: "\f0e2\f0e2";}.fad.fa-arrow-rotate-right::after, .fa-duotone.fa-arrow-rotate-right::after {content: "\f01e\f01e";}.fad.fa-arrow-right-rotate::after, .fa-duotone.fa-arrow-right-rotate::after {content: "\f01e\f01e";}.fad.fa-arrow-rotate-forward::after, .fa-duotone.fa-arrow-rotate-forward::after {content: "\f01e\f01e";}.fad.fa-redo::after, .fa-duotone.fa-redo::after {content: "\f01e\f01e";}.fad.fa-arrow-trend-down::after, .fa-duotone.fa-arrow-trend-down::after {content: "\e097\e097";}.fad.fa-arrow-trend-up::after, .fa-duotone.fa-arrow-trend-up::after {content: "\e098\e098";}.fad.fa-arrow-turn-down::after, .fa-duotone.fa-arrow-turn-down::after {content: "\f149\f149";}.fad.fa-level-down::after, .fa-duotone.fa-level-down::after {content: "\f149\f149";}.fad.fa-arrow-turn-down-left::after, .fa-duotone.fa-arrow-turn-down-left::after {content: "\e2e1\e2e1";}.fad.fa-arrow-turn-down-right::after, .fa-duotone.fa-arrow-turn-down-right::after {content: "\e3d6\e3d6";}.fad.fa-arrow-turn-up::after, .fa-duotone.fa-arrow-turn-up::after {content: "\f148\f148";}.fad.fa-level-up::after, .fa-duotone.fa-level-up::after {content: "\f148\f148";}.fad.fa-arrow-up::after, .fa-duotone.fa-arrow-up::after {content: "\f062\f062";}.fad.fa-arrow-up-1-9::after, .fa-duotone.fa-arrow-up-1-9::after {content: "\f163\f163";}.fad.fa-sort-numeric-up::after, .fa-duotone.fa-sort-numeric-up::after {content: "\f163\f163";}.fad.fa-arrow-up-9-1::after, .fa-duotone.fa-arrow-up-9-1::after {content: "\f887\f887";}.fad.fa-sort-numeric-up-alt::after, .fa-duotone.fa-sort-numeric-up-alt::after {content: "\f887\f887";}.fad.fa-arrow-up-a-z::after, .fa-duotone.fa-arrow-up-a-z::after {content: "\f15e\f15e";}.fad.fa-sort-alpha-up::after, .fa-duotone.fa-sort-alpha-up::after {content: "\f15e\f15e";}.fad.fa-arrow-up-arrow-down::after, .fa-duotone.fa-arrow-up-arrow-down::after {content: "\e099\e099";}.fad.fa-sort-up-down::after, .fa-duotone.fa-sort-up-down::after {content: "\e099\e099";}.fad.fa-arrow-up-big-small::after, .fa-duotone.fa-arrow-up-big-small::after {content: "\f88e\f88e";}.fad.fa-sort-size-up::after, .fa-duotone.fa-sort-size-up::after {content: "\f88e\f88e";}.fad.fa-arrow-up-from-arc::after, .fa-duotone.fa-arrow-up-from-arc::after {content: "\e4b4\e4b4";}.fad.fa-arrow-up-from-bracket::after, .fa-duotone.fa-arrow-up-from-bracket::after {content: "\e09a\e09a";}.fad.fa-arrow-up-from-dotted-line::after, .fa-duotone.fa-arrow-up-from-dotted-line::after {content: "\e09b\e09b";}.fad.fa-arrow-up-from-ground-water::after, .fa-duotone.fa-arrow-up-from-ground-water::after {content: "\e4b5\e4b5";}.fad.fa-arrow-up-from-line::after, .fa-duotone.fa-arrow-up-from-line::after {content: "\f342\f342";}.fad.fa-arrow-from-bottom::after, .fa-duotone.fa-arrow-from-bottom::after {content: "\f342\f342";}.fad.fa-arrow-up-from-square::after, .fa-duotone.fa-arrow-up-from-square::after {content: "\e09c\e09c";}.fad.fa-arrow-up-from-water-pump::after, .fa-duotone.fa-arrow-up-from-water-pump::after {content: "\e4b6\e4b6";}.fad.fa-arrow-up-left::after, .fa-duotone.fa-arrow-up-left::after {content: "\e09d\e09d";}.fad.fa-arrow-up-left-from-circle::after, .fa-duotone.fa-arrow-up-left-from-circle::after {content: "\e09e\e09e";}.fad.fa-arrow-up-long::after, .fa-duotone.fa-arrow-up-long::after {content: "\f176\f176";}.fad.fa-long-arrow-up::after, .fa-duotone.fa-long-arrow-up::after {content: "\f176\f176";}.fad.fa-arrow-up-right::after, .fa-duotone.fa-arrow-up-right::after {content: "\e09f\e09f";}.fad.fa-arrow-up-right-and-arrow-down-left-from-center::after, .fa-duotone.fa-arrow-up-right-and-arrow-down-left-from-center::after {content: "\e0a0\e0a0";}.fad.fa-arrow-up-right-dots::after, .fa-duotone.fa-arrow-up-right-dots::after {content: "\e4b7\e4b7";}.fad.fa-arrow-up-right-from-square::after, .fa-duotone.fa-arrow-up-right-from-square::after {content: "\f08e\f08e";}.fad.fa-external-link::after, .fa-duotone.fa-external-link::after {content: "\f08e\f08e";}.fad.fa-arrow-up-short-wide::after, .fa-duotone.fa-arrow-up-short-wide::after {content: "\f885\f885";}.fad.fa-sort-amount-up-alt::after, .fa-duotone.fa-sort-amount-up-alt::after {content: "\f885\f885";}.fad.fa-arrow-up-small-big::after, .fa-duotone.fa-arrow-up-small-big::after {content: "\f88f\f88f";}.fad.fa-sort-size-up-alt::after, .fa-duotone.fa-sort-size-up-alt::after {content: "\f88f\f88f";}.fad.fa-arrow-up-square-triangle::after, .fa-duotone.fa-arrow-up-square-triangle::after {content: "\f88b\f88b";}.fad.fa-sort-shapes-up-alt::after, .fa-duotone.fa-sort-shapes-up-alt::after {content: "\f88b\f88b";}.fad.fa-arrow-up-to-dotted-line::after, .fa-duotone.fa-arrow-up-to-dotted-line::after {content: "\e0a1\e0a1";}.fad.fa-arrow-up-to-line::after, .fa-duotone.fa-arrow-up-to-line::after {content: "\f341\f341";}.fad.fa-arrow-to-top::after, .fa-duotone.fa-arrow-to-top::after {content: "\f341\f341";}.fad.fa-arrow-up-triangle-square::after, .fa-duotone.fa-arrow-up-triangle-square::after {content: "\f88a\f88a";}.fad.fa-sort-shapes-up::after, .fa-duotone.fa-sort-shapes-up::after {content: "\f88a\f88a";}.fad.fa-arrow-up-wide-short::after, .fa-duotone.fa-arrow-up-wide-short::after {content: "\f161\f161";}.fad.fa-sort-amount-up::after, .fa-duotone.fa-sort-amount-up::after {content: "\f161\f161";}.fad.fa-arrow-up-z-a::after, .fa-duotone.fa-arrow-up-z-a::after {content: "\f882\f882";}.fad.fa-sort-alpha-up-alt::after, .fa-duotone.fa-sort-alpha-up-alt::after {content: "\f882\f882";}.fad.fa-arrows-cross::after, .fa-duotone.fa-arrows-cross::after {content: "\e0a2\e0a2";}.fad.fa-arrows-down-to-line::after, .fa-duotone.fa-arrows-down-to-line::after {content: "\e4b8\e4b8";}.fad.fa-arrows-down-to-people::after, .fa-duotone.fa-arrows-down-to-people::after {content: "\e4b9\e4b9";}.fad.fa-arrows-from-dotted-line::after, .fa-duotone.fa-arrows-from-dotted-line::after {content: "\e0a3\e0a3";}.fad.fa-arrows-from-line::after, .fa-duotone.fa-arrows-from-line::after {content: "\e0a4\e0a4";}.fad.fa-arrows-left-right::after, .fa-duotone.fa-arrows-left-right::after {content: "\f07e\f07e";}.fad.fa-arrows-h::after, .fa-duotone.fa-arrows-h::after {content: "\f07e\f07e";}.fad.fa-arrows-left-right-to-line::after, .fa-duotone.fa-arrows-left-right-to-line::after {content: "\e4ba\e4ba";}.fad.fa-arrows-maximize::after, .fa-duotone.fa-arrows-maximize::after {content: "\f31d\f31d";}.fad.fa-expand-arrows::after, .fa-duotone.fa-expand-arrows::after {content: "\f31d\f31d";}.fad.fa-arrows-minimize::after, .fa-duotone.fa-arrows-minimize::after {content: "\e0a5\e0a5";}.fad.fa-compress-arrows::after, .fa-duotone.fa-compress-arrows::after {content: "\e0a5\e0a5";}.fad.fa-arrows-repeat::after, .fa-duotone.fa-arrows-repeat::after {content: "\f364\f364";}.fad.fa-repeat-alt::after, .fa-duotone.fa-repeat-alt::after {content: "\f364\f364";}.fad.fa-arrows-repeat-1::after, .fa-duotone.fa-arrows-repeat-1::after {content: "\f366\f366";}.fad.fa-repeat-1-alt::after, .fa-duotone.fa-repeat-1-alt::after {content: "\f366\f366";}.fad.fa-arrows-retweet::after, .fa-duotone.fa-arrows-retweet::after {content: "\f361\f361";}.fad.fa-retweet-alt::after, .fa-duotone.fa-retweet-alt::after {content: "\f361\f361";}.fad.fa-arrows-rotate::after, .fa-duotone.fa-arrows-rotate::after {content: "\f021\f021";}.fad.fa-refresh::after, .fa-duotone.fa-refresh::after {content: "\f021\f021";}.fad.fa-sync::after, .fa-duotone.fa-sync::after {content: "\f021\f021";}.fad.fa-arrows-spin::after, .fa-duotone.fa-arrows-spin::after {content: "\e4bb\e4bb";}.fad.fa-arrows-split-up-and-left::after, .fa-duotone.fa-arrows-split-up-and-left::after {content: "\e4bc\e4bc";}.fad.fa-arrows-to-circle::after, .fa-duotone.fa-arrows-to-circle::after {content: "\e4bd\e4bd";}.fad.fa-arrows-to-dot::after, .fa-duotone.fa-arrows-to-dot::after {content: "\e4be\e4be";}.fad.fa-arrows-to-dotted-line::after, .fa-duotone.fa-arrows-to-dotted-line::after {content: "\e0a6\e0a6";}.fad.fa-arrows-to-eye::after, .fa-duotone.fa-arrows-to-eye::after {content: "\e4bf\e4bf";}.fad.fa-arrows-to-line::after, .fa-duotone.fa-arrows-to-line::after {content: "\e0a7\e0a7";}.fad.fa-arrows-turn-right::after, .fa-duotone.fa-arrows-turn-right::after {content: "\e4c0\e4c0";}.fad.fa-arrows-turn-to-dots::after, .fa-duotone.fa-arrows-turn-to-dots::after {content: "\e4c1\e4c1";}.fad.fa-arrows-up-down::after, .fa-duotone.fa-arrows-up-down::after {content: "\f07d\f07d";}.fad.fa-arrows-v::after, .fa-duotone.fa-arrows-v::after {content: "\f07d\f07d";}.fad.fa-arrows-up-down-left-right::after, .fa-duotone.fa-arrows-up-down-left-right::after {content: "\f047\f047";}.fad.fa-arrows::after, .fa-duotone.fa-arrows::after {content: "\f047\f047";}.fad.fa-arrows-up-to-line::after, .fa-duotone.fa-arrows-up-to-line::after {content: "\e4c2\e4c2";}.fad.fa-asterisk::after, .fa-duotone.fa-asterisk::after {content: "\2a\2a";}.fad.fa-at::after, .fa-duotone.fa-at::after {content: "\40\40";}.fad.fa-atom::after, .fa-duotone.fa-atom::after {content: "\f5d2\f5d2";}.fad.fa-atom-simple::after, .fa-duotone.fa-atom-simple::after {content: "\f5d3\f5d3";}.fad.fa-atom-alt::after, .fa-duotone.fa-atom-alt::after {content: "\f5d3\f5d3";}.fad.fa-audio-description::after, .fa-duotone.fa-audio-description::after {content: "\f29e\f29e";}.fad.fa-audio-description-slash::after, .fa-duotone.fa-audio-description-slash::after {content: "\e0a8\e0a8";}.fad.fa-austral-sign::after, .fa-duotone.fa-austral-sign::after {content: "\e0a9\e0a9";}.fad.fa-avocado::after, .fa-duotone.fa-avocado::after {content: "\e0aa\e0aa";}.fad.fa-award::after, .fa-duotone.fa-award::after {content: "\f559\f559";}.fad.fa-award-simple::after, .fa-duotone.fa-award-simple::after {content: "\e0ab\e0ab";}.fad.fa-axe::after, .fa-duotone.fa-axe::after {content: "\f6b2\f6b2";}.fad.fa-axe-battle::after, .fa-duotone.fa-axe-battle::after {content: "\f6b3\f6b3";}.fad.fa-b::after, .fa-duotone.fa-b::after {content: "\42\42";}.fad.fa-baby::after, .fa-duotone.fa-baby::after {content: "\f77c\f77c";}.fad.fa-baby-carriage::after, .fa-duotone.fa-baby-carriage::after {content: "\f77d\f77d";}.fad.fa-carriage-baby::after, .fa-duotone.fa-carriage-baby::after {content: "\f77d\f77d";}.fad.fa-backpack::after, .fa-duotone.fa-backpack::after {content: "\f5d4\f5d4";}.fad.fa-backward::after, .fa-duotone.fa-backward::after {content: "\f04a\f04a";}.fad.fa-backward-fast::after, .fa-duotone.fa-backward-fast::after {content: "\f049\f049";}.fad.fa-fast-backward::after, .fa-duotone.fa-fast-backward::after {content: "\f049\f049";}.fad.fa-backward-step::after, .fa-duotone.fa-backward-step::after {content: "\f048\f048";}.fad.fa-step-backward::after, .fa-duotone.fa-step-backward::after {content: "\f048\f048";}.fad.fa-bacon::after, .fa-duotone.fa-bacon::after {content: "\f7e5\f7e5";}.fad.fa-bacteria::after, .fa-duotone.fa-bacteria::after {content: "\e059\e059";}.fad.fa-bacterium::after, .fa-duotone.fa-bacterium::after {content: "\e05a\e05a";}.fad.fa-badge::after, .fa-duotone.fa-badge::after {content: "\f335\f335";}.fad.fa-badge-check::after, .fa-duotone.fa-badge-check::after {content: "\f336\f336";}.fad.fa-badge-dollar::after, .fa-duotone.fa-badge-dollar::after {content: "\f645\f645";}.fad.fa-badge-percent::after, .fa-duotone.fa-badge-percent::after {content: "\f646\f646";}.fad.fa-badge-sheriff::after, .fa-duotone.fa-badge-sheriff::after {content: "\f8a2\f8a2";}.fad.fa-badger-honey::after, .fa-duotone.fa-badger-honey::after {content: "\f6b4\f6b4";}.fad.fa-badminton::after, .fa-duotone.fa-badminton::after {content: "\e33a\e33a";}.fad.fa-bag-shopping::after, .fa-duotone.fa-bag-shopping::after {content: "\f290\f290";}.fad.fa-shopping-bag::after, .fa-duotone.fa-shopping-bag::after {content: "\f290\f290";}.fad.fa-bagel::after, .fa-duotone.fa-bagel::after {content: "\e3d7\e3d7";}.fad.fa-bags-shopping::after, .fa-duotone.fa-bags-shopping::after {content: "\f847\f847";}.fad.fa-baguette::after, .fa-duotone.fa-baguette::after {content: "\e3d8\e3d8";}.fad.fa-bahai::after, .fa-duotone.fa-bahai::after {content: "\f666\f666";}.fad.fa-baht-sign::after, .fa-duotone.fa-baht-sign::after {content: "\e0ac\e0ac";}.fad.fa-ball-pile::after, .fa-duotone.fa-ball-pile::after {content: "\f77e\f77e";}.fad.fa-balloon::after, .fa-duotone.fa-balloon::after {content: "\e2e3\e2e3";}.fad.fa-balloons::after, .fa-duotone.fa-balloons::after {content: "\e2e4\e2e4";}.fad.fa-ballot::after, .fa-duotone.fa-ballot::after {content: "\f732\f732";}.fad.fa-ballot-check::after, .fa-duotone.fa-ballot-check::after {content: "\f733\f733";}.fad.fa-ban::after, .fa-duotone.fa-ban::after {content: "\f05e\f05e";}.fad.fa-cancel::after, .fa-duotone.fa-cancel::after {content: "\f05e\f05e";}.fad.fa-ban-bug::after, .fa-duotone.fa-ban-bug::after {content: "\f7f9\f7f9";}.fad.fa-debug::after, .fa-duotone.fa-debug::after {content: "\f7f9\f7f9";}.fad.fa-ban-parking::after, .fa-duotone.fa-ban-parking::after {content: "\f616\f616";}.fad.fa-parking-circle-slash::after, .fa-duotone.fa-parking-circle-slash::after {content: "\f616\f616";}.fad.fa-ban-smoking::after, .fa-duotone.fa-ban-smoking::after {content: "\f54d\f54d";}.fad.fa-smoking-ban::after, .fa-duotone.fa-smoking-ban::after {content: "\f54d\f54d";}.fad.fa-banana::after, .fa-duotone.fa-banana::after {content: "\e2e5\e2e5";}.fad.fa-bandage::after, .fa-duotone.fa-bandage::after {content: "\f462\f462";}.fad.fa-band-aid::after, .fa-duotone.fa-band-aid::after {content: "\f462\f462";}.fad.fa-bangladeshi-taka-sign::after, .fa-duotone.fa-bangladeshi-taka-sign::after {content: "\e2e6\e2e6";}.fad.fa-banjo::after, .fa-duotone.fa-banjo::after {content: "\f8a3\f8a3";}.fad.fa-barcode::after, .fa-duotone.fa-barcode::after {content: "\f02a\f02a";}.fad.fa-barcode-read::after, .fa-duotone.fa-barcode-read::after {content: "\f464\f464";}.fad.fa-barcode-scan::after, .fa-duotone.fa-barcode-scan::after {content: "\f465\f465";}.fad.fa-bars::after, .fa-duotone.fa-bars::after {content: "\f0c9\f0c9";}.fad.fa-navicon::after, .fa-duotone.fa-navicon::after {content: "\f0c9\f0c9";}.fad.fa-bars-filter::after, .fa-duotone.fa-bars-filter::after {content: "\e0ad\e0ad";}.fad.fa-bars-progress::after, .fa-duotone.fa-bars-progress::after {content: "\f828\f828";}.fad.fa-tasks-alt::after, .fa-duotone.fa-tasks-alt::after {content: "\f828\f828";}.fad.fa-bars-sort::after, .fa-duotone.fa-bars-sort::after {content: "\e0ae\e0ae";}.fad.fa-bars-staggered::after, .fa-duotone.fa-bars-staggered::after {content: "\f550\f550";}.fad.fa-reorder::after, .fa-duotone.fa-reorder::after {content: "\f550\f550";}.fad.fa-stream::after, .fa-duotone.fa-stream::after {content: "\f550\f550";}.fad.fa-baseball::after, .fa-duotone.fa-baseball::after {content: "\f433\f433";}.fad.fa-baseball-ball::after, .fa-duotone.fa-baseball-ball::after {content: "\f433\f433";}.fad.fa-baseball-bat-ball::after, .fa-duotone.fa-baseball-bat-ball::after {content: "\f432\f432";}.fad.fa-basket-shopping::after, .fa-duotone.fa-basket-shopping::after {content: "\f291\f291";}.fad.fa-shopping-basket::after, .fa-duotone.fa-shopping-basket::after {content: "\f291\f291";}.fad.fa-basket-shopping-simple::after, .fa-duotone.fa-basket-shopping-simple::after {content: "\e0af\e0af";}.fad.fa-shopping-basket-alt::after, .fa-duotone.fa-shopping-basket-alt::after {content: "\e0af\e0af";}.fad.fa-basketball::after, .fa-duotone.fa-basketball::after {content: "\f434\f434";}.fad.fa-basketball-ball::after, .fa-duotone.fa-basketball-ball::after {content: "\f434\f434";}.fad.fa-basketball-hoop::after, .fa-duotone.fa-basketball-hoop::after {content: "\f435\f435";}.fad.fa-bat::after, .fa-duotone.fa-bat::after {content: "\f6b5\f6b5";}.fad.fa-bath::after, .fa-duotone.fa-bath::after {content: "\f2cd\f2cd";}.fad.fa-bathtub::after, .fa-duotone.fa-bathtub::after {content: "\f2cd\f2cd";}.fad.fa-battery-bolt::after, .fa-duotone.fa-battery-bolt::after {content: "\f376\f376";}.fad.fa-battery-empty::after, .fa-duotone.fa-battery-empty::after {content: "\f244\f244";}.fad.fa-battery-0::after, .fa-duotone.fa-battery-0::after {content: "\f244\f244";}.fad.fa-battery-exclamation::after, .fa-duotone.fa-battery-exclamation::after {content: "\e0b0\e0b0";}.fad.fa-battery-full::after, .fa-duotone.fa-battery-full::after {content: "\f240\f240";}.fad.fa-battery::after, .fa-duotone.fa-battery::after {content: "\f240\f240";}.fad.fa-battery-5::after, .fa-duotone.fa-battery-5::after {content: "\f240\f240";}.fad.fa-battery-half::after, .fa-duotone.fa-battery-half::after {content: "\f242\f242";}.fad.fa-battery-3::after, .fa-duotone.fa-battery-3::after {content: "\f242\f242";}.fad.fa-battery-low::after, .fa-duotone.fa-battery-low::after {content: "\e0b1\e0b1";}.fad.fa-battery-1::after, .fa-duotone.fa-battery-1::after {content: "\e0b1\e0b1";}.fad.fa-battery-quarter::after, .fa-duotone.fa-battery-quarter::after {content: "\f243\f243";}.fad.fa-battery-2::after, .fa-duotone.fa-battery-2::after {content: "\f243\f243";}.fad.fa-battery-slash::after, .fa-duotone.fa-battery-slash::after {content: "\f377\f377";}.fad.fa-battery-three-quarters::after, .fa-duotone.fa-battery-three-quarters::after {content: "\f241\f241";}.fad.fa-battery-4::after, .fa-duotone.fa-battery-4::after {content: "\f241\f241";}.fad.fa-bed::after, .fa-duotone.fa-bed::after {content: "\f236\f236";}.fad.fa-bed-bunk::after, .fa-duotone.fa-bed-bunk::after {content: "\f8f8\f8f8";}.fad.fa-bed-empty::after, .fa-duotone.fa-bed-empty::after {content: "\f8f9\f8f9";}.fad.fa-bed-front::after, .fa-duotone.fa-bed-front::after {content: "\f8f7\f8f7";}.fad.fa-bed-alt::after, .fa-duotone.fa-bed-alt::after {content: "\f8f7\f8f7";}.fad.fa-bed-pulse::after, .fa-duotone.fa-bed-pulse::after {content: "\f487\f487";}.fad.fa-procedures::after, .fa-duotone.fa-procedures::after {content: "\f487\f487";}.fad.fa-bee::after, .fa-duotone.fa-bee::after {content: "\e0b2\e0b2";}.fad.fa-beer-mug::after, .fa-duotone.fa-beer-mug::after {content: "\e0b3\e0b3";}.fad.fa-beer-foam::after, .fa-duotone.fa-beer-foam::after {content: "\e0b3\e0b3";}.fad.fa-beer-mug-empty::after, .fa-duotone.fa-beer-mug-empty::after {content: "\f0fc\f0fc";}.fad.fa-beer::after, .fa-duotone.fa-beer::after {content: "\f0fc\f0fc";}.fad.fa-bell::after, .fa-duotone.fa-bell::after {content: "\f0f3\f0f3";}.fad.fa-bell-concierge::after, .fa-duotone.fa-bell-concierge::after {content: "\f562\f562";}.fad.fa-concierge-bell::after, .fa-duotone.fa-concierge-bell::after {content: "\f562\f562";}.fad.fa-bell-exclamation::after, .fa-duotone.fa-bell-exclamation::after {content: "\f848\f848";}.fad.fa-bell-on::after, .fa-duotone.fa-bell-on::after {content: "\f8fa\f8fa";}.fad.fa-bell-plus::after, .fa-duotone.fa-bell-plus::after {content: "\f849\f849";}.fad.fa-bell-school::after, .fa-duotone.fa-bell-school::after {content: "\f5d5\f5d5";}.fad.fa-bell-school-slash::after, .fa-duotone.fa-bell-school-slash::after {content: "\f5d6\f5d6";}.fad.fa-bell-slash::after, .fa-duotone.fa-bell-slash::after {content: "\f1f6\f1f6";}.fad.fa-bells::after, .fa-duotone.fa-bells::after {content: "\f77f\f77f";}.fad.fa-bench-tree::after, .fa-duotone.fa-bench-tree::after {content: "\e2e7\e2e7";}.fad.fa-bezier-curve::after, .fa-duotone.fa-bezier-curve::after {content: "\f55b\f55b";}.fad.fa-bicycle::after, .fa-duotone.fa-bicycle::after {content: "\f206\f206";}.fad.fa-binary::after, .fa-duotone.fa-binary::after {content: "\e33b\e33b";}.fad.fa-binary-circle-check::after, .fa-duotone.fa-binary-circle-check::after {content: "\e33c\e33c";}.fad.fa-binary-lock::after, .fa-duotone.fa-binary-lock::after {content: "\e33d\e33d";}.fad.fa-binary-slash::after, .fa-duotone.fa-binary-slash::after {content: "\e33e\e33e";}.fad.fa-binoculars::after, .fa-duotone.fa-binoculars::after {content: "\f1e5\f1e5";}.fad.fa-biohazard::after, .fa-duotone.fa-biohazard::after {content: "\f780\f780";}.fad.fa-bird::after, .fa-duotone.fa-bird::after {content: "\e469\e469";}.fad.fa-bitcoin-sign::after, .fa-duotone.fa-bitcoin-sign::after {content: "\e0b4\e0b4";}.fad.fa-blanket::after, .fa-duotone.fa-blanket::after {content: "\f498\f498";}.fad.fa-blanket-fire::after, .fa-duotone.fa-blanket-fire::after {content: "\e3da\e3da";}.fad.fa-blender::after, .fa-duotone.fa-blender::after {content: "\f517\f517";}.fad.fa-blender-phone::after, .fa-duotone.fa-blender-phone::after {content: "\f6b6\f6b6";}.fad.fa-blinds::after, .fa-duotone.fa-blinds::after {content: "\f8fb\f8fb";}.fad.fa-blinds-open::after, .fa-duotone.fa-blinds-open::after {content: "\f8fc\f8fc";}.fad.fa-blinds-raised::after, .fa-duotone.fa-blinds-raised::after {content: "\f8fd\f8fd";}.fad.fa-block::after, .fa-duotone.fa-block::after {content: "\e46a\e46a";}.fad.fa-block-brick::after, .fa-duotone.fa-block-brick::after {content: "\e3db\e3db";}.fad.fa-wall-brick::after, .fa-duotone.fa-wall-brick::after {content: "\e3db\e3db";}.fad.fa-block-brick-fire::after, .fa-duotone.fa-block-brick-fire::after {content: "\e3dc\e3dc";}.fad.fa-firewall::after, .fa-duotone.fa-firewall::after {content: "\e3dc\e3dc";}.fad.fa-block-question::after, .fa-duotone.fa-block-question::after {content: "\e3dd\e3dd";}.fad.fa-block-quote::after, .fa-duotone.fa-block-quote::after {content: "\e0b5\e0b5";}.fad.fa-blog::after, .fa-duotone.fa-blog::after {content: "\f781\f781";}.fad.fa-blueberries::after, .fa-duotone.fa-blueberries::after {content: "\e2e8\e2e8";}.fad.fa-bold::after, .fa-duotone.fa-bold::after {content: "\f032\f032";}.fad.fa-bolt::after, .fa-duotone.fa-bolt::after {content: "\f0e7\f0e7";}.fad.fa-zap::after, .fa-duotone.fa-zap::after {content: "\f0e7\f0e7";}.fad.fa-bolt-auto::after, .fa-duotone.fa-bolt-auto::after {content: "\e0b6\e0b6";}.fad.fa-bolt-lightning::after, .fa-duotone.fa-bolt-lightning::after {content: "\e0b7\e0b7";}.fad.fa-bolt-slash::after, .fa-duotone.fa-bolt-slash::after {content: "\e0b8\e0b8";}.fad.fa-bomb::after, .fa-duotone.fa-bomb::after {content: "\f1e2\f1e2";}.fad.fa-bone::after, .fa-duotone.fa-bone::after {content: "\f5d7\f5d7";}.fad.fa-bone-break::after, .fa-duotone.fa-bone-break::after {content: "\f5d8\f5d8";}.fad.fa-bong::after, .fa-duotone.fa-bong::after {content: "\f55c\f55c";}.fad.fa-book::after, .fa-duotone.fa-book::after {content: "\f02d\f02d";}.fad.fa-book-arrow-right::after, .fa-duotone.fa-book-arrow-right::after {content: "\e0b9\e0b9";}.fad.fa-book-arrow-up::after, .fa-duotone.fa-book-arrow-up::after {content: "\e0ba\e0ba";}.fad.fa-book-atlas::after, .fa-duotone.fa-book-atlas::after {content: "\f558\f558";}.fad.fa-atlas::after, .fa-duotone.fa-atlas::after {content: "\f558\f558";}.fad.fa-book-bible::after, .fa-duotone.fa-book-bible::after {content: "\f647\f647";}.fad.fa-bible::after, .fa-duotone.fa-bible::after {content: "\f647\f647";}.fad.fa-book-blank::after, .fa-duotone.fa-book-blank::after {content: "\f5d9\f5d9";}.fad.fa-book-alt::after, .fa-duotone.fa-book-alt::after {content: "\f5d9\f5d9";}.fad.fa-book-bookmark::after, .fa-duotone.fa-book-bookmark::after {content: "\e0bb\e0bb";}.fad.fa-book-circle-arrow-right::after, .fa-duotone.fa-book-circle-arrow-right::after {content: "\e0bc\e0bc";}.fad.fa-book-circle-arrow-up::after, .fa-duotone.fa-book-circle-arrow-up::after {content: "\e0bd\e0bd";}.fad.fa-book-copy::after, .fa-duotone.fa-book-copy::after {content: "\e0be\e0be";}.fad.fa-book-font::after, .fa-duotone.fa-book-font::after {content: "\e0bf\e0bf";}.fad.fa-book-heart::after, .fa-duotone.fa-book-heart::after {content: "\f499\f499";}.fad.fa-book-journal-whills::after, .fa-duotone.fa-book-journal-whills::after {content: "\f66a\f66a";}.fad.fa-journal-whills::after, .fa-duotone.fa-journal-whills::after {content: "\f66a\f66a";}.fad.fa-book-medical::after, .fa-duotone.fa-book-medical::after {content: "\f7e6\f7e6";}.fad.fa-book-open::after, .fa-duotone.fa-book-open::after {content: "\f518\f518";}.fad.fa-book-open-cover::after, .fa-duotone.fa-book-open-cover::after {content: "\e0c0\e0c0";}.fad.fa-book-open-alt::after, .fa-duotone.fa-book-open-alt::after {content: "\e0c0\e0c0";}.fad.fa-book-open-reader::after, .fa-duotone.fa-book-open-reader::after {content: "\f5da\f5da";}.fad.fa-book-reader::after, .fa-duotone.fa-book-reader::after {content: "\f5da\f5da";}.fad.fa-book-quran::after, .fa-duotone.fa-book-quran::after {content: "\f687\f687";}.fad.fa-quran::after, .fa-duotone.fa-quran::after {content: "\f687\f687";}.fad.fa-book-section::after, .fa-duotone.fa-book-section::after {content: "\e0c1\e0c1";}.fad.fa-book-law::after, .fa-duotone.fa-book-law::after {content: "\e0c1\e0c1";}.fad.fa-book-skull::after, .fa-duotone.fa-book-skull::after {content: "\f6b7\f6b7";}.fad.fa-book-dead::after, .fa-duotone.fa-book-dead::after {content: "\f6b7\f6b7";}.fad.fa-book-sparkles::after, .fa-duotone.fa-book-sparkles::after {content: "\f6b8\f6b8";}.fad.fa-book-spells::after, .fa-duotone.fa-book-spells::after {content: "\f6b8\f6b8";}.fad.fa-book-tanakh::after, .fa-duotone.fa-book-tanakh::after {content: "\f827\f827";}.fad.fa-tanakh::after, .fa-duotone.fa-tanakh::after {content: "\f827\f827";}.fad.fa-book-user::after, .fa-duotone.fa-book-user::after {content: "\f7e7\f7e7";}.fad.fa-bookmark::after, .fa-duotone.fa-bookmark::after {content: "\f02e\f02e";}.fad.fa-bookmark-slash::after, .fa-duotone.fa-bookmark-slash::after {content: "\e0c2\e0c2";}.fad.fa-books::after, .fa-duotone.fa-books::after {content: "\f5db\f5db";}.fad.fa-books-medical::after, .fa-duotone.fa-books-medical::after {content: "\f7e8\f7e8";}.fad.fa-boombox::after, .fa-duotone.fa-boombox::after {content: "\f8a5\f8a5";}.fad.fa-boot::after, .fa-duotone.fa-boot::after {content: "\f782\f782";}.fad.fa-boot-heeled::after, .fa-duotone.fa-boot-heeled::after {content: "\e33f\e33f";}.fad.fa-booth-curtain::after, .fa-duotone.fa-booth-curtain::after {content: "\f734\f734";}.fad.fa-border-all::after, .fa-duotone.fa-border-all::after {content: "\f84c\f84c";}.fad.fa-border-bottom::after, .fa-duotone.fa-border-bottom::after {content: "\f84d\f84d";}.fad.fa-border-bottom-right::after, .fa-duotone.fa-border-bottom-right::after {content: "\f854\f854";}.fad.fa-border-style-alt::after, .fa-duotone.fa-border-style-alt::after {content: "\f854\f854";}.fad.fa-border-center-h::after, .fa-duotone.fa-border-center-h::after {content: "\f89c\f89c";}.fad.fa-border-center-v::after, .fa-duotone.fa-border-center-v::after {content: "\f89d\f89d";}.fad.fa-border-inner::after, .fa-duotone.fa-border-inner::after {content: "\f84e\f84e";}.fad.fa-border-left::after, .fa-duotone.fa-border-left::after {content: "\f84f\f84f";}.fad.fa-border-none::after, .fa-duotone.fa-border-none::after {content: "\f850\f850";}.fad.fa-border-outer::after, .fa-duotone.fa-border-outer::after {content: "\f851\f851";}.fad.fa-border-right::after, .fa-duotone.fa-border-right::after {content: "\f852\f852";}.fad.fa-border-top::after, .fa-duotone.fa-border-top::after {content: "\f855\f855";}.fad.fa-border-top-left::after, .fa-duotone.fa-border-top-left::after {content: "\f853\f853";}.fad.fa-border-style::after, .fa-duotone.fa-border-style::after {content: "\f853\f853";}.fad.fa-bore-hole::after, .fa-duotone.fa-bore-hole::after {content: "\e4c3\e4c3";}.fad.fa-bottle-droplet::after, .fa-duotone.fa-bottle-droplet::after {content: "\e4c4\e4c4";}.fad.fa-bottle-water::after, .fa-duotone.fa-bottle-water::after {content: "\e4c5\e4c5";}.fad.fa-bow-arrow::after, .fa-duotone.fa-bow-arrow::after {content: "\f6b9\f6b9";}.fad.fa-bowl-chopsticks::after, .fa-duotone.fa-bowl-chopsticks::after {content: "\e2e9\e2e9";}.fad.fa-bowl-chopsticks-noodles::after, .fa-duotone.fa-bowl-chopsticks-noodles::after {content: "\e2ea\e2ea";}.fad.fa-bowl-food::after, .fa-duotone.fa-bowl-food::after {content: "\e4c6\e4c6";}.fad.fa-bowl-hot::after, .fa-duotone.fa-bowl-hot::after {content: "\f823\f823";}.fad.fa-soup::after, .fa-duotone.fa-soup::after {content: "\f823\f823";}.fad.fa-bowl-rice::after, .fa-duotone.fa-bowl-rice::after {content: "\e2eb\e2eb";}.fad.fa-bowl-scoop::after, .fa-duotone.fa-bowl-scoop::after {content: "\e3de\e3de";}.fad.fa-bowl-shaved-ice::after, .fa-duotone.fa-bowl-shaved-ice::after {content: "\e3de\e3de";}.fad.fa-bowl-scoops::after, .fa-duotone.fa-bowl-scoops::after {content: "\e3df\e3df";}.fad.fa-bowl-soft-serve::after, .fa-duotone.fa-bowl-soft-serve::after {content: "\e46b\e46b";}.fad.fa-bowl-spoon::after, .fa-duotone.fa-bowl-spoon::after {content: "\e3e0\e3e0";}.fad.fa-bowling-ball::after, .fa-duotone.fa-bowling-ball::after {content: "\f436\f436";}.fad.fa-bowling-ball-pin::after, .fa-duotone.fa-bowling-ball-pin::after {content: "\e0c3\e0c3";}.fad.fa-bowling-pins::after, .fa-duotone.fa-bowling-pins::after {content: "\f437\f437";}.fad.fa-box::after, .fa-duotone.fa-box::after {content: "\f466\f466";}.fad.fa-box-archive::after, .fa-duotone.fa-box-archive::after {content: "\f187\f187";}.fad.fa-archive::after, .fa-duotone.fa-archive::after {content: "\f187\f187";}.fad.fa-box-ballot::after, .fa-duotone.fa-box-ballot::after {content: "\f735\f735";}.fad.fa-box-check::after, .fa-duotone.fa-box-check::after {content: "\f467\f467";}.fad.fa-box-circle-check::after, .fa-duotone.fa-box-circle-check::after {content: "\e0c4\e0c4";}.fad.fa-box-dollar::after, .fa-duotone.fa-box-dollar::after {content: "\f4a0\f4a0";}.fad.fa-box-usd::after, .fa-duotone.fa-box-usd::after {content: "\f4a0\f4a0";}.fad.fa-box-heart::after, .fa-duotone.fa-box-heart::after {content: "\f49d\f49d";}.fad.fa-box-open::after, .fa-duotone.fa-box-open::after {content: "\f49e\f49e";}.fad.fa-box-open-full::after, .fa-duotone.fa-box-open-full::after {content: "\f49c\f49c";}.fad.fa-box-full::after, .fa-duotone.fa-box-full::after {content: "\f49c\f49c";}.fad.fa-box-taped::after, .fa-duotone.fa-box-taped::after {content: "\f49a\f49a";}.fad.fa-box-alt::after, .fa-duotone.fa-box-alt::after {content: "\f49a\f49a";}.fad.fa-box-tissue::after, .fa-duotone.fa-box-tissue::after {content: "\e05b\e05b";}.fad.fa-boxes-packing::after, .fa-duotone.fa-boxes-packing::after {content: "\e4c7\e4c7";}.fad.fa-boxes-stacked::after, .fa-duotone.fa-boxes-stacked::after {content: "\f468\f468";}.fad.fa-boxes::after, .fa-duotone.fa-boxes::after {content: "\f468\f468";}.fad.fa-boxes-alt::after, .fa-duotone.fa-boxes-alt::after {content: "\f468\f468";}.fad.fa-boxing-glove::after, .fa-duotone.fa-boxing-glove::after {content: "\f438\f438";}.fad.fa-glove-boxing::after, .fa-duotone.fa-glove-boxing::after {content: "\f438\f438";}.fad.fa-bracket-curly::after, .fa-duotone.fa-bracket-curly::after {content: "\7b\7b";}.fad.fa-bracket-curly-left::after, .fa-duotone.fa-bracket-curly-left::after {content: "\7b\7b";}.fad.fa-bracket-curly-right::after, .fa-duotone.fa-bracket-curly-right::after {content: "\7d\7d";}.fad.fa-bracket-round::after, .fa-duotone.fa-bracket-round::after {content: "\28\28";}.fad.fa-parenthesis::after, .fa-duotone.fa-parenthesis::after {content: "\28\28";}.fad.fa-bracket-round-right::after, .fa-duotone.fa-bracket-round-right::after {content: "\29\29";}.fad.fa-bracket-square::after, .fa-duotone.fa-bracket-square::after {content: "\5b\5b";}.fad.fa-bracket::after, .fa-duotone.fa-bracket::after {content: "\5b\5b";}.fad.fa-bracket-left::after, .fa-duotone.fa-bracket-left::after {content: "\5b\5b";}.fad.fa-bracket-square-right::after, .fa-duotone.fa-bracket-square-right::after {content: "\5d\5d";}.fad.fa-brackets-curly::after, .fa-duotone.fa-brackets-curly::after {content: "\f7ea\f7ea";}.fad.fa-brackets-round::after, .fa-duotone.fa-brackets-round::after {content: "\e0c5\e0c5";}.fad.fa-parentheses::after, .fa-duotone.fa-parentheses::after {content: "\e0c5\e0c5";}.fad.fa-brackets-square::after, .fa-duotone.fa-brackets-square::after {content: "\f7e9\f7e9";}.fad.fa-brackets::after, .fa-duotone.fa-brackets::after {content: "\f7e9\f7e9";}.fad.fa-braille::after, .fa-duotone.fa-braille::after {content: "\f2a1\f2a1";}.fad.fa-brain::after, .fa-duotone.fa-brain::after {content: "\f5dc\f5dc";}.fad.fa-brain-arrow-curved-right::after, .fa-duotone.fa-brain-arrow-curved-right::after {content: "\f677\f677";}.fad.fa-mind-share::after, .fa-duotone.fa-mind-share::after {content: "\f677\f677";}.fad.fa-brain-circuit::after, .fa-duotone.fa-brain-circuit::after {content: "\e0c6\e0c6";}.fad.fa-brake-warning::after, .fa-duotone.fa-brake-warning::after {content: "\e0c7\e0c7";}.fad.fa-brazilian-real-sign::after, .fa-duotone.fa-brazilian-real-sign::after {content: "\e46c\e46c";}.fad.fa-bread-loaf::after, .fa-duotone.fa-bread-loaf::after {content: "\f7eb\f7eb";}.fad.fa-bread-slice::after, .fa-duotone.fa-bread-slice::after {content: "\f7ec\f7ec";}.fad.fa-bread-slice-butter::after, .fa-duotone.fa-bread-slice-butter::after {content: "\e3e1\e3e1";}.fad.fa-bridge::after, .fa-duotone.fa-bridge::after {content: "\e4c8\e4c8";}.fad.fa-bridge-circle-check::after, .fa-duotone.fa-bridge-circle-check::after {content: "\e4c9\e4c9";}.fad.fa-bridge-circle-exclamation::after, .fa-duotone.fa-bridge-circle-exclamation::after {content: "\e4ca\e4ca";}.fad.fa-bridge-circle-xmark::after, .fa-duotone.fa-bridge-circle-xmark::after {content: "\e4cb\e4cb";}.fad.fa-bridge-lock::after, .fa-duotone.fa-bridge-lock::after {content: "\e4cc\e4cc";}.fad.fa-bridge-suspension::after, .fa-duotone.fa-bridge-suspension::after {content: "\e4cd\e4cd";}.fad.fa-bridge-water::after, .fa-duotone.fa-bridge-water::after {content: "\e4ce\e4ce";}.fad.fa-briefcase::after, .fa-duotone.fa-briefcase::after {content: "\f0b1\f0b1";}.fad.fa-briefcase-arrow-right::after, .fa-duotone.fa-briefcase-arrow-right::after {content: "\e2f2\e2f2";}.fad.fa-briefcase-blank::after, .fa-duotone.fa-briefcase-blank::after {content: "\e0c8\e0c8";}.fad.fa-briefcase-medical::after, .fa-duotone.fa-briefcase-medical::after {content: "\f469\f469";}.fad.fa-brightness::after, .fa-duotone.fa-brightness::after {content: "\e0c9\e0c9";}.fad.fa-brightness-low::after, .fa-duotone.fa-brightness-low::after {content: "\e0ca\e0ca";}.fad.fa-bring-forward::after, .fa-duotone.fa-bring-forward::after {content: "\f856\f856";}.fad.fa-bring-front::after, .fa-duotone.fa-bring-front::after {content: "\f857\f857";}.fad.fa-broccoli::after, .fa-duotone.fa-broccoli::after {content: "\e3e2\e3e2";}.fad.fa-broom::after, .fa-duotone.fa-broom::after {content: "\f51a\f51a";}.fad.fa-broom-ball::after, .fa-duotone.fa-broom-ball::after {content: "\f458\f458";}.fad.fa-quidditch::after, .fa-duotone.fa-quidditch::after {content: "\f458\f458";}.fad.fa-quidditch-broom-ball::after, .fa-duotone.fa-quidditch-broom-ball::after {content: "\f458\f458";}.fad.fa-browser::after, .fa-duotone.fa-browser::after {content: "\f37e\f37e";}.fad.fa-browsers::after, .fa-duotone.fa-browsers::after {content: "\e0cb\e0cb";}.fad.fa-brush::after, .fa-duotone.fa-brush::after {content: "\f55d\f55d";}.fad.fa-bucket::after, .fa-duotone.fa-bucket::after {content: "\e4cf\e4cf";}.fad.fa-bug::after, .fa-duotone.fa-bug::after {content: "\f188\f188";}.fad.fa-bug-slash::after, .fa-duotone.fa-bug-slash::after {content: "\e490\e490";}.fad.fa-bugs::after, .fa-duotone.fa-bugs::after {content: "\e4d0\e4d0";}.fad.fa-building::after, .fa-duotone.fa-building::after {content: "\f1ad\f1ad";}.fad.fa-building-circle-arrow-right::after, .fa-duotone.fa-building-circle-arrow-right::after {content: "\e4d1\e4d1";}.fad.fa-building-circle-check::after, .fa-duotone.fa-building-circle-check::after {content: "\e4d2\e4d2";}.fad.fa-building-circle-exclamation::after, .fa-duotone.fa-building-circle-exclamation::after {content: "\e4d3\e4d3";}.fad.fa-building-circle-xmark::after, .fa-duotone.fa-building-circle-xmark::after {content: "\e4d4\e4d4";}.fad.fa-building-columns::after, .fa-duotone.fa-building-columns::after {content: "\f19c\f19c";}.fad.fa-bank::after, .fa-duotone.fa-bank::after {content: "\f19c\f19c";}.fad.fa-institution::after, .fa-duotone.fa-institution::after {content: "\f19c\f19c";}.fad.fa-museum::after, .fa-duotone.fa-museum::after {content: "\f19c\f19c";}.fad.fa-university::after, .fa-duotone.fa-university::after {content: "\f19c\f19c";}.fad.fa-building-flag::after, .fa-duotone.fa-building-flag::after {content: "\e4d5\e4d5";}.fad.fa-building-lock::after, .fa-duotone.fa-building-lock::after {content: "\e4d6\e4d6";}.fad.fa-building-ngo::after, .fa-duotone.fa-building-ngo::after {content: "\e4d7\e4d7";}.fad.fa-building-shield::after, .fa-duotone.fa-building-shield::after {content: "\e4d8\e4d8";}.fad.fa-building-un::after, .fa-duotone.fa-building-un::after {content: "\e4d9\e4d9";}.fad.fa-building-user::after, .fa-duotone.fa-building-user::after {content: "\e4da\e4da";}.fad.fa-building-wheat::after, .fa-duotone.fa-building-wheat::after {content: "\e4db\e4db";}.fad.fa-buildings::after, .fa-duotone.fa-buildings::after {content: "\e0cc\e0cc";}.fad.fa-bullhorn::after, .fa-duotone.fa-bullhorn::after {content: "\f0a1\f0a1";}.fad.fa-bullseye::after, .fa-duotone.fa-bullseye::after {content: "\f140\f140";}.fad.fa-bullseye-arrow::after, .fa-duotone.fa-bullseye-arrow::after {content: "\f648\f648";}.fad.fa-bullseye-pointer::after, .fa-duotone.fa-bullseye-pointer::after {content: "\f649\f649";}.fad.fa-burger::after, .fa-duotone.fa-burger::after {content: "\f805\f805";}.fad.fa-hamburger::after, .fa-duotone.fa-hamburger::after {content: "\f805\f805";}.fad.fa-burger-cheese::after, .fa-duotone.fa-burger-cheese::after {content: "\f7f1\f7f1";}.fad.fa-cheeseburger::after, .fa-duotone.fa-cheeseburger::after {content: "\f7f1\f7f1";}.fad.fa-burger-fries::after, .fa-duotone.fa-burger-fries::after {content: "\e0cd\e0cd";}.fad.fa-burger-glass::after, .fa-duotone.fa-burger-glass::after {content: "\e0ce\e0ce";}.fad.fa-burger-lettuce::after, .fa-duotone.fa-burger-lettuce::after {content: "\e3e3\e3e3";}.fad.fa-burger-soda::after, .fa-duotone.fa-burger-soda::after {content: "\f858\f858";}.fad.fa-burrito::after, .fa-duotone.fa-burrito::after {content: "\f7ed\f7ed";}.fad.fa-burst::after, .fa-duotone.fa-burst::after {content: "\e4dc\e4dc";}.fad.fa-bus::after, .fa-duotone.fa-bus::after {content: "\f207\f207";}.fad.fa-bus-school::after, .fa-duotone.fa-bus-school::after {content: "\f5dd\f5dd";}.fad.fa-bus-simple::after, .fa-duotone.fa-bus-simple::after {content: "\f55e\f55e";}.fad.fa-bus-alt::after, .fa-duotone.fa-bus-alt::after {content: "\f55e\f55e";}.fad.fa-business-time::after, .fa-duotone.fa-business-time::after {content: "\f64a\f64a";}.fad.fa-briefcase-clock::after, .fa-duotone.fa-briefcase-clock::after {content: "\f64a\f64a";}.fad.fa-butter::after, .fa-duotone.fa-butter::after {content: "\e3e4\e3e4";}.fad.fa-c::after, .fa-duotone.fa-c::after {content: "\43\43";}.fad.fa-cabin::after, .fa-duotone.fa-cabin::after {content: "\e46d\e46d";}.fad.fa-cabinet-filing::after, .fa-duotone.fa-cabinet-filing::after {content: "\f64b\f64b";}.fad.fa-cable-car::after, .fa-duotone.fa-cable-car::after {content: "\e0cf\e0cf";}.fad.fa-cactus::after, .fa-duotone.fa-cactus::after {content: "\f8a7\f8a7";}.fad.fa-cake-candles::after, .fa-duotone.fa-cake-candles::after {content: "\f1fd\f1fd";}.fad.fa-birthday-cake::after, .fa-duotone.fa-birthday-cake::after {content: "\f1fd\f1fd";}.fad.fa-cake::after, .fa-duotone.fa-cake::after {content: "\f1fd\f1fd";}.fad.fa-cake-slice::after, .fa-duotone.fa-cake-slice::after {content: "\e3e5\e3e5";}.fad.fa-shortcake::after, .fa-duotone.fa-shortcake::after {content: "\e3e5\e3e5";}.fad.fa-calculator::after, .fa-duotone.fa-calculator::after {content: "\f1ec\f1ec";}.fad.fa-calculator-simple::after, .fa-duotone.fa-calculator-simple::after {content: "\f64c\f64c";}.fad.fa-calculator-alt::after, .fa-duotone.fa-calculator-alt::after {content: "\f64c\f64c";}.fad.fa-calendar::after, .fa-duotone.fa-calendar::after {content: "\f133\f133";}.fad.fa-calendar-arrow-down::after, .fa-duotone.fa-calendar-arrow-down::after {content: "\e0d0\e0d0";}.fad.fa-calendar-download::after, .fa-duotone.fa-calendar-download::after {content: "\e0d0\e0d0";}.fad.fa-calendar-arrow-up::after, .fa-duotone.fa-calendar-arrow-up::after {content: "\e0d1\e0d1";}.fad.fa-calendar-upload::after, .fa-duotone.fa-calendar-upload::after {content: "\e0d1\e0d1";}.fad.fa-calendar-check::after, .fa-duotone.fa-calendar-check::after {content: "\f274\f274";}.fad.fa-calendar-circle-exclamation::after, .fa-duotone.fa-calendar-circle-exclamation::after {content: "\e46e\e46e";}.fad.fa-calendar-circle-minus::after, .fa-duotone.fa-calendar-circle-minus::after {content: "\e46f\e46f";}.fad.fa-calendar-circle-plus::after, .fa-duotone.fa-calendar-circle-plus::after {content: "\e470\e470";}.fad.fa-calendar-circle-user::after, .fa-duotone.fa-calendar-circle-user::after {content: "\e471\e471";}.fad.fa-calendar-clock::after, .fa-duotone.fa-calendar-clock::after {content: "\e0d2\e0d2";}.fad.fa-calendar-time::after, .fa-duotone.fa-calendar-time::after {content: "\e0d2\e0d2";}.fad.fa-calendar-day::after, .fa-duotone.fa-calendar-day::after {content: "\f783\f783";}.fad.fa-calendar-days::after, .fa-duotone.fa-calendar-days::after {content: "\f073\f073";}.fad.fa-calendar-alt::after, .fa-duotone.fa-calendar-alt::after {content: "\f073\f073";}.fad.fa-calendar-exclamation::after, .fa-duotone.fa-calendar-exclamation::after {content: "\f334\f334";}.fad.fa-calendar-heart::after, .fa-duotone.fa-calendar-heart::after {content: "\e0d3\e0d3";}.fad.fa-calendar-image::after, .fa-duotone.fa-calendar-image::after {content: "\e0d4\e0d4";}.fad.fa-calendar-lines::after, .fa-duotone.fa-calendar-lines::after {content: "\e0d5\e0d5";}.fad.fa-calendar-note::after, .fa-duotone.fa-calendar-note::after {content: "\e0d5\e0d5";}.fad.fa-calendar-lines-pen::after, .fa-duotone.fa-calendar-lines-pen::after {content: "\e472\e472";}.fad.fa-calendar-minus::after, .fa-duotone.fa-calendar-minus::after {content: "\f272\f272";}.fad.fa-calendar-pen::after, .fa-duotone.fa-calendar-pen::after {content: "\f333\f333";}.fad.fa-calendar-edit::after, .fa-duotone.fa-calendar-edit::after {content: "\f333\f333";}.fad.fa-calendar-plus::after, .fa-duotone.fa-calendar-plus::after {content: "\f271\f271";}.fad.fa-calendar-range::after, .fa-duotone.fa-calendar-range::after {content: "\e0d6\e0d6";}.fad.fa-calendar-star::after, .fa-duotone.fa-calendar-star::after {content: "\f736\f736";}.fad.fa-calendar-week::after, .fa-duotone.fa-calendar-week::after {content: "\f784\f784";}.fad.fa-calendar-xmark::after, .fa-duotone.fa-calendar-xmark::after {content: "\f273\f273";}.fad.fa-calendar-times::after, .fa-duotone.fa-calendar-times::after {content: "\f273\f273";}.fad.fa-calendars::after, .fa-duotone.fa-calendars::after {content: "\e0d7\e0d7";}.fad.fa-camcorder::after, .fa-duotone.fa-camcorder::after {content: "\f8a8\f8a8";}.fad.fa-video-handheld::after, .fa-duotone.fa-video-handheld::after {content: "\f8a8\f8a8";}.fad.fa-camera::after, .fa-duotone.fa-camera::after {content: "\f030\f030";}.fad.fa-camera-alt::after, .fa-duotone.fa-camera-alt::after {content: "\f030\f030";}.fad.fa-camera-cctv::after, .fa-duotone.fa-camera-cctv::after {content: "\f8ac\f8ac";}.fad.fa-cctv::after, .fa-duotone.fa-cctv::after {content: "\f8ac\f8ac";}.fad.fa-camera-movie::after, .fa-duotone.fa-camera-movie::after {content: "\f8a9\f8a9";}.fad.fa-camera-polaroid::after, .fa-duotone.fa-camera-polaroid::after {content: "\f8aa\f8aa";}.fad.fa-camera-retro::after, .fa-duotone.fa-camera-retro::after {content: "\f083\f083";}.fad.fa-camera-rotate::after, .fa-duotone.fa-camera-rotate::after {content: "\e0d8\e0d8";}.fad.fa-camera-security::after, .fa-duotone.fa-camera-security::after {content: "\f8fe\f8fe";}.fad.fa-camera-home::after, .fa-duotone.fa-camera-home::after {content: "\f8fe\f8fe";}.fad.fa-camera-slash::after, .fa-duotone.fa-camera-slash::after {content: "\e0d9\e0d9";}.fad.fa-camera-viewfinder::after, .fa-duotone.fa-camera-viewfinder::after {content: "\e0da\e0da";}.fad.fa-screenshot::after, .fa-duotone.fa-screenshot::after {content: "\e0da\e0da";}.fad.fa-camera-web::after, .fa-duotone.fa-camera-web::after {content: "\f832\f832";}.fad.fa-webcam::after, .fa-duotone.fa-webcam::after {content: "\f832\f832";}.fad.fa-camera-web-slash::after, .fa-duotone.fa-camera-web-slash::after {content: "\f833\f833";}.fad.fa-webcam-slash::after, .fa-duotone.fa-webcam-slash::after {content: "\f833\f833";}.fad.fa-campfire::after, .fa-duotone.fa-campfire::after {content: "\f6ba\f6ba";}.fad.fa-campground::after, .fa-duotone.fa-campground::after {content: "\f6bb\f6bb";}.fad.fa-can-food::after, .fa-duotone.fa-can-food::after {content: "\e3e6\e3e6";}.fad.fa-candle-holder::after, .fa-duotone.fa-candle-holder::after {content: "\f6bc\f6bc";}.fad.fa-candy::after, .fa-duotone.fa-candy::after {content: "\e3e7\e3e7";}.fad.fa-candy-bar::after, .fa-duotone.fa-candy-bar::after {content: "\e3e8\e3e8";}.fad.fa-chocolate-bar::after, .fa-duotone.fa-chocolate-bar::after {content: "\e3e8\e3e8";}.fad.fa-candy-cane::after, .fa-duotone.fa-candy-cane::after {content: "\f786\f786";}.fad.fa-candy-corn::after, .fa-duotone.fa-candy-corn::after {content: "\f6bd\f6bd";}.fad.fa-cannabis::after, .fa-duotone.fa-cannabis::after {content: "\f55f\f55f";}.fad.fa-capsules::after, .fa-duotone.fa-capsules::after {content: "\f46b\f46b";}.fad.fa-car::after, .fa-duotone.fa-car::after {content: "\f1b9\f1b9";}.fad.fa-automobile::after, .fa-duotone.fa-automobile::after {content: "\f1b9\f1b9";}.fad.fa-car-battery::after, .fa-duotone.fa-car-battery::after {content: "\f5df\f5df";}.fad.fa-battery-car::after, .fa-duotone.fa-battery-car::after {content: "\f5df\f5df";}.fad.fa-car-bolt::after, .fa-duotone.fa-car-bolt::after {content: "\e341\e341";}.fad.fa-car-building::after, .fa-duotone.fa-car-building::after {content: "\f859\f859";}.fad.fa-car-bump::after, .fa-duotone.fa-car-bump::after {content: "\f5e0\f5e0";}.fad.fa-car-burst::after, .fa-duotone.fa-car-burst::after {content: "\f5e1\f5e1";}.fad.fa-car-crash::after, .fa-duotone.fa-car-crash::after {content: "\f5e1\f5e1";}.fad.fa-car-bus::after, .fa-duotone.fa-car-bus::after {content: "\f85a\f85a";}.fad.fa-car-circle-bolt::after, .fa-duotone.fa-car-circle-bolt::after {content: "\e342\e342";}.fad.fa-car-garage::after, .fa-duotone.fa-car-garage::after {content: "\f5e2\f5e2";}.fad.fa-car-mirrors::after, .fa-duotone.fa-car-mirrors::after {content: "\e343\e343";}.fad.fa-car-on::after, .fa-duotone.fa-car-on::after {content: "\e4dd\e4dd";}.fad.fa-car-rear::after, .fa-duotone.fa-car-rear::after {content: "\f5de\f5de";}.fad.fa-car-alt::after, .fa-duotone.fa-car-alt::after {content: "\f5de\f5de";}.fad.fa-car-side::after, .fa-duotone.fa-car-side::after {content: "\f5e4\f5e4";}.fad.fa-car-side-bolt::after, .fa-duotone.fa-car-side-bolt::after {content: "\e344\e344";}.fad.fa-car-tilt::after, .fa-duotone.fa-car-tilt::after {content: "\f5e5\f5e5";}.fad.fa-car-tunnel::after, .fa-duotone.fa-car-tunnel::after {content: "\e4de\e4de";}.fad.fa-car-wash::after, .fa-duotone.fa-car-wash::after {content: "\f5e6\f5e6";}.fad.fa-car-wrench::after, .fa-duotone.fa-car-wrench::after {content: "\f5e3\f5e3";}.fad.fa-car-mechanic::after, .fa-duotone.fa-car-mechanic::after {content: "\f5e3\f5e3";}.fad.fa-caravan::after, .fa-duotone.fa-caravan::after {content: "\f8ff\f8ff";}.fad.fa-caravan-simple::after, .fa-duotone.fa-caravan-simple::after {content: "\e000\e000";}.fad.fa-caravan-alt::after, .fa-duotone.fa-caravan-alt::after {content: "\e000\e000";}.fad.fa-card-club::after, .fa-duotone.fa-card-club::after {content: "\e3e9\e3e9";}.fad.fa-card-diamond::after, .fa-duotone.fa-card-diamond::after {content: "\e3ea\e3ea";}.fad.fa-card-heart::after, .fa-duotone.fa-card-heart::after {content: "\e3eb\e3eb";}.fad.fa-card-spade::after, .fa-duotone.fa-card-spade::after {content: "\e3ec\e3ec";}.fad.fa-cards::after, .fa-duotone.fa-cards::after {content: "\e3ed\e3ed";}.fad.fa-cards-blank::after, .fa-duotone.fa-cards-blank::after {content: "\e4df\e4df";}.fad.fa-caret-down::after, .fa-duotone.fa-caret-down::after {content: "\f0d7\f0d7";}.fad.fa-caret-left::after, .fa-duotone.fa-caret-left::after {content: "\f0d9\f0d9";}.fad.fa-caret-right::after, .fa-duotone.fa-caret-right::after {content: "\f0da\f0da";}.fad.fa-caret-up::after, .fa-duotone.fa-caret-up::after {content: "\f0d8\f0d8";}.fad.fa-carrot::after, .fa-duotone.fa-carrot::after {content: "\f787\f787";}.fad.fa-cars::after, .fa-duotone.fa-cars::after {content: "\f85b\f85b";}.fad.fa-cart-arrow-down::after, .fa-duotone.fa-cart-arrow-down::after {content: "\f218\f218";}.fad.fa-cart-arrow-up::after, .fa-duotone.fa-cart-arrow-up::after {content: "\e3ee\e3ee";}.fad.fa-cart-circle-arrow-down::after, .fa-duotone.fa-cart-circle-arrow-down::after {content: "\e3ef\e3ef";}.fad.fa-cart-circle-arrow-up::after, .fa-duotone.fa-cart-circle-arrow-up::after {content: "\e3f0\e3f0";}.fad.fa-cart-circle-check::after, .fa-duotone.fa-cart-circle-check::after {content: "\e3f1\e3f1";}.fad.fa-cart-circle-exclamation::after, .fa-duotone.fa-cart-circle-exclamation::after {content: "\e3f2\e3f2";}.fad.fa-cart-circle-plus::after, .fa-duotone.fa-cart-circle-plus::after {content: "\e3f3\e3f3";}.fad.fa-cart-circle-xmark::after, .fa-duotone.fa-cart-circle-xmark::after {content: "\e3f4\e3f4";}.fad.fa-cart-flatbed::after, .fa-duotone.fa-cart-flatbed::after {content: "\f474\f474";}.fad.fa-dolly-flatbed::after, .fa-duotone.fa-dolly-flatbed::after {content: "\f474\f474";}.fad.fa-cart-flatbed-boxes::after, .fa-duotone.fa-cart-flatbed-boxes::after {content: "\f475\f475";}.fad.fa-dolly-flatbed-alt::after, .fa-duotone.fa-dolly-flatbed-alt::after {content: "\f475\f475";}.fad.fa-cart-flatbed-empty::after, .fa-duotone.fa-cart-flatbed-empty::after {content: "\f476\f476";}.fad.fa-dolly-flatbed-empty::after, .fa-duotone.fa-dolly-flatbed-empty::after {content: "\f476\f476";}.fad.fa-cart-flatbed-suitcase::after, .fa-duotone.fa-cart-flatbed-suitcase::after {content: "\f59d\f59d";}.fad.fa-luggage-cart::after, .fa-duotone.fa-luggage-cart::after {content: "\f59d\f59d";}.fad.fa-cart-minus::after, .fa-duotone.fa-cart-minus::after {content: "\e0db\e0db";}.fad.fa-cart-plus::after, .fa-duotone.fa-cart-plus::after {content: "\f217\f217";}.fad.fa-cart-shopping::after, .fa-duotone.fa-cart-shopping::after {content: "\f07a\f07a";}.fad.fa-shopping-cart::after, .fa-duotone.fa-shopping-cart::after {content: "\f07a\f07a";}.fad.fa-cart-shopping-fast::after, .fa-duotone.fa-cart-shopping-fast::after {content: "\e0dc\e0dc";}.fad.fa-cart-xmark::after, .fa-duotone.fa-cart-xmark::after {content: "\e0dd\e0dd";}.fad.fa-cash-register::after, .fa-duotone.fa-cash-register::after {content: "\f788\f788";}.fad.fa-cassette-betamax::after, .fa-duotone.fa-cassette-betamax::after {content: "\f8a4\f8a4";}.fad.fa-betamax::after, .fa-duotone.fa-betamax::after {content: "\f8a4\f8a4";}.fad.fa-cassette-tape::after, .fa-duotone.fa-cassette-tape::after {content: "\f8ab\f8ab";}.fad.fa-cassette-vhs::after, .fa-duotone.fa-cassette-vhs::after {content: "\f8ec\f8ec";}.fad.fa-vhs::after, .fa-duotone.fa-vhs::after {content: "\f8ec\f8ec";}.fad.fa-castle::after, .fa-duotone.fa-castle::after {content: "\e0de\e0de";}.fad.fa-cat::after, .fa-duotone.fa-cat::after {content: "\f6be\f6be";}.fad.fa-cat-space::after, .fa-duotone.fa-cat-space::after {content: "\e001\e001";}.fad.fa-cauldron::after, .fa-duotone.fa-cauldron::after {content: "\f6bf\f6bf";}.fad.fa-cedi-sign::after, .fa-duotone.fa-cedi-sign::after {content: "\e0df\e0df";}.fad.fa-cent-sign::after, .fa-duotone.fa-cent-sign::after {content: "\e3f5\e3f5";}.fad.fa-certificate::after, .fa-duotone.fa-certificate::after {content: "\f0a3\f0a3";}.fad.fa-chair::after, .fa-duotone.fa-chair::after {content: "\f6c0\f6c0";}.fad.fa-chair-office::after, .fa-duotone.fa-chair-office::after {content: "\f6c1\f6c1";}.fad.fa-chalkboard::after, .fa-duotone.fa-chalkboard::after {content: "\f51b\f51b";}.fad.fa-blackboard::after, .fa-duotone.fa-blackboard::after {content: "\f51b\f51b";}.fad.fa-chalkboard-user::after, .fa-duotone.fa-chalkboard-user::after {content: "\f51c\f51c";}.fad.fa-chalkboard-teacher::after, .fa-duotone.fa-chalkboard-teacher::after {content: "\f51c\f51c";}.fad.fa-champagne-glass::after, .fa-duotone.fa-champagne-glass::after {content: "\f79e\f79e";}.fad.fa-glass-champagne::after, .fa-duotone.fa-glass-champagne::after {content: "\f79e\f79e";}.fad.fa-champagne-glasses::after, .fa-duotone.fa-champagne-glasses::after {content: "\f79f\f79f";}.fad.fa-glass-cheers::after, .fa-duotone.fa-glass-cheers::after {content: "\f79f\f79f";}.fad.fa-charging-station::after, .fa-duotone.fa-charging-station::after {content: "\f5e7\f5e7";}.fad.fa-chart-area::after, .fa-duotone.fa-chart-area::after {content: "\f1fe\f1fe";}.fad.fa-area-chart::after, .fa-duotone.fa-area-chart::after {content: "\f1fe\f1fe";}.fad.fa-chart-bar::after, .fa-duotone.fa-chart-bar::after {content: "\f080\f080";}.fad.fa-bar-chart::after, .fa-duotone.fa-bar-chart::after {content: "\f080\f080";}.fad.fa-chart-bullet::after, .fa-duotone.fa-chart-bullet::after {content: "\e0e1\e0e1";}.fad.fa-chart-candlestick::after, .fa-duotone.fa-chart-candlestick::after {content: "\e0e2\e0e2";}.fad.fa-chart-column::after, .fa-duotone.fa-chart-column::after {content: "\e0e3\e0e3";}.fad.fa-chart-gantt::after, .fa-duotone.fa-chart-gantt::after {content: "\e0e4\e0e4";}.fad.fa-chart-line::after, .fa-duotone.fa-chart-line::after {content: "\f201\f201";}.fad.fa-line-chart::after, .fa-duotone.fa-line-chart::after {content: "\f201\f201";}.fad.fa-chart-line-down::after, .fa-duotone.fa-chart-line-down::after {content: "\f64d\f64d";}.fad.fa-chart-line-up::after, .fa-duotone.fa-chart-line-up::after {content: "\e0e5\e0e5";}.fad.fa-chart-mixed::after, .fa-duotone.fa-chart-mixed::after {content: "\f643\f643";}.fad.fa-analytics::after, .fa-duotone.fa-analytics::after {content: "\f643\f643";}.fad.fa-chart-network::after, .fa-duotone.fa-chart-network::after {content: "\f78a\f78a";}.fad.fa-chart-pie::after, .fa-duotone.fa-chart-pie::after {content: "\f200\f200";}.fad.fa-pie-chart::after, .fa-duotone.fa-pie-chart::after {content: "\f200\f200";}.fad.fa-chart-pie-simple::after, .fa-duotone.fa-chart-pie-simple::after {content: "\f64e\f64e";}.fad.fa-chart-pie-alt::after, .fa-duotone.fa-chart-pie-alt::after {content: "\f64e\f64e";}.fad.fa-chart-pyramid::after, .fa-duotone.fa-chart-pyramid::after {content: "\e0e6\e0e6";}.fad.fa-chart-radar::after, .fa-duotone.fa-chart-radar::after {content: "\e0e7\e0e7";}.fad.fa-chart-scatter::after, .fa-duotone.fa-chart-scatter::after {content: "\f7ee\f7ee";}.fad.fa-chart-scatter-3d::after, .fa-duotone.fa-chart-scatter-3d::after {content: "\e0e8\e0e8";}.fad.fa-chart-scatter-bubble::after, .fa-duotone.fa-chart-scatter-bubble::after {content: "\e0e9\e0e9";}.fad.fa-chart-simple::after, .fa-duotone.fa-chart-simple::after {content: "\e473\e473";}.fad.fa-chart-simple-horizontal::after, .fa-duotone.fa-chart-simple-horizontal::after {content: "\e474\e474";}.fad.fa-chart-tree-map::after, .fa-duotone.fa-chart-tree-map::after {content: "\e0ea\e0ea";}.fad.fa-chart-user::after, .fa-duotone.fa-chart-user::after {content: "\f6a3\f6a3";}.fad.fa-user-chart::after, .fa-duotone.fa-user-chart::after {content: "\f6a3\f6a3";}.fad.fa-chart-waterfall::after, .fa-duotone.fa-chart-waterfall::after {content: "\e0eb\e0eb";}.fad.fa-check::after, .fa-duotone.fa-check::after {content: "\f00c\f00c";}.fad.fa-check-double::after, .fa-duotone.fa-check-double::after {content: "\f560\f560";}.fad.fa-check-to-slot::after, .fa-duotone.fa-check-to-slot::after {content: "\f772\f772";}.fad.fa-vote-yea::after, .fa-duotone.fa-vote-yea::after {content: "\f772\f772";}.fad.fa-cheese::after, .fa-duotone.fa-cheese::after {content: "\f7ef\f7ef";}.fad.fa-cheese-swiss::after, .fa-duotone.fa-cheese-swiss::after {content: "\f7f0\f7f0";}.fad.fa-cherries::after, .fa-duotone.fa-cherries::after {content: "\e0ec\e0ec";}.fad.fa-chess::after, .fa-duotone.fa-chess::after {content: "\f439\f439";}.fad.fa-chess-bishop::after, .fa-duotone.fa-chess-bishop::after {content: "\f43a\f43a";}.fad.fa-chess-bishop-piece::after, .fa-duotone.fa-chess-bishop-piece::after {content: "\f43b\f43b";}.fad.fa-chess-bishop-alt::after, .fa-duotone.fa-chess-bishop-alt::after {content: "\f43b\f43b";}.fad.fa-chess-board::after, .fa-duotone.fa-chess-board::after {content: "\f43c\f43c";}.fad.fa-chess-clock::after, .fa-duotone.fa-chess-clock::after {content: "\f43d\f43d";}.fad.fa-chess-clock-flip::after, .fa-duotone.fa-chess-clock-flip::after {content: "\f43e\f43e";}.fad.fa-chess-clock-alt::after, .fa-duotone.fa-chess-clock-alt::after {content: "\f43e\f43e";}.fad.fa-chess-king::after, .fa-duotone.fa-chess-king::after {content: "\f43f\f43f";}.fad.fa-chess-king-piece::after, .fa-duotone.fa-chess-king-piece::after {content: "\f440\f440";}.fad.fa-chess-king-alt::after, .fa-duotone.fa-chess-king-alt::after {content: "\f440\f440";}.fad.fa-chess-knight::after, .fa-duotone.fa-chess-knight::after {content: "\f441\f441";}.fad.fa-chess-knight-piece::after, .fa-duotone.fa-chess-knight-piece::after {content: "\f442\f442";}.fad.fa-chess-knight-alt::after, .fa-duotone.fa-chess-knight-alt::after {content: "\f442\f442";}.fad.fa-chess-pawn::after, .fa-duotone.fa-chess-pawn::after {content: "\f443\f443";}.fad.fa-chess-pawn-piece::after, .fa-duotone.fa-chess-pawn-piece::after {content: "\f444\f444";}.fad.fa-chess-pawn-alt::after, .fa-duotone.fa-chess-pawn-alt::after {content: "\f444\f444";}.fad.fa-chess-queen::after, .fa-duotone.fa-chess-queen::after {content: "\f445\f445";}.fad.fa-chess-queen-piece::after, .fa-duotone.fa-chess-queen-piece::after {content: "\f446\f446";}.fad.fa-chess-queen-alt::after, .fa-duotone.fa-chess-queen-alt::after {content: "\f446\f446";}.fad.fa-chess-rook::after, .fa-duotone.fa-chess-rook::after {content: "\f447\f447";}.fad.fa-chess-rook-piece::after, .fa-duotone.fa-chess-rook-piece::after {content: "\f448\f448";}.fad.fa-chess-rook-alt::after, .fa-duotone.fa-chess-rook-alt::after {content: "\f448\f448";}.fad.fa-chestnut::after, .fa-duotone.fa-chestnut::after {content: "\e3f6\e3f6";}.fad.fa-chevron-down::after, .fa-duotone.fa-chevron-down::after {content: "\f078\f078";}.fad.fa-chevron-left::after, .fa-duotone.fa-chevron-left::after {content: "\f053\f053";}.fad.fa-chevron-right::after, .fa-duotone.fa-chevron-right::after {content: "\f054\f054";}.fad.fa-chevron-up::after, .fa-duotone.fa-chevron-up::after {content: "\f077\f077";}.fad.fa-chevrons-down::after, .fa-duotone.fa-chevrons-down::after {content: "\f322\f322";}.fad.fa-chevron-double-down::after, .fa-duotone.fa-chevron-double-down::after {content: "\f322\f322";}.fad.fa-chevrons-left::after, .fa-duotone.fa-chevrons-left::after {content: "\f323\f323";}.fad.fa-chevron-double-left::after, .fa-duotone.fa-chevron-double-left::after {content: "\f323\f323";}.fad.fa-chevrons-right::after, .fa-duotone.fa-chevrons-right::after {content: "\f324\f324";}.fad.fa-chevron-double-right::after, .fa-duotone.fa-chevron-double-right::after {content: "\f324\f324";}.fad.fa-chevrons-up::after, .fa-duotone.fa-chevrons-up::after {content: "\f325\f325";}.fad.fa-chevron-double-up::after, .fa-duotone.fa-chevron-double-up::after {content: "\f325\f325";}.fad.fa-child::after, .fa-duotone.fa-child::after {content: "\f1ae\f1ae";}.fad.fa-child-dress::after, .fa-duotone.fa-child-dress::after {content: "\e59c\e59c";}.fad.fa-child-reaching::after, .fa-duotone.fa-child-reaching::after {content: "\e59d\e59d";}.fad.fa-child-rifle::after, .fa-duotone.fa-child-rifle::after {content: "\e4e0\e4e0";}.fad.fa-children::after, .fa-duotone.fa-children::after {content: "\e4e1\e4e1";}.fad.fa-chimney::after, .fa-duotone.fa-chimney::after {content: "\f78b\f78b";}.fad.fa-chopsticks::after, .fa-duotone.fa-chopsticks::after {content: "\e3f7\e3f7";}.fad.fa-church::after, .fa-duotone.fa-church::after {content: "\f51d\f51d";}.fad.fa-circle::after, .fa-duotone.fa-circle::after {content: "\f111\f111";}.fad.fa-circle-0::after, .fa-duotone.fa-circle-0::after {content: "\e0ed\e0ed";}.fad.fa-circle-1::after, .fa-duotone.fa-circle-1::after {content: "\e0ee\e0ee";}.fad.fa-circle-2::after, .fa-duotone.fa-circle-2::after {content: "\e0ef\e0ef";}.fad.fa-circle-3::after, .fa-duotone.fa-circle-3::after {content: "\e0f0\e0f0";}.fad.fa-circle-4::after, .fa-duotone.fa-circle-4::after {content: "\e0f1\e0f1";}.fad.fa-circle-5::after, .fa-duotone.fa-circle-5::after {content: "\e0f2\e0f2";}.fad.fa-circle-6::after, .fa-duotone.fa-circle-6::after {content: "\e0f3\e0f3";}.fad.fa-circle-7::after, .fa-duotone.fa-circle-7::after {content: "\e0f4\e0f4";}.fad.fa-circle-8::after, .fa-duotone.fa-circle-8::after {content: "\e0f5\e0f5";}.fad.fa-circle-9::after, .fa-duotone.fa-circle-9::after {content: "\e0f6\e0f6";}.fad.fa-circle-a::after, .fa-duotone.fa-circle-a::after {content: "\e0f7\e0f7";}.fad.fa-circle-ampersand::after, .fa-duotone.fa-circle-ampersand::after {content: "\e0f8\e0f8";}.fad.fa-circle-arrow-down::after, .fa-duotone.fa-circle-arrow-down::after {content: "\f0ab\f0ab";}.fad.fa-arrow-circle-down::after, .fa-duotone.fa-arrow-circle-down::after {content: "\f0ab\f0ab";}.fad.fa-circle-arrow-down-left::after, .fa-duotone.fa-circle-arrow-down-left::after {content: "\e0f9\e0f9";}.fad.fa-circle-arrow-down-right::after, .fa-duotone.fa-circle-arrow-down-right::after {content: "\e0fa\e0fa";}.fad.fa-circle-arrow-left::after, .fa-duotone.fa-circle-arrow-left::after {content: "\f0a8\f0a8";}.fad.fa-arrow-circle-left::after, .fa-duotone.fa-arrow-circle-left::after {content: "\f0a8\f0a8";}.fad.fa-circle-arrow-right::after, .fa-duotone.fa-circle-arrow-right::after {content: "\f0a9\f0a9";}.fad.fa-arrow-circle-right::after, .fa-duotone.fa-arrow-circle-right::after {content: "\f0a9\f0a9";}.fad.fa-circle-arrow-up::after, .fa-duotone.fa-circle-arrow-up::after {content: "\f0aa\f0aa";}.fad.fa-arrow-circle-up::after, .fa-duotone.fa-arrow-circle-up::after {content: "\f0aa\f0aa";}.fad.fa-circle-arrow-up-left::after, .fa-duotone.fa-circle-arrow-up-left::after {content: "\e0fb\e0fb";}.fad.fa-circle-arrow-up-right::after, .fa-duotone.fa-circle-arrow-up-right::after {content: "\e0fc\e0fc";}.fad.fa-circle-b::after, .fa-duotone.fa-circle-b::after {content: "\e0fd\e0fd";}.fad.fa-circle-bolt::after, .fa-duotone.fa-circle-bolt::after {content: "\e0fe\e0fe";}.fad.fa-circle-book-open::after, .fa-duotone.fa-circle-book-open::after {content: "\e0ff\e0ff";}.fad.fa-book-circle::after, .fa-duotone.fa-book-circle::after {content: "\e0ff\e0ff";}.fad.fa-circle-bookmark::after, .fa-duotone.fa-circle-bookmark::after {content: "\e100\e100";}.fad.fa-bookmark-circle::after, .fa-duotone.fa-bookmark-circle::after {content: "\e100\e100";}.fad.fa-circle-c::after, .fa-duotone.fa-circle-c::after {content: "\e101\e101";}.fad.fa-circle-calendar::after, .fa-duotone.fa-circle-calendar::after {content: "\e102\e102";}.fad.fa-calendar-circle::after, .fa-duotone.fa-calendar-circle::after {content: "\e102\e102";}.fad.fa-circle-camera::after, .fa-duotone.fa-circle-camera::after {content: "\e103\e103";}.fad.fa-camera-circle::after, .fa-duotone.fa-camera-circle::after {content: "\e103\e103";}.fad.fa-circle-caret-down::after, .fa-duotone.fa-circle-caret-down::after {content: "\f32d\f32d";}.fad.fa-caret-circle-down::after, .fa-duotone.fa-caret-circle-down::after {content: "\f32d\f32d";}.fad.fa-circle-caret-left::after, .fa-duotone.fa-circle-caret-left::after {content: "\f32e\f32e";}.fad.fa-caret-circle-left::after, .fa-duotone.fa-caret-circle-left::after {content: "\f32e\f32e";}.fad.fa-circle-caret-right::after, .fa-duotone.fa-circle-caret-right::after {content: "\f330\f330";}.fad.fa-caret-circle-right::after, .fa-duotone.fa-caret-circle-right::after {content: "\f330\f330";}.fad.fa-circle-caret-up::after, .fa-duotone.fa-circle-caret-up::after {content: "\f331\f331";}.fad.fa-caret-circle-up::after, .fa-duotone.fa-caret-circle-up::after {content: "\f331\f331";}.fad.fa-circle-check::after, .fa-duotone.fa-circle-check::after {content: "\f058\f058";}.fad.fa-check-circle::after, .fa-duotone.fa-check-circle::after {content: "\f058\f058";}.fad.fa-circle-chevron-down::after, .fa-duotone.fa-circle-chevron-down::after {content: "\f13a\f13a";}.fad.fa-chevron-circle-down::after, .fa-duotone.fa-chevron-circle-down::after {content: "\f13a\f13a";}.fad.fa-circle-chevron-left::after, .fa-duotone.fa-circle-chevron-left::after {content: "\f137\f137";}.fad.fa-chevron-circle-left::after, .fa-duotone.fa-chevron-circle-left::after {content: "\f137\f137";}.fad.fa-circle-chevron-right::after, .fa-duotone.fa-circle-chevron-right::after {content: "\f138\f138";}.fad.fa-chevron-circle-right::after, .fa-duotone.fa-chevron-circle-right::after {content: "\f138\f138";}.fad.fa-circle-chevron-up::after, .fa-duotone.fa-circle-chevron-up::after {content: "\f139\f139";}.fad.fa-chevron-circle-up::after, .fa-duotone.fa-chevron-circle-up::after {content: "\f139\f139";}.fad.fa-circle-d::after, .fa-duotone.fa-circle-d::after {content: "\e104\e104";}.fad.fa-circle-dashed::after, .fa-duotone.fa-circle-dashed::after {content: "\e105\e105";}.fad.fa-circle-divide::after, .fa-duotone.fa-circle-divide::after {content: "\e106\e106";}.fad.fa-circle-dollar::after, .fa-duotone.fa-circle-dollar::after {content: "\f2e8\f2e8";}.fad.fa-dollar-circle::after, .fa-duotone.fa-dollar-circle::after {content: "\f2e8\f2e8";}.fad.fa-usd-circle::after, .fa-duotone.fa-usd-circle::after {content: "\f2e8\f2e8";}.fad.fa-circle-dollar-to-slot::after, .fa-duotone.fa-circle-dollar-to-slot::after {content: "\f4b9\f4b9";}.fad.fa-donate::after, .fa-duotone.fa-donate::after {content: "\f4b9\f4b9";}.fad.fa-circle-dot::after, .fa-duotone.fa-circle-dot::after {content: "\f192\f192";}.fad.fa-dot-circle::after, .fa-duotone.fa-dot-circle::after {content: "\f192\f192";}.fad.fa-circle-down::after, .fa-duotone.fa-circle-down::after {content: "\f358\f358";}.fad.fa-arrow-alt-circle-down::after, .fa-duotone.fa-arrow-alt-circle-down::after {content: "\f358\f358";}.fad.fa-circle-down-left::after, .fa-duotone.fa-circle-down-left::after {content: "\e107\e107";}.fad.fa-circle-down-right::after, .fa-duotone.fa-circle-down-right::after {content: "\e108\e108";}.fad.fa-circle-e::after, .fa-duotone.fa-circle-e::after {content: "\e109\e109";}.fad.fa-circle-ellipsis::after, .fa-duotone.fa-circle-ellipsis::after {content: "\e10a\e10a";}.fad.fa-circle-ellipsis-vertical::after, .fa-duotone.fa-circle-ellipsis-vertical::after {content: "\e10b\e10b";}.fad.fa-circle-envelope::after, .fa-duotone.fa-circle-envelope::after {content: "\e10c\e10c";}.fad.fa-envelope-circle::after, .fa-duotone.fa-envelope-circle::after {content: "\e10c\e10c";}.fad.fa-circle-exclamation::after, .fa-duotone.fa-circle-exclamation::after {content: "\f06a\f06a";}.fad.fa-exclamation-circle::after, .fa-duotone.fa-exclamation-circle::after {content: "\f06a\f06a";}.fad.fa-circle-exclamation-check::after, .fa-duotone.fa-circle-exclamation-check::after {content: "\e10d\e10d";}.fad.fa-circle-f::after, .fa-duotone.fa-circle-f::after {content: "\e10e\e10e";}.fad.fa-circle-g::after, .fa-duotone.fa-circle-g::after {content: "\e10f\e10f";}.fad.fa-circle-h::after, .fa-duotone.fa-circle-h::after {content: "\f47e\f47e";}.fad.fa-hospital-symbol::after, .fa-duotone.fa-hospital-symbol::after {content: "\f47e\f47e";}.fad.fa-circle-half::after, .fa-duotone.fa-circle-half::after {content: "\e110\e110";}.fad.fa-circle-half-stroke::after, .fa-duotone.fa-circle-half-stroke::after {content: "\f042\f042";}.fad.fa-adjust::after, .fa-duotone.fa-adjust::after {content: "\f042\f042";}.fad.fa-circle-heart::after, .fa-duotone.fa-circle-heart::after {content: "\f4c7\f4c7";}.fad.fa-heart-circle::after, .fa-duotone.fa-heart-circle::after {content: "\f4c7\f4c7";}.fad.fa-circle-i::after, .fa-duotone.fa-circle-i::after {content: "\e111\e111";}.fad.fa-circle-info::after, .fa-duotone.fa-circle-info::after {content: "\f05a\f05a";}.fad.fa-info-circle::after, .fa-duotone.fa-info-circle::after {content: "\f05a\f05a";}.fad.fa-circle-j::after, .fa-duotone.fa-circle-j::after {content: "\e112\e112";}.fad.fa-circle-k::after, .fa-duotone.fa-circle-k::after {content: "\e113\e113";}.fad.fa-circle-l::after, .fa-duotone.fa-circle-l::after {content: "\e114\e114";}.fad.fa-circle-left::after, .fa-duotone.fa-circle-left::after {content: "\f359\f359";}.fad.fa-arrow-alt-circle-left::after, .fa-duotone.fa-arrow-alt-circle-left::after {content: "\f359\f359";}.fad.fa-circle-location-arrow::after, .fa-duotone.fa-circle-location-arrow::after {content: "\f602\f602";}.fad.fa-location-circle::after, .fa-duotone.fa-location-circle::after {content: "\f602\f602";}.fad.fa-circle-m::after, .fa-duotone.fa-circle-m::after {content: "\e115\e115";}.fad.fa-circle-microphone::after, .fa-duotone.fa-circle-microphone::after {content: "\e116\e116";}.fad.fa-microphone-circle::after, .fa-duotone.fa-microphone-circle::after {content: "\e116\e116";}.fad.fa-circle-microphone-lines::after, .fa-duotone.fa-circle-microphone-lines::after {content: "\e117\e117";}.fad.fa-microphone-circle-alt::after, .fa-duotone.fa-microphone-circle-alt::after {content: "\e117\e117";}.fad.fa-circle-minus::after, .fa-duotone.fa-circle-minus::after {content: "\f056\f056";}.fad.fa-minus-circle::after, .fa-duotone.fa-minus-circle::after {content: "\f056\f056";}.fad.fa-circle-n::after, .fa-duotone.fa-circle-n::after {content: "\e118\e118";}.fad.fa-circle-nodes::after, .fa-duotone.fa-circle-nodes::after {content: "\e4e2\e4e2";}.fad.fa-circle-notch::after, .fa-duotone.fa-circle-notch::after {content: "\f1ce\f1ce";}.fad.fa-circle-o::after, .fa-duotone.fa-circle-o::after {content: "\e119\e119";}.fad.fa-circle-p::after, .fa-duotone.fa-circle-p::after {content: "\e11a\e11a";}.fad.fa-circle-parking::after, .fa-duotone.fa-circle-parking::after {content: "\f615\f615";}.fad.fa-parking-circle::after, .fa-duotone.fa-parking-circle::after {content: "\f615\f615";}.fad.fa-circle-pause::after, .fa-duotone.fa-circle-pause::after {content: "\f28b\f28b";}.fad.fa-pause-circle::after, .fa-duotone.fa-pause-circle::after {content: "\f28b\f28b";}.fad.fa-circle-phone::after, .fa-duotone.fa-circle-phone::after {content: "\e11b\e11b";}.fad.fa-phone-circle::after, .fa-duotone.fa-phone-circle::after {content: "\e11b\e11b";}.fad.fa-circle-phone-flip::after, .fa-duotone.fa-circle-phone-flip::after {content: "\e11c\e11c";}.fad.fa-phone-circle-alt::after, .fa-duotone.fa-phone-circle-alt::after {content: "\e11c\e11c";}.fad.fa-circle-phone-hangup::after, .fa-duotone.fa-circle-phone-hangup::after {content: "\e11d\e11d";}.fad.fa-phone-circle-down::after, .fa-duotone.fa-phone-circle-down::after {content: "\e11d\e11d";}.fad.fa-circle-play::after, .fa-duotone.fa-circle-play::after {content: "\f144\f144";}.fad.fa-play-circle::after, .fa-duotone.fa-play-circle::after {content: "\f144\f144";}.fad.fa-circle-plus::after, .fa-duotone.fa-circle-plus::after {content: "\f055\f055";}.fad.fa-plus-circle::after, .fa-duotone.fa-plus-circle::after {content: "\f055\f055";}.fad.fa-circle-q::after, .fa-duotone.fa-circle-q::after {content: "\e11e\e11e";}.fad.fa-circle-quarter::after, .fa-duotone.fa-circle-quarter::after {content: "\e11f\e11f";}.fad.fa-circle-quarters::after, .fa-duotone.fa-circle-quarters::after {content: "\e3f8\e3f8";}.fad.fa-circle-question::after, .fa-duotone.fa-circle-question::after {content: "\f059\f059";}.fad.fa-question-circle::after, .fa-duotone.fa-question-circle::after {content: "\f059\f059";}.fad.fa-circle-r::after, .fa-duotone.fa-circle-r::after {content: "\e120\e120";}.fad.fa-circle-radiation::after, .fa-duotone.fa-circle-radiation::after {content: "\f7ba\f7ba";}.fad.fa-radiation-alt::after, .fa-duotone.fa-radiation-alt::after {content: "\f7ba\f7ba";}.fad.fa-circle-right::after, .fa-duotone.fa-circle-right::after {content: "\f35a\f35a";}.fad.fa-arrow-alt-circle-right::after, .fa-duotone.fa-arrow-alt-circle-right::after {content: "\f35a\f35a";}.fad.fa-circle-s::after, .fa-duotone.fa-circle-s::after {content: "\e121\e121";}.fad.fa-circle-small::after, .fa-duotone.fa-circle-small::after {content: "\e122\e122";}.fad.fa-circle-sort::after, .fa-duotone.fa-circle-sort::after {content: "\e030\e030";}.fad.fa-sort-circle::after, .fa-duotone.fa-sort-circle::after {content: "\e030\e030";}.fad.fa-circle-sort-down::after, .fa-duotone.fa-circle-sort-down::after {content: "\e031\e031";}.fad.fa-sort-circle-down::after, .fa-duotone.fa-sort-circle-down::after {content: "\e031\e031";}.fad.fa-circle-sort-up::after, .fa-duotone.fa-circle-sort-up::after {content: "\e032\e032";}.fad.fa-sort-circle-up::after, .fa-duotone.fa-sort-circle-up::after {content: "\e032\e032";}.fad.fa-circle-star::after, .fa-duotone.fa-circle-star::after {content: "\e123\e123";}.fad.fa-star-circle::after, .fa-duotone.fa-star-circle::after {content: "\e123\e123";}.fad.fa-circle-stop::after, .fa-duotone.fa-circle-stop::after {content: "\f28d\f28d";}.fad.fa-stop-circle::after, .fa-duotone.fa-stop-circle::after {content: "\f28d\f28d";}.fad.fa-circle-t::after, .fa-duotone.fa-circle-t::after {content: "\e124\e124";}.fad.fa-circle-three-quarters::after, .fa-duotone.fa-circle-three-quarters::after {content: "\e125\e125";}.fad.fa-circle-trash::after, .fa-duotone.fa-circle-trash::after {content: "\e126\e126";}.fad.fa-trash-circle::after, .fa-duotone.fa-trash-circle::after {content: "\e126\e126";}.fad.fa-circle-u::after, .fa-duotone.fa-circle-u::after {content: "\e127\e127";}.fad.fa-circle-up::after, .fa-duotone.fa-circle-up::after {content: "\f35b\f35b";}.fad.fa-arrow-alt-circle-up::after, .fa-duotone.fa-arrow-alt-circle-up::after {content: "\f35b\f35b";}.fad.fa-circle-up-left::after, .fa-duotone.fa-circle-up-left::after {content: "\e128\e128";}.fad.fa-circle-up-right::after, .fa-duotone.fa-circle-up-right::after {content: "\e129\e129";}.fad.fa-circle-user::after, .fa-duotone.fa-circle-user::after {content: "\f2bd\f2bd";}.fad.fa-user-circle::after, .fa-duotone.fa-user-circle::after {content: "\f2bd\f2bd";}.fad.fa-circle-v::after, .fa-duotone.fa-circle-v::after {content: "\e12a\e12a";}.fad.fa-circle-video::after, .fa-duotone.fa-circle-video::after {content: "\e12b\e12b";}.fad.fa-video-circle::after, .fa-duotone.fa-video-circle::after {content: "\e12b\e12b";}.fad.fa-circle-w::after, .fa-duotone.fa-circle-w::after {content: "\e12c\e12c";}.fad.fa-circle-waveform-lines::after, .fa-duotone.fa-circle-waveform-lines::after {content: "\e12d\e12d";}.fad.fa-waveform-circle::after, .fa-duotone.fa-waveform-circle::after {content: "\e12d\e12d";}.fad.fa-circle-x::after, .fa-duotone.fa-circle-x::after {content: "\e12e\e12e";}.fad.fa-circle-xmark::after, .fa-duotone.fa-circle-xmark::after {content: "\f057\f057";}.fad.fa-times-circle::after, .fa-duotone.fa-times-circle::after {content: "\f057\f057";}.fad.fa-xmark-circle::after, .fa-duotone.fa-xmark-circle::after {content: "\f057\f057";}.fad.fa-circle-y::after, .fa-duotone.fa-circle-y::after {content: "\e12f\e12f";}.fad.fa-circle-z::after, .fa-duotone.fa-circle-z::after {content: "\e130\e130";}.fad.fa-citrus::after, .fa-duotone.fa-citrus::after {content: "\e2f4\e2f4";}.fad.fa-citrus-slice::after, .fa-duotone.fa-citrus-slice::after {content: "\e2f5\e2f5";}.fad.fa-city::after, .fa-duotone.fa-city::after {content: "\f64f\f64f";}.fad.fa-clapperboard::after, .fa-duotone.fa-clapperboard::after {content: "\e131\e131";}.fad.fa-clapperboard-play::after, .fa-duotone.fa-clapperboard-play::after {content: "\e132\e132";}.fad.fa-clarinet::after, .fa-duotone.fa-clarinet::after {content: "\f8ad\f8ad";}.fad.fa-claw-marks::after, .fa-duotone.fa-claw-marks::after {content: "\f6c2\f6c2";}.fad.fa-clipboard::after, .fa-duotone.fa-clipboard::after {content: "\f328\f328";}.fad.fa-clipboard-check::after, .fa-duotone.fa-clipboard-check::after {content: "\f46c\f46c";}.fad.fa-clipboard-list::after, .fa-duotone.fa-clipboard-list::after {content: "\f46d\f46d";}.fad.fa-clipboard-list-check::after, .fa-duotone.fa-clipboard-list-check::after {content: "\f737\f737";}.fad.fa-clipboard-medical::after, .fa-duotone.fa-clipboard-medical::after {content: "\e133\e133";}.fad.fa-clipboard-prescription::after, .fa-duotone.fa-clipboard-prescription::after {content: "\f5e8\f5e8";}.fad.fa-clipboard-question::after, .fa-duotone.fa-clipboard-question::after {content: "\e4e3\e4e3";}.fad.fa-clipboard-user::after, .fa-duotone.fa-clipboard-user::after {content: "\f7f3\f7f3";}.fad.fa-clock::after, .fa-duotone.fa-clock::after {content: "\f017\f017";}.fad.fa-clock-four::after, .fa-duotone.fa-clock-four::after {content: "\f017\f017";}.fad.fa-clock-desk::after, .fa-duotone.fa-clock-desk::after {content: "\e134\e134";}.fad.fa-clock-eight::after, .fa-duotone.fa-clock-eight::after {content: "\e345\e345";}.fad.fa-clock-eight-thirty::after, .fa-duotone.fa-clock-eight-thirty::after {content: "\e346\e346";}.fad.fa-clock-eleven::after, .fa-duotone.fa-clock-eleven::after {content: "\e347\e347";}.fad.fa-clock-eleven-thirty::after, .fa-duotone.fa-clock-eleven-thirty::after {content: "\e348\e348";}.fad.fa-clock-five::after, .fa-duotone.fa-clock-five::after {content: "\e349\e349";}.fad.fa-clock-five-thirty::after, .fa-duotone.fa-clock-five-thirty::after {content: "\e34a\e34a";}.fad.fa-clock-four-thirty::after, .fa-duotone.fa-clock-four-thirty::after {content: "\e34b\e34b";}.fad.fa-clock-nine::after, .fa-duotone.fa-clock-nine::after {content: "\e34c\e34c";}.fad.fa-clock-nine-thirty::after, .fa-duotone.fa-clock-nine-thirty::after {content: "\e34d\e34d";}.fad.fa-clock-one::after, .fa-duotone.fa-clock-one::after {content: "\e34e\e34e";}.fad.fa-clock-one-thirty::after, .fa-duotone.fa-clock-one-thirty::after {content: "\e34f\e34f";}.fad.fa-clock-rotate-left::after, .fa-duotone.fa-clock-rotate-left::after {content: "\f1da\f1da";}.fad.fa-history::after, .fa-duotone.fa-history::after {content: "\f1da\f1da";}.fad.fa-clock-seven::after, .fa-duotone.fa-clock-seven::after {content: "\e350\e350";}.fad.fa-clock-seven-thirty::after, .fa-duotone.fa-clock-seven-thirty::after {content: "\e351\e351";}.fad.fa-clock-six::after, .fa-duotone.fa-clock-six::after {content: "\e352\e352";}.fad.fa-clock-six-thirty::after, .fa-duotone.fa-clock-six-thirty::after {content: "\e353\e353";}.fad.fa-clock-ten::after, .fa-duotone.fa-clock-ten::after {content: "\e354\e354";}.fad.fa-clock-ten-thirty::after, .fa-duotone.fa-clock-ten-thirty::after {content: "\e355\e355";}.fad.fa-clock-three::after, .fa-duotone.fa-clock-three::after {content: "\e356\e356";}.fad.fa-clock-three-thirty::after, .fa-duotone.fa-clock-three-thirty::after {content: "\e357\e357";}.fad.fa-clock-twelve::after, .fa-duotone.fa-clock-twelve::after {content: "\e358\e358";}.fad.fa-clock-twelve-thirty::after, .fa-duotone.fa-clock-twelve-thirty::after {content: "\e359\e359";}.fad.fa-clock-two::after, .fa-duotone.fa-clock-two::after {content: "\e35a\e35a";}.fad.fa-clock-two-thirty::after, .fa-duotone.fa-clock-two-thirty::after {content: "\e35b\e35b";}.fad.fa-clone::after, .fa-duotone.fa-clone::after {content: "\f24d\f24d";}.fad.fa-closed-captioning::after, .fa-duotone.fa-closed-captioning::after {content: "\f20a\f20a";}.fad.fa-closed-captioning-slash::after, .fa-duotone.fa-closed-captioning-slash::after {content: "\e135\e135";}.fad.fa-clothes-hanger::after, .fa-duotone.fa-clothes-hanger::after {content: "\e136\e136";}.fad.fa-cloud::after, .fa-duotone.fa-cloud::after {content: "\f0c2\f0c2";}.fad.fa-cloud-arrow-down::after, .fa-duotone.fa-cloud-arrow-down::after {content: "\f0ed\f0ed";}.fad.fa-cloud-download::after, .fa-duotone.fa-cloud-download::after {content: "\f0ed\f0ed";}.fad.fa-cloud-download-alt::after, .fa-duotone.fa-cloud-download-alt::after {content: "\f0ed\f0ed";}.fad.fa-cloud-arrow-up::after, .fa-duotone.fa-cloud-arrow-up::after {content: "\f0ee\f0ee";}.fad.fa-cloud-upload::after, .fa-duotone.fa-cloud-upload::after {content: "\f0ee\f0ee";}.fad.fa-cloud-upload-alt::after, .fa-duotone.fa-cloud-upload-alt::after {content: "\f0ee\f0ee";}.fad.fa-cloud-bolt::after, .fa-duotone.fa-cloud-bolt::after {content: "\f76c\f76c";}.fad.fa-thunderstorm::after, .fa-duotone.fa-thunderstorm::after {content: "\f76c\f76c";}.fad.fa-cloud-bolt-moon::after, .fa-duotone.fa-cloud-bolt-moon::after {content: "\f76d\f76d";}.fad.fa-thunderstorm-moon::after, .fa-duotone.fa-thunderstorm-moon::after {content: "\f76d\f76d";}.fad.fa-cloud-bolt-sun::after, .fa-duotone.fa-cloud-bolt-sun::after {content: "\f76e\f76e";}.fad.fa-thunderstorm-sun::after, .fa-duotone.fa-thunderstorm-sun::after {content: "\f76e\f76e";}.fad.fa-cloud-check::after, .fa-duotone.fa-cloud-check::after {content: "\e35c\e35c";}.fad.fa-cloud-drizzle::after, .fa-duotone.fa-cloud-drizzle::after {content: "\f738\f738";}.fad.fa-cloud-exclamation::after, .fa-duotone.fa-cloud-exclamation::after {content: "\e491\e491";}.fad.fa-cloud-fog::after, .fa-duotone.fa-cloud-fog::after {content: "\f74e\f74e";}.fad.fa-fog::after, .fa-duotone.fa-fog::after {content: "\f74e\f74e";}.fad.fa-cloud-hail::after, .fa-duotone.fa-cloud-hail::after {content: "\f739\f739";}.fad.fa-cloud-hail-mixed::after, .fa-duotone.fa-cloud-hail-mixed::after {content: "\f73a\f73a";}.fad.fa-cloud-meatball::after, .fa-duotone.fa-cloud-meatball::after {content: "\f73b\f73b";}.fad.fa-cloud-minus::after, .fa-duotone.fa-cloud-minus::after {content: "\e35d\e35d";}.fad.fa-cloud-moon::after, .fa-duotone.fa-cloud-moon::after {content: "\f6c3\f6c3";}.fad.fa-cloud-moon-rain::after, .fa-duotone.fa-cloud-moon-rain::after {content: "\f73c\f73c";}.fad.fa-cloud-music::after, .fa-duotone.fa-cloud-music::after {content: "\f8ae\f8ae";}.fad.fa-cloud-plus::after, .fa-duotone.fa-cloud-plus::after {content: "\e35e\e35e";}.fad.fa-cloud-question::after, .fa-duotone.fa-cloud-question::after {content: "\e492\e492";}.fad.fa-cloud-rain::after, .fa-duotone.fa-cloud-rain::after {content: "\f73d\f73d";}.fad.fa-cloud-rainbow::after, .fa-duotone.fa-cloud-rainbow::after {content: "\f73e\f73e";}.fad.fa-cloud-showers::after, .fa-duotone.fa-cloud-showers::after {content: "\f73f\f73f";}.fad.fa-cloud-showers-heavy::after, .fa-duotone.fa-cloud-showers-heavy::after {content: "\f740\f740";}.fad.fa-cloud-showers-water::after, .fa-duotone.fa-cloud-showers-water::after {content: "\e4e4\e4e4";}.fad.fa-cloud-slash::after, .fa-duotone.fa-cloud-slash::after {content: "\e137\e137";}.fad.fa-cloud-sleet::after, .fa-duotone.fa-cloud-sleet::after {content: "\f741\f741";}.fad.fa-cloud-snow::after, .fa-duotone.fa-cloud-snow::after {content: "\f742\f742";}.fad.fa-cloud-sun::after, .fa-duotone.fa-cloud-sun::after {content: "\f6c4\f6c4";}.fad.fa-cloud-sun-rain::after, .fa-duotone.fa-cloud-sun-rain::after {content: "\f743\f743";}.fad.fa-cloud-word::after, .fa-duotone.fa-cloud-word::after {content: "\e138\e138";}.fad.fa-cloud-xmark::after, .fa-duotone.fa-cloud-xmark::after {content: "\e35f\e35f";}.fad.fa-clouds::after, .fa-duotone.fa-clouds::after {content: "\f744\f744";}.fad.fa-clouds-moon::after, .fa-duotone.fa-clouds-moon::after {content: "\f745\f745";}.fad.fa-clouds-sun::after, .fa-duotone.fa-clouds-sun::after {content: "\f746\f746";}.fad.fa-clover::after, .fa-duotone.fa-clover::after {content: "\e139\e139";}.fad.fa-club::after, .fa-duotone.fa-club::after {content: "\f327\f327";}.fad.fa-coconut::after, .fa-duotone.fa-coconut::after {content: "\e2f6\e2f6";}.fad.fa-code::after, .fa-duotone.fa-code::after {content: "\f121\f121";}.fad.fa-code-branch::after, .fa-duotone.fa-code-branch::after {content: "\f126\f126";}.fad.fa-code-commit::after, .fa-duotone.fa-code-commit::after {content: "\f386\f386";}.fad.fa-code-compare::after, .fa-duotone.fa-code-compare::after {content: "\e13a\e13a";}.fad.fa-code-fork::after, .fa-duotone.fa-code-fork::after {content: "\e13b\e13b";}.fad.fa-code-merge::after, .fa-duotone.fa-code-merge::after {content: "\f387\f387";}.fad.fa-code-pull-request::after, .fa-duotone.fa-code-pull-request::after {content: "\e13c\e13c";}.fad.fa-code-pull-request-closed::after, .fa-duotone.fa-code-pull-request-closed::after {content: "\e3f9\e3f9";}.fad.fa-code-pull-request-draft::after, .fa-duotone.fa-code-pull-request-draft::after {content: "\e3fa\e3fa";}.fad.fa-code-simple::after, .fa-duotone.fa-code-simple::after {content: "\e13d\e13d";}.fad.fa-coffee-bean::after, .fa-duotone.fa-coffee-bean::after {content: "\e13e\e13e";}.fad.fa-coffee-beans::after, .fa-duotone.fa-coffee-beans::after {content: "\e13f\e13f";}.fad.fa-coffee-pot::after, .fa-duotone.fa-coffee-pot::after {content: "\e002\e002";}.fad.fa-coffin::after, .fa-duotone.fa-coffin::after {content: "\f6c6\f6c6";}.fad.fa-coffin-cross::after, .fa-duotone.fa-coffin-cross::after {content: "\e051\e051";}.fad.fa-coin::after, .fa-duotone.fa-coin::after {content: "\f85c\f85c";}.fad.fa-coin-blank::after, .fa-duotone.fa-coin-blank::after {content: "\e3fb\e3fb";}.fad.fa-coin-front::after, .fa-duotone.fa-coin-front::after {content: "\e3fc\e3fc";}.fad.fa-coin-vertical::after, .fa-duotone.fa-coin-vertical::after {content: "\e3fd\e3fd";}.fad.fa-coins::after, .fa-duotone.fa-coins::after {content: "\f51e\f51e";}.fad.fa-colon::after, .fa-duotone.fa-colon::after {content: "\3a\3a";}.fad.fa-colon-sign::after, .fa-duotone.fa-colon-sign::after {content: "\e140\e140";}.fad.fa-columns-3::after, .fa-duotone.fa-columns-3::after {content: "\e361\e361";}.fad.fa-comet::after, .fa-duotone.fa-comet::after {content: "\e003\e003";}.fad.fa-comma::after, .fa-duotone.fa-comma::after {content: "\2c\2c";}.fad.fa-command::after, .fa-duotone.fa-command::after {content: "\e142\e142";}.fad.fa-comment::after, .fa-duotone.fa-comment::after {content: "\f075\f075";}.fad.fa-comment-arrow-down::after, .fa-duotone.fa-comment-arrow-down::after {content: "\e143\e143";}.fad.fa-comment-arrow-up::after, .fa-duotone.fa-comment-arrow-up::after {content: "\e144\e144";}.fad.fa-comment-arrow-up-right::after, .fa-duotone.fa-comment-arrow-up-right::after {content: "\e145\e145";}.fad.fa-comment-captions::after, .fa-duotone.fa-comment-captions::after {content: "\e146\e146";}.fad.fa-comment-check::after, .fa-duotone.fa-comment-check::after {content: "\f4ac\f4ac";}.fad.fa-comment-code::after, .fa-duotone.fa-comment-code::after {content: "\e147\e147";}.fad.fa-comment-dollar::after, .fa-duotone.fa-comment-dollar::after {content: "\f651\f651";}.fad.fa-comment-dots::after, .fa-duotone.fa-comment-dots::after {content: "\f4ad\f4ad";}.fad.fa-commenting::after, .fa-duotone.fa-commenting::after {content: "\f4ad\f4ad";}.fad.fa-comment-exclamation::after, .fa-duotone.fa-comment-exclamation::after {content: "\f4af\f4af";}.fad.fa-comment-image::after, .fa-duotone.fa-comment-image::after {content: "\e148\e148";}.fad.fa-comment-lines::after, .fa-duotone.fa-comment-lines::after {content: "\f4b0\f4b0";}.fad.fa-comment-medical::after, .fa-duotone.fa-comment-medical::after {content: "\f7f5\f7f5";}.fad.fa-comment-middle::after, .fa-duotone.fa-comment-middle::after {content: "\e149\e149";}.fad.fa-comment-middle-top::after, .fa-duotone.fa-comment-middle-top::after {content: "\e14a\e14a";}.fad.fa-comment-minus::after, .fa-duotone.fa-comment-minus::after {content: "\f4b1\f4b1";}.fad.fa-comment-music::after, .fa-duotone.fa-comment-music::after {content: "\f8b0\f8b0";}.fad.fa-comment-pen::after, .fa-duotone.fa-comment-pen::after {content: "\f4ae\f4ae";}.fad.fa-comment-edit::after, .fa-duotone.fa-comment-edit::after {content: "\f4ae\f4ae";}.fad.fa-comment-plus::after, .fa-duotone.fa-comment-plus::after {content: "\f4b2\f4b2";}.fad.fa-comment-question::after, .fa-duotone.fa-comment-question::after {content: "\e14b\e14b";}.fad.fa-comment-quote::after, .fa-duotone.fa-comment-quote::after {content: "\e14c\e14c";}.fad.fa-comment-slash::after, .fa-duotone.fa-comment-slash::after {content: "\f4b3\f4b3";}.fad.fa-comment-smile::after, .fa-duotone.fa-comment-smile::after {content: "\f4b4\f4b4";}.fad.fa-comment-sms::after, .fa-duotone.fa-comment-sms::after {content: "\f7cd\f7cd";}.fad.fa-sms::after, .fa-duotone.fa-sms::after {content: "\f7cd\f7cd";}.fad.fa-comment-text::after, .fa-duotone.fa-comment-text::after {content: "\e14d\e14d";}.fad.fa-comment-xmark::after, .fa-duotone.fa-comment-xmark::after {content: "\f4b5\f4b5";}.fad.fa-comment-times::after, .fa-duotone.fa-comment-times::after {content: "\f4b5\f4b5";}.fad.fa-comments::after, .fa-duotone.fa-comments::after {content: "\f086\f086";}.fad.fa-comments-dollar::after, .fa-duotone.fa-comments-dollar::after {content: "\f653\f653";}.fad.fa-comments-question::after, .fa-duotone.fa-comments-question::after {content: "\e14e\e14e";}.fad.fa-comments-question-check::after, .fa-duotone.fa-comments-question-check::after {content: "\e14f\e14f";}.fad.fa-compact-disc::after, .fa-duotone.fa-compact-disc::after {content: "\f51f\f51f";}.fad.fa-compass::after, .fa-duotone.fa-compass::after {content: "\f14e\f14e";}.fad.fa-compass-drafting::after, .fa-duotone.fa-compass-drafting::after {content: "\f568\f568";}.fad.fa-drafting-compass::after, .fa-duotone.fa-drafting-compass::after {content: "\f568\f568";}.fad.fa-compass-slash::after, .fa-duotone.fa-compass-slash::after {content: "\f5e9\f5e9";}.fad.fa-compress::after, .fa-duotone.fa-compress::after {content: "\f066\f066";}.fad.fa-compress-wide::after, .fa-duotone.fa-compress-wide::after {content: "\f326\f326";}.fad.fa-computer::after, .fa-duotone.fa-computer::after {content: "\e4e5\e4e5";}.fad.fa-computer-classic::after, .fa-duotone.fa-computer-classic::after {content: "\f8b1\f8b1";}.fad.fa-computer-mouse::after, .fa-duotone.fa-computer-mouse::after {content: "\f8cc\f8cc";}.fad.fa-mouse::after, .fa-duotone.fa-mouse::after {content: "\f8cc\f8cc";}.fad.fa-computer-mouse-scrollwheel::after, .fa-duotone.fa-computer-mouse-scrollwheel::after {content: "\f8cd\f8cd";}.fad.fa-mouse-alt::after, .fa-duotone.fa-mouse-alt::after {content: "\f8cd\f8cd";}.fad.fa-computer-speaker::after, .fa-duotone.fa-computer-speaker::after {content: "\f8b2\f8b2";}.fad.fa-container-storage::after, .fa-duotone.fa-container-storage::after {content: "\f4b7\f4b7";}.fad.fa-conveyor-belt::after, .fa-duotone.fa-conveyor-belt::after {content: "\f46e\f46e";}.fad.fa-conveyor-belt-boxes::after, .fa-duotone.fa-conveyor-belt-boxes::after {content: "\f46f\f46f";}.fad.fa-conveyor-belt-alt::after, .fa-duotone.fa-conveyor-belt-alt::after {content: "\f46f\f46f";}.fad.fa-conveyor-belt-empty::after, .fa-duotone.fa-conveyor-belt-empty::after {content: "\e150\e150";}.fad.fa-cookie::after, .fa-duotone.fa-cookie::after {content: "\f563\f563";}.fad.fa-cookie-bite::after, .fa-duotone.fa-cookie-bite::after {content: "\f564\f564";}.fad.fa-copy::after, .fa-duotone.fa-copy::after {content: "\f0c5\f0c5";}.fad.fa-copyright::after, .fa-duotone.fa-copyright::after {content: "\f1f9\f1f9";}.fad.fa-corn::after, .fa-duotone.fa-corn::after {content: "\f6c7\f6c7";}.fad.fa-corner::after, .fa-duotone.fa-corner::after {content: "\e3fe\e3fe";}.fad.fa-couch::after, .fa-duotone.fa-couch::after {content: "\f4b8\f4b8";}.fad.fa-cow::after, .fa-duotone.fa-cow::after {content: "\f6c8\f6c8";}.fad.fa-cowbell::after, .fa-duotone.fa-cowbell::after {content: "\f8b3\f8b3";}.fad.fa-cowbell-circle-plus::after, .fa-duotone.fa-cowbell-circle-plus::after {content: "\f8b4\f8b4";}.fad.fa-cowbell-more::after, .fa-duotone.fa-cowbell-more::after {content: "\f8b4\f8b4";}.fad.fa-crab::after, .fa-duotone.fa-crab::after {content: "\e3ff\e3ff";}.fad.fa-crate-apple::after, .fa-duotone.fa-crate-apple::after {content: "\f6b1\f6b1";}.fad.fa-apple-crate::after, .fa-duotone.fa-apple-crate::after {content: "\f6b1\f6b1";}.fad.fa-crate-empty::after, .fa-duotone.fa-crate-empty::after {content: "\e151\e151";}.fad.fa-credit-card::after, .fa-duotone.fa-credit-card::after {content: "\f09d\f09d";}.fad.fa-credit-card-alt::after, .fa-duotone.fa-credit-card-alt::after {content: "\f09d\f09d";}.fad.fa-credit-card-blank::after, .fa-duotone.fa-credit-card-blank::after {content: "\f389\f389";}.fad.fa-credit-card-front::after, .fa-duotone.fa-credit-card-front::after {content: "\f38a\f38a";}.fad.fa-cricket-bat-ball::after, .fa-duotone.fa-cricket-bat-ball::after {content: "\f449\f449";}.fad.fa-cricket::after, .fa-duotone.fa-cricket::after {content: "\f449\f449";}.fad.fa-croissant::after, .fa-duotone.fa-croissant::after {content: "\f7f6\f7f6";}.fad.fa-crop::after, .fa-duotone.fa-crop::after {content: "\f125\f125";}.fad.fa-crop-simple::after, .fa-duotone.fa-crop-simple::after {content: "\f565\f565";}.fad.fa-crop-alt::after, .fa-duotone.fa-crop-alt::after {content: "\f565\f565";}.fad.fa-cross::after, .fa-duotone.fa-cross::after {content: "\f654\f654";}.fad.fa-crosshairs::after, .fa-duotone.fa-crosshairs::after {content: "\f05b\f05b";}.fad.fa-crow::after, .fa-duotone.fa-crow::after {content: "\f520\f520";}.fad.fa-crown::after, .fa-duotone.fa-crown::after {content: "\f521\f521";}.fad.fa-crutch::after, .fa-duotone.fa-crutch::after {content: "\f7f7\f7f7";}.fad.fa-crutches::after, .fa-duotone.fa-crutches::after {content: "\f7f8\f7f8";}.fad.fa-cruzeiro-sign::after, .fa-duotone.fa-cruzeiro-sign::after {content: "\e152\e152";}.fad.fa-crystal-ball::after, .fa-duotone.fa-crystal-ball::after {content: "\e362\e362";}.fad.fa-cube::after, .fa-duotone.fa-cube::after {content: "\f1b2\f1b2";}.fad.fa-cubes::after, .fa-duotone.fa-cubes::after {content: "\f1b3\f1b3";}.fad.fa-cubes-stacked::after, .fa-duotone.fa-cubes-stacked::after {content: "\e4e6\e4e6";}.fad.fa-cucumber::after, .fa-duotone.fa-cucumber::after {content: "\e401\e401";}.fad.fa-cup-straw::after, .fa-duotone.fa-cup-straw::after {content: "\e363\e363";}.fad.fa-cup-straw-swoosh::after, .fa-duotone.fa-cup-straw-swoosh::after {content: "\e364\e364";}.fad.fa-cup-togo::after, .fa-duotone.fa-cup-togo::after {content: "\f6c5\f6c5";}.fad.fa-coffee-togo::after, .fa-duotone.fa-coffee-togo::after {content: "\f6c5\f6c5";}.fad.fa-cupcake::after, .fa-duotone.fa-cupcake::after {content: "\e402\e402";}.fad.fa-curling-stone::after, .fa-duotone.fa-curling-stone::after {content: "\f44a\f44a";}.fad.fa-curling::after, .fa-duotone.fa-curling::after {content: "\f44a\f44a";}.fad.fa-custard::after, .fa-duotone.fa-custard::after {content: "\e403\e403";}.fad.fa-d::after, .fa-duotone.fa-d::after {content: "\44\44";}.fad.fa-dagger::after, .fa-duotone.fa-dagger::after {content: "\f6cb\f6cb";}.fad.fa-dash::after, .fa-duotone.fa-dash::after {content: "\e404\e404";}.fad.fa-minus-large::after, .fa-duotone.fa-minus-large::after {content: "\e404\e404";}.fad.fa-database::after, .fa-duotone.fa-database::after {content: "\f1c0\f1c0";}.fad.fa-deer::after, .fa-duotone.fa-deer::after {content: "\f78e\f78e";}.fad.fa-deer-rudolph::after, .fa-duotone.fa-deer-rudolph::after {content: "\f78f\f78f";}.fad.fa-delete-left::after, .fa-duotone.fa-delete-left::after {content: "\f55a\f55a";}.fad.fa-backspace::after, .fa-duotone.fa-backspace::after {content: "\f55a\f55a";}.fad.fa-delete-right::after, .fa-duotone.fa-delete-right::after {content: "\e154\e154";}.fad.fa-democrat::after, .fa-duotone.fa-democrat::after {content: "\f747\f747";}.fad.fa-desktop::after, .fa-duotone.fa-desktop::after {content: "\f390\f390";}.fad.fa-desktop-alt::after, .fa-duotone.fa-desktop-alt::after {content: "\f390\f390";}.fad.fa-desktop-arrow-down::after, .fa-duotone.fa-desktop-arrow-down::after {content: "\e155\e155";}.fad.fa-dharmachakra::after, .fa-duotone.fa-dharmachakra::after {content: "\f655\f655";}.fad.fa-diagram-cells::after, .fa-duotone.fa-diagram-cells::after {content: "\e475\e475";}.fad.fa-diagram-lean-canvas::after, .fa-duotone.fa-diagram-lean-canvas::after {content: "\e156\e156";}.fad.fa-diagram-nested::after, .fa-duotone.fa-diagram-nested::after {content: "\e157\e157";}.fad.fa-diagram-next::after, .fa-duotone.fa-diagram-next::after {content: "\e476\e476";}.fad.fa-diagram-predecessor::after, .fa-duotone.fa-diagram-predecessor::after {content: "\e477\e477";}.fad.fa-diagram-previous::after, .fa-duotone.fa-diagram-previous::after {content: "\e478\e478";}.fad.fa-diagram-project::after, .fa-duotone.fa-diagram-project::after {content: "\f542\f542";}.fad.fa-project-diagram::after, .fa-duotone.fa-project-diagram::after {content: "\f542\f542";}.fad.fa-diagram-sankey::after, .fa-duotone.fa-diagram-sankey::after {content: "\e158\e158";}.fad.fa-diagram-subtask::after, .fa-duotone.fa-diagram-subtask::after {content: "\e479\e479";}.fad.fa-diagram-successor::after, .fa-duotone.fa-diagram-successor::after {content: "\e47a\e47a";}.fad.fa-diagram-venn::after, .fa-duotone.fa-diagram-venn::after {content: "\e15a\e15a";}.fad.fa-dial::after, .fa-duotone.fa-dial::after {content: "\e15b\e15b";}.fad.fa-dial-med-high::after, .fa-duotone.fa-dial-med-high::after {content: "\e15b\e15b";}.fad.fa-dial-high::after, .fa-duotone.fa-dial-high::after {content: "\e15c\e15c";}.fad.fa-dial-low::after, .fa-duotone.fa-dial-low::after {content: "\e15d\e15d";}.fad.fa-dial-max::after, .fa-duotone.fa-dial-max::after {content: "\e15e\e15e";}.fad.fa-dial-med::after, .fa-duotone.fa-dial-med::after {content: "\e15f\e15f";}.fad.fa-dial-med-low::after, .fa-duotone.fa-dial-med-low::after {content: "\e160\e160";}.fad.fa-dial-min::after, .fa-duotone.fa-dial-min::after {content: "\e161\e161";}.fad.fa-dial-off::after, .fa-duotone.fa-dial-off::after {content: "\e162\e162";}.fad.fa-diamond::after, .fa-duotone.fa-diamond::after {content: "\f219\f219";}.fad.fa-diamond-exclamation::after, .fa-duotone.fa-diamond-exclamation::after {content: "\e405\e405";}.fad.fa-diamond-turn-right::after, .fa-duotone.fa-diamond-turn-right::after {content: "\f5eb\f5eb";}.fad.fa-directions::after, .fa-duotone.fa-directions::after {content: "\f5eb\f5eb";}.fad.fa-dice::after, .fa-duotone.fa-dice::after {content: "\f522\f522";}.fad.fa-dice-d10::after, .fa-duotone.fa-dice-d10::after {content: "\f6cd\f6cd";}.fad.fa-dice-d12::after, .fa-duotone.fa-dice-d12::after {content: "\f6ce\f6ce";}.fad.fa-dice-d20::after, .fa-duotone.fa-dice-d20::after {content: "\f6cf\f6cf";}.fad.fa-dice-d4::after, .fa-duotone.fa-dice-d4::after {content: "\f6d0\f6d0";}.fad.fa-dice-d6::after, .fa-duotone.fa-dice-d6::after {content: "\f6d1\f6d1";}.fad.fa-dice-d8::after, .fa-duotone.fa-dice-d8::after {content: "\f6d2\f6d2";}.fad.fa-dice-five::after, .fa-duotone.fa-dice-five::after {content: "\f523\f523";}.fad.fa-dice-four::after, .fa-duotone.fa-dice-four::after {content: "\f524\f524";}.fad.fa-dice-one::after, .fa-duotone.fa-dice-one::after {content: "\f525\f525";}.fad.fa-dice-six::after, .fa-duotone.fa-dice-six::after {content: "\f526\f526";}.fad.fa-dice-three::after, .fa-duotone.fa-dice-three::after {content: "\f527\f527";}.fad.fa-dice-two::after, .fa-duotone.fa-dice-two::after {content: "\f528\f528";}.fad.fa-diploma::after, .fa-duotone.fa-diploma::after {content: "\f5ea\f5ea";}.fad.fa-scroll-ribbon::after, .fa-duotone.fa-scroll-ribbon::after {content: "\f5ea\f5ea";}.fad.fa-disc-drive::after, .fa-duotone.fa-disc-drive::after {content: "\f8b5\f8b5";}.fad.fa-disease::after, .fa-duotone.fa-disease::after {content: "\f7fa\f7fa";}.fad.fa-display::after, .fa-duotone.fa-display::after {content: "\e163\e163";}.fad.fa-display-arrow-down::after, .fa-duotone.fa-display-arrow-down::after {content: "\e164\e164";}.fad.fa-display-code::after, .fa-duotone.fa-display-code::after {content: "\e165\e165";}.fad.fa-desktop-code::after, .fa-duotone.fa-desktop-code::after {content: "\e165\e165";}.fad.fa-display-medical::after, .fa-duotone.fa-display-medical::after {content: "\e166\e166";}.fad.fa-desktop-medical::after, .fa-duotone.fa-desktop-medical::after {content: "\e166\e166";}.fad.fa-display-slash::after, .fa-duotone.fa-display-slash::after {content: "\e2fa\e2fa";}.fad.fa-desktop-slash::after, .fa-duotone.fa-desktop-slash::after {content: "\e2fa\e2fa";}.fad.fa-distribute-spacing-horizontal::after, .fa-duotone.fa-distribute-spacing-horizontal::after {content: "\e365\e365";}.fad.fa-distribute-spacing-vertical::after, .fa-duotone.fa-distribute-spacing-vertical::after {content: "\e366\e366";}.fad.fa-ditto::after, .fa-duotone.fa-ditto::after {content: "\22\22";}.fad.fa-divide::after, .fa-duotone.fa-divide::after {content: "\f529\f529";}.fad.fa-dna::after, .fa-duotone.fa-dna::after {content: "\f471\f471";}.fad.fa-do-not-enter::after, .fa-duotone.fa-do-not-enter::after {content: "\f5ec\f5ec";}.fad.fa-dog::after, .fa-duotone.fa-dog::after {content: "\f6d3\f6d3";}.fad.fa-dog-leashed::after, .fa-duotone.fa-dog-leashed::after {content: "\f6d4\f6d4";}.fad.fa-dollar-sign::after, .fa-duotone.fa-dollar-sign::after {content: "\24\24";}.fad.fa-dollar::after, .fa-duotone.fa-dollar::after {content: "\24\24";}.fad.fa-usd::after, .fa-duotone.fa-usd::after {content: "\24\24";}.fad.fa-dolly::after, .fa-duotone.fa-dolly::after {content: "\f472\f472";}.fad.fa-dolly-box::after, .fa-duotone.fa-dolly-box::after {content: "\f472\f472";}.fad.fa-dolly-empty::after, .fa-duotone.fa-dolly-empty::after {content: "\f473\f473";}.fad.fa-dolphin::after, .fa-duotone.fa-dolphin::after {content: "\e168\e168";}.fad.fa-dong-sign::after, .fa-duotone.fa-dong-sign::after {content: "\e169\e169";}.fad.fa-donut::after, .fa-duotone.fa-donut::after {content: "\e406\e406";}.fad.fa-doughnut::after, .fa-duotone.fa-doughnut::after {content: "\e406\e406";}.fad.fa-door-closed::after, .fa-duotone.fa-door-closed::after {content: "\f52a\f52a";}.fad.fa-door-open::after, .fa-duotone.fa-door-open::after {content: "\f52b\f52b";}.fad.fa-dove::after, .fa-duotone.fa-dove::after {content: "\f4ba\f4ba";}.fad.fa-down::after, .fa-duotone.fa-down::after {content: "\f354\f354";}.fad.fa-arrow-alt-down::after, .fa-duotone.fa-arrow-alt-down::after {content: "\f354\f354";}.fad.fa-down-from-dotted-line::after, .fa-duotone.fa-down-from-dotted-line::after {content: "\e407\e407";}.fad.fa-down-from-line::after, .fa-duotone.fa-down-from-line::after {content: "\f349\f349";}.fad.fa-arrow-alt-from-top::after, .fa-duotone.fa-arrow-alt-from-top::after {content: "\f349\f349";}.fad.fa-down-left::after, .fa-duotone.fa-down-left::after {content: "\e16a\e16a";}.fad.fa-down-left-and-up-right-to-center::after, .fa-duotone.fa-down-left-and-up-right-to-center::after {content: "\f422\f422";}.fad.fa-compress-alt::after, .fa-duotone.fa-compress-alt::after {content: "\f422\f422";}.fad.fa-down-long::after, .fa-duotone.fa-down-long::after {content: "\f309\f309";}.fad.fa-long-arrow-alt-down::after, .fa-duotone.fa-long-arrow-alt-down::after {content: "\f309\f309";}.fad.fa-down-right::after, .fa-duotone.fa-down-right::after {content: "\e16b\e16b";}.fad.fa-down-to-bracket::after, .fa-duotone.fa-down-to-bracket::after {content: "\e4e7\e4e7";}.fad.fa-down-to-dotted-line::after, .fa-duotone.fa-down-to-dotted-line::after {content: "\e408\e408";}.fad.fa-down-to-line::after, .fa-duotone.fa-down-to-line::after {content: "\f34a\f34a";}.fad.fa-arrow-alt-to-bottom::after, .fa-duotone.fa-arrow-alt-to-bottom::after {content: "\f34a\f34a";}.fad.fa-download::after, .fa-duotone.fa-download::after {content: "\f019\f019";}.fad.fa-dragon::after, .fa-duotone.fa-dragon::after {content: "\f6d5\f6d5";}.fad.fa-draw-circle::after, .fa-duotone.fa-draw-circle::after {content: "\f5ed\f5ed";}.fad.fa-draw-polygon::after, .fa-duotone.fa-draw-polygon::after {content: "\f5ee\f5ee";}.fad.fa-draw-square::after, .fa-duotone.fa-draw-square::after {content: "\f5ef\f5ef";}.fad.fa-dreidel::after, .fa-duotone.fa-dreidel::after {content: "\f792\f792";}.fad.fa-drone::after, .fa-duotone.fa-drone::after {content: "\f85f\f85f";}.fad.fa-drone-front::after, .fa-duotone.fa-drone-front::after {content: "\f860\f860";}.fad.fa-drone-alt::after, .fa-duotone.fa-drone-alt::after {content: "\f860\f860";}.fad.fa-droplet::after, .fa-duotone.fa-droplet::after {content: "\f043\f043";}.fad.fa-tint::after, .fa-duotone.fa-tint::after {content: "\f043\f043";}.fad.fa-droplet-degree::after, .fa-duotone.fa-droplet-degree::after {content: "\f748\f748";}.fad.fa-dewpoint::after, .fa-duotone.fa-dewpoint::after {content: "\f748\f748";}.fad.fa-droplet-percent::after, .fa-duotone.fa-droplet-percent::after {content: "\f750\f750";}.fad.fa-humidity::after, .fa-duotone.fa-humidity::after {content: "\f750\f750";}.fad.fa-droplet-slash::after, .fa-duotone.fa-droplet-slash::after {content: "\f5c7\f5c7";}.fad.fa-tint-slash::after, .fa-duotone.fa-tint-slash::after {content: "\f5c7\f5c7";}.fad.fa-drum::after, .fa-duotone.fa-drum::after {content: "\f569\f569";}.fad.fa-drum-steelpan::after, .fa-duotone.fa-drum-steelpan::after {content: "\f56a\f56a";}.fad.fa-drumstick::after, .fa-duotone.fa-drumstick::after {content: "\f6d6\f6d6";}.fad.fa-drumstick-bite::after, .fa-duotone.fa-drumstick-bite::after {content: "\f6d7\f6d7";}.fad.fa-dryer::after, .fa-duotone.fa-dryer::after {content: "\f861\f861";}.fad.fa-dryer-heat::after, .fa-duotone.fa-dryer-heat::after {content: "\f862\f862";}.fad.fa-dryer-alt::after, .fa-duotone.fa-dryer-alt::after {content: "\f862\f862";}.fad.fa-duck::after, .fa-duotone.fa-duck::after {content: "\f6d8\f6d8";}.fad.fa-dumbbell::after, .fa-duotone.fa-dumbbell::after {content: "\f44b\f44b";}.fad.fa-dumpster::after, .fa-duotone.fa-dumpster::after {content: "\f793\f793";}.fad.fa-dumpster-fire::after, .fa-duotone.fa-dumpster-fire::after {content: "\f794\f794";}.fad.fa-dungeon::after, .fa-duotone.fa-dungeon::after {content: "\f6d9\f6d9";}.fad.fa-e::after, .fa-duotone.fa-e::after {content: "\45\45";}.fad.fa-ear::after, .fa-duotone.fa-ear::after {content: "\f5f0\f5f0";}.fad.fa-ear-deaf::after, .fa-duotone.fa-ear-deaf::after {content: "\f2a4\f2a4";}.fad.fa-deaf::after, .fa-duotone.fa-deaf::after {content: "\f2a4\f2a4";}.fad.fa-deafness::after, .fa-duotone.fa-deafness::after {content: "\f2a4\f2a4";}.fad.fa-hard-of-hearing::after, .fa-duotone.fa-hard-of-hearing::after {content: "\f2a4\f2a4";}.fad.fa-ear-listen::after, .fa-duotone.fa-ear-listen::after {content: "\f2a2\f2a2";}.fad.fa-assistive-listening-systems::after, .fa-duotone.fa-assistive-listening-systems::after {content: "\f2a2\f2a2";}.fad.fa-ear-muffs::after, .fa-duotone.fa-ear-muffs::after {content: "\f795\f795";}.fad.fa-earth-africa::after, .fa-duotone.fa-earth-africa::after {content: "\f57c\f57c";}.fad.fa-globe-africa::after, .fa-duotone.fa-globe-africa::after {content: "\f57c\f57c";}.fad.fa-earth-americas::after, .fa-duotone.fa-earth-americas::after {content: "\f57d\f57d";}.fad.fa-earth::after, .fa-duotone.fa-earth::after {content: "\f57d\f57d";}.fad.fa-earth-america::after, .fa-duotone.fa-earth-america::after {content: "\f57d\f57d";}.fad.fa-globe-americas::after, .fa-duotone.fa-globe-americas::after {content: "\f57d\f57d";}.fad.fa-earth-asia::after, .fa-duotone.fa-earth-asia::after {content: "\f57e\f57e";}.fad.fa-globe-asia::after, .fa-duotone.fa-globe-asia::after {content: "\f57e\f57e";}.fad.fa-earth-europe::after, .fa-duotone.fa-earth-europe::after {content: "\f7a2\f7a2";}.fad.fa-globe-europe::after, .fa-duotone.fa-globe-europe::after {content: "\f7a2\f7a2";}.fad.fa-earth-oceania::after, .fa-duotone.fa-earth-oceania::after {content: "\e47b\e47b";}.fad.fa-globe-oceania::after, .fa-duotone.fa-globe-oceania::after {content: "\e47b\e47b";}.fad.fa-eclipse::after, .fa-duotone.fa-eclipse::after {content: "\f749\f749";}.fad.fa-egg::after, .fa-duotone.fa-egg::after {content: "\f7fb\f7fb";}.fad.fa-egg-fried::after, .fa-duotone.fa-egg-fried::after {content: "\f7fc\f7fc";}.fad.fa-eggplant::after, .fa-duotone.fa-eggplant::after {content: "\e16c\e16c";}.fad.fa-eject::after, .fa-duotone.fa-eject::after {content: "\f052\f052";}.fad.fa-elephant::after, .fa-duotone.fa-elephant::after {content: "\f6da\f6da";}.fad.fa-elevator::after, .fa-duotone.fa-elevator::after {content: "\e16d\e16d";}.fad.fa-ellipsis::after, .fa-duotone.fa-ellipsis::after {content: "\f141\f141";}.fad.fa-ellipsis-h::after, .fa-duotone.fa-ellipsis-h::after {content: "\f141\f141";}.fad.fa-ellipsis-stroke::after, .fa-duotone.fa-ellipsis-stroke::after {content: "\f39b\f39b";}.fad.fa-ellipsis-h-alt::after, .fa-duotone.fa-ellipsis-h-alt::after {content: "\f39b\f39b";}.fad.fa-ellipsis-stroke-vertical::after, .fa-duotone.fa-ellipsis-stroke-vertical::after {content: "\f39c\f39c";}.fad.fa-ellipsis-v-alt::after, .fa-duotone.fa-ellipsis-v-alt::after {content: "\f39c\f39c";}.fad.fa-ellipsis-vertical::after, .fa-duotone.fa-ellipsis-vertical::after {content: "\f142\f142";}.fad.fa-ellipsis-v::after, .fa-duotone.fa-ellipsis-v::after {content: "\f142\f142";}.fad.fa-empty-set::after, .fa-duotone.fa-empty-set::after {content: "\f656\f656";}.fad.fa-engine::after, .fa-duotone.fa-engine::after {content: "\e16e\e16e";}.fad.fa-engine-warning::after, .fa-duotone.fa-engine-warning::after {content: "\f5f2\f5f2";}.fad.fa-engine-exclamation::after, .fa-duotone.fa-engine-exclamation::after {content: "\f5f2\f5f2";}.fad.fa-envelope::after, .fa-duotone.fa-envelope::after {content: "\f0e0\f0e0";}.fad.fa-envelope-circle-check::after, .fa-duotone.fa-envelope-circle-check::after {content: "\e4e8\e4e8";}.fad.fa-envelope-dot::after, .fa-duotone.fa-envelope-dot::after {content: "\e16f\e16f";}.fad.fa-envelope-badge::after, .fa-duotone.fa-envelope-badge::after {content: "\e16f\e16f";}.fad.fa-envelope-open::after, .fa-duotone.fa-envelope-open::after {content: "\f2b6\f2b6";}.fad.fa-envelope-open-dollar::after, .fa-duotone.fa-envelope-open-dollar::after {content: "\f657\f657";}.fad.fa-envelope-open-text::after, .fa-duotone.fa-envelope-open-text::after {content: "\f658\f658";}.fad.fa-envelopes::after, .fa-duotone.fa-envelopes::after {content: "\e170\e170";}.fad.fa-envelopes-bulk::after, .fa-duotone.fa-envelopes-bulk::after {content: "\f674\f674";}.fad.fa-mail-bulk::after, .fa-duotone.fa-mail-bulk::after {content: "\f674\f674";}.fad.fa-equals::after, .fa-duotone.fa-equals::after {content: "\3d\3d";}.fad.fa-eraser::after, .fa-duotone.fa-eraser::after {content: "\f12d\f12d";}.fad.fa-escalator::after, .fa-duotone.fa-escalator::after {content: "\e171\e171";}.fad.fa-ethernet::after, .fa-duotone.fa-ethernet::after {content: "\f796\f796";}.fad.fa-euro-sign::after, .fa-duotone.fa-euro-sign::after {content: "\f153\f153";}.fad.fa-eur::after, .fa-duotone.fa-eur::after {content: "\f153\f153";}.fad.fa-euro::after, .fa-duotone.fa-euro::after {content: "\f153\f153";}.fad.fa-exclamation::after, .fa-duotone.fa-exclamation::after {content: "\21\21";}.fad.fa-expand::after, .fa-duotone.fa-expand::after {content: "\f065\f065";}.fad.fa-expand-wide::after, .fa-duotone.fa-expand-wide::after {content: "\f320\f320";}.fad.fa-explosion::after, .fa-duotone.fa-explosion::after {content: "\e4e9\e4e9";}.fad.fa-eye::after, .fa-duotone.fa-eye::after {content: "\f06e\f06e";}.fad.fa-eye-dropper::after, .fa-duotone.fa-eye-dropper::after {content: "\f1fb\f1fb";}.fad.fa-eye-dropper-empty::after, .fa-duotone.fa-eye-dropper-empty::after {content: "\f1fb\f1fb";}.fad.fa-eyedropper::after, .fa-duotone.fa-eyedropper::after {content: "\f1fb\f1fb";}.fad.fa-eye-dropper-full::after, .fa-duotone.fa-eye-dropper-full::after {content: "\e172\e172";}.fad.fa-eye-dropper-half::after, .fa-duotone.fa-eye-dropper-half::after {content: "\e173\e173";}.fad.fa-eye-evil::after, .fa-duotone.fa-eye-evil::after {content: "\f6db\f6db";}.fad.fa-eye-low-vision::after, .fa-duotone.fa-eye-low-vision::after {content: "\f2a8\f2a8";}.fad.fa-low-vision::after, .fa-duotone.fa-low-vision::after {content: "\f2a8\f2a8";}.fad.fa-eye-slash::after, .fa-duotone.fa-eye-slash::after {content: "\f070\f070";}.fad.fa-eyes::after, .fa-duotone.fa-eyes::after {content: "\e367\e367";}.fad.fa-f::after, .fa-duotone.fa-f::after {content: "\46\46";}.fad.fa-face-angry::after, .fa-duotone.fa-face-angry::after {content: "\f556\f556";}.fad.fa-angry::after, .fa-duotone.fa-angry::after {content: "\f556\f556";}.fad.fa-face-angry-horns::after, .fa-duotone.fa-face-angry-horns::after {content: "\e368\e368";}.fad.fa-face-anguished::after, .fa-duotone.fa-face-anguished::after {content: "\e369\e369";}.fad.fa-face-anxious-sweat::after, .fa-duotone.fa-face-anxious-sweat::after {content: "\e36a\e36a";}.fad.fa-face-astonished::after, .fa-duotone.fa-face-astonished::after {content: "\e36b\e36b";}.fad.fa-face-awesome::after, .fa-duotone.fa-face-awesome::after {content: "\e409\e409";}.fad.fa-gave-dandy::after, .fa-duotone.fa-gave-dandy::after {content: "\e409\e409";}.fad.fa-face-beam-hand-over-mouth::after, .fa-duotone.fa-face-beam-hand-over-mouth::after {content: "\e47c\e47c";}.fad.fa-face-clouds::after, .fa-duotone.fa-face-clouds::after {content: "\e47d\e47d";}.fad.fa-face-confounded::after, .fa-duotone.fa-face-confounded::after {content: "\e36c\e36c";}.fad.fa-face-confused::after, .fa-duotone.fa-face-confused::after {content: "\e36d\e36d";}.fad.fa-face-cowboy-hat::after, .fa-duotone.fa-face-cowboy-hat::after {content: "\e36e\e36e";}.fad.fa-face-diagonal-mouth::after, .fa-duotone.fa-face-diagonal-mouth::after {content: "\e47e\e47e";}.fad.fa-face-disappointed::after, .fa-duotone.fa-face-disappointed::after {content: "\e36f\e36f";}.fad.fa-face-disguise::after, .fa-duotone.fa-face-disguise::after {content: "\e370\e370";}.fad.fa-face-dizzy::after, .fa-duotone.fa-face-dizzy::after {content: "\f567\f567";}.fad.fa-dizzy::after, .fa-duotone.fa-dizzy::after {content: "\f567\f567";}.fad.fa-face-dotted::after, .fa-duotone.fa-face-dotted::after {content: "\e47f\e47f";}.fad.fa-face-downcast-sweat::after, .fa-duotone.fa-face-downcast-sweat::after {content: "\e371\e371";}.fad.fa-face-drooling::after, .fa-duotone.fa-face-drooling::after {content: "\e372\e372";}.fad.fa-face-exhaling::after, .fa-duotone.fa-face-exhaling::after {content: "\e480\e480";}.fad.fa-face-explode::after, .fa-duotone.fa-face-explode::after {content: "\e2fe\e2fe";}.fad.fa-exploding-head::after, .fa-duotone.fa-exploding-head::after {content: "\e2fe\e2fe";}.fad.fa-face-expressionless::after, .fa-duotone.fa-face-expressionless::after {content: "\e373\e373";}.fad.fa-face-eyes-xmarks::after, .fa-duotone.fa-face-eyes-xmarks::after {content: "\e374\e374";}.fad.fa-face-fearful::after, .fa-duotone.fa-face-fearful::after {content: "\e375\e375";}.fad.fa-face-flushed::after, .fa-duotone.fa-face-flushed::after {content: "\f579\f579";}.fad.fa-flushed::after, .fa-duotone.fa-flushed::after {content: "\f579\f579";}.fad.fa-face-frown::after, .fa-duotone.fa-face-frown::after {content: "\f119\f119";}.fad.fa-frown::after, .fa-duotone.fa-frown::after {content: "\f119\f119";}.fad.fa-face-frown-open::after, .fa-duotone.fa-face-frown-open::after {content: "\f57a\f57a";}.fad.fa-frown-open::after, .fa-duotone.fa-frown-open::after {content: "\f57a\f57a";}.fad.fa-face-frown-slight::after, .fa-duotone.fa-face-frown-slight::after {content: "\e376\e376";}.fad.fa-face-glasses::after, .fa-duotone.fa-face-glasses::after {content: "\e377\e377";}.fad.fa-face-grimace::after, .fa-duotone.fa-face-grimace::after {content: "\f57f\f57f";}.fad.fa-grimace::after, .fa-duotone.fa-grimace::after {content: "\f57f\f57f";}.fad.fa-face-grin::after, .fa-duotone.fa-face-grin::after {content: "\f580\f580";}.fad.fa-grin::after, .fa-duotone.fa-grin::after {content: "\f580\f580";}.fad.fa-face-grin-beam::after, .fa-duotone.fa-face-grin-beam::after {content: "\f582\f582";}.fad.fa-grin-beam::after, .fa-duotone.fa-grin-beam::after {content: "\f582\f582";}.fad.fa-face-grin-beam-sweat::after, .fa-duotone.fa-face-grin-beam-sweat::after {content: "\f583\f583";}.fad.fa-grin-beam-sweat::after, .fa-duotone.fa-grin-beam-sweat::after {content: "\f583\f583";}.fad.fa-face-grin-hearts::after, .fa-duotone.fa-face-grin-hearts::after {content: "\f584\f584";}.fad.fa-grin-hearts::after, .fa-duotone.fa-grin-hearts::after {content: "\f584\f584";}.fad.fa-face-grin-squint::after, .fa-duotone.fa-face-grin-squint::after {content: "\f585\f585";}.fad.fa-grin-squint::after, .fa-duotone.fa-grin-squint::after {content: "\f585\f585";}.fad.fa-face-grin-squint-tears::after, .fa-duotone.fa-face-grin-squint-tears::after {content: "\f586\f586";}.fad.fa-grin-squint-tears::after, .fa-duotone.fa-grin-squint-tears::after {content: "\f586\f586";}.fad.fa-face-grin-stars::after, .fa-duotone.fa-face-grin-stars::after {content: "\f587\f587";}.fad.fa-grin-stars::after, .fa-duotone.fa-grin-stars::after {content: "\f587\f587";}.fad.fa-face-grin-tears::after, .fa-duotone.fa-face-grin-tears::after {content: "\f588\f588";}.fad.fa-grin-tears::after, .fa-duotone.fa-grin-tears::after {content: "\f588\f588";}.fad.fa-face-grin-tongue::after, .fa-duotone.fa-face-grin-tongue::after {content: "\f589\f589";}.fad.fa-grin-tongue::after, .fa-duotone.fa-grin-tongue::after {content: "\f589\f589";}.fad.fa-face-grin-tongue-squint::after, .fa-duotone.fa-face-grin-tongue-squint::after {content: "\f58a\f58a";}.fad.fa-grin-tongue-squint::after, .fa-duotone.fa-grin-tongue-squint::after {content: "\f58a\f58a";}.fad.fa-face-grin-tongue-wink::after, .fa-duotone.fa-face-grin-tongue-wink::after {content: "\f58b\f58b";}.fad.fa-grin-tongue-wink::after, .fa-duotone.fa-grin-tongue-wink::after {content: "\f58b\f58b";}.fad.fa-face-grin-wide::after, .fa-duotone.fa-face-grin-wide::after {content: "\f581\f581";}.fad.fa-grin-alt::after, .fa-duotone.fa-grin-alt::after {content: "\f581\f581";}.fad.fa-face-grin-wink::after, .fa-duotone.fa-face-grin-wink::after {content: "\f58c\f58c";}.fad.fa-grin-wink::after, .fa-duotone.fa-grin-wink::after {content: "\f58c\f58c";}.fad.fa-face-hand-over-mouth::after, .fa-duotone.fa-face-hand-over-mouth::after {content: "\e378\e378";}.fad.fa-face-hand-peeking::after, .fa-duotone.fa-face-hand-peeking::after {content: "\e481\e481";}.fad.fa-face-hand-yawn::after, .fa-duotone.fa-face-hand-yawn::after {content: "\e379\e379";}.fad.fa-face-head-bandage::after, .fa-duotone.fa-face-head-bandage::after {content: "\e37a\e37a";}.fad.fa-face-holding-back-tears::after, .fa-duotone.fa-face-holding-back-tears::after {content: "\e482\e482";}.fad.fa-face-hushed::after, .fa-duotone.fa-face-hushed::after {content: "\e37b\e37b";}.fad.fa-face-icicles::after, .fa-duotone.fa-face-icicles::after {content: "\e37c\e37c";}.fad.fa-face-kiss::after, .fa-duotone.fa-face-kiss::after {content: "\f596\f596";}.fad.fa-kiss::after, .fa-duotone.fa-kiss::after {content: "\f596\f596";}.fad.fa-face-kiss-beam::after, .fa-duotone.fa-face-kiss-beam::after {content: "\f597\f597";}.fad.fa-kiss-beam::after, .fa-duotone.fa-kiss-beam::after {content: "\f597\f597";}.fad.fa-face-kiss-closed-eyes::after, .fa-duotone.fa-face-kiss-closed-eyes::after {content: "\e37d\e37d";}.fad.fa-face-kiss-wink-heart::after, .fa-duotone.fa-face-kiss-wink-heart::after {content: "\f598\f598";}.fad.fa-kiss-wink-heart::after, .fa-duotone.fa-kiss-wink-heart::after {content: "\f598\f598";}.fad.fa-face-laugh::after, .fa-duotone.fa-face-laugh::after {content: "\f599\f599";}.fad.fa-laugh::after, .fa-duotone.fa-laugh::after {content: "\f599\f599";}.fad.fa-face-laugh-beam::after, .fa-duotone.fa-face-laugh-beam::after {content: "\f59a\f59a";}.fad.fa-laugh-beam::after, .fa-duotone.fa-laugh-beam::after {content: "\f59a\f59a";}.fad.fa-face-laugh-squint::after, .fa-duotone.fa-face-laugh-squint::after {content: "\f59b\f59b";}.fad.fa-laugh-squint::after, .fa-duotone.fa-laugh-squint::after {content: "\f59b\f59b";}.fad.fa-face-laugh-wink::after, .fa-duotone.fa-face-laugh-wink::after {content: "\f59c\f59c";}.fad.fa-laugh-wink::after, .fa-duotone.fa-laugh-wink::after {content: "\f59c\f59c";}.fad.fa-face-lying::after, .fa-duotone.fa-face-lying::after {content: "\e37e\e37e";}.fad.fa-face-mask::after, .fa-duotone.fa-face-mask::after {content: "\e37f\e37f";}.fad.fa-face-meh::after, .fa-duotone.fa-face-meh::after {content: "\f11a\f11a";}.fad.fa-meh::after, .fa-duotone.fa-meh::after {content: "\f11a\f11a";}.fad.fa-face-meh-blank::after, .fa-duotone.fa-face-meh-blank::after {content: "\f5a4\f5a4";}.fad.fa-meh-blank::after, .fa-duotone.fa-meh-blank::after {content: "\f5a4\f5a4";}.fad.fa-face-melting::after, .fa-duotone.fa-face-melting::after {content: "\e483\e483";}.fad.fa-face-monocle::after, .fa-duotone.fa-face-monocle::after {content: "\e380\e380";}.fad.fa-face-nauseated::after, .fa-duotone.fa-face-nauseated::after {content: "\e381\e381";}.fad.fa-face-nose-steam::after, .fa-duotone.fa-face-nose-steam::after {content: "\e382\e382";}.fad.fa-face-party::after, .fa-duotone.fa-face-party::after {content: "\e383\e383";}.fad.fa-face-pensive::after, .fa-duotone.fa-face-pensive::after {content: "\e384\e384";}.fad.fa-face-persevering::after, .fa-duotone.fa-face-persevering::after {content: "\e385\e385";}.fad.fa-face-pleading::after, .fa-duotone.fa-face-pleading::after {content: "\e386\e386";}.fad.fa-face-pouting::after, .fa-duotone.fa-face-pouting::after {content: "\e387\e387";}.fad.fa-face-raised-eyebrow::after, .fa-duotone.fa-face-raised-eyebrow::after {content: "\e388\e388";}.fad.fa-face-relieved::after, .fa-duotone.fa-face-relieved::after {content: "\e389\e389";}.fad.fa-face-rolling-eyes::after, .fa-duotone.fa-face-rolling-eyes::after {content: "\f5a5\f5a5";}.fad.fa-meh-rolling-eyes::after, .fa-duotone.fa-meh-rolling-eyes::after {content: "\f5a5\f5a5";}.fad.fa-face-sad-cry::after, .fa-duotone.fa-face-sad-cry::after {content: "\f5b3\f5b3";}.fad.fa-sad-cry::after, .fa-duotone.fa-sad-cry::after {content: "\f5b3\f5b3";}.fad.fa-face-sad-sweat::after, .fa-duotone.fa-face-sad-sweat::after {content: "\e38a\e38a";}.fad.fa-face-sad-tear::after, .fa-duotone.fa-face-sad-tear::after {content: "\f5b4\f5b4";}.fad.fa-sad-tear::after, .fa-duotone.fa-sad-tear::after {content: "\f5b4\f5b4";}.fad.fa-face-saluting::after, .fa-duotone.fa-face-saluting::after {content: "\e484\e484";}.fad.fa-face-scream::after, .fa-duotone.fa-face-scream::after {content: "\e38b\e38b";}.fad.fa-face-shush::after, .fa-duotone.fa-face-shush::after {content: "\e38c\e38c";}.fad.fa-face-sleeping::after, .fa-duotone.fa-face-sleeping::after {content: "\e38d\e38d";}.fad.fa-face-sleepy::after, .fa-duotone.fa-face-sleepy::after {content: "\e38e\e38e";}.fad.fa-face-smile::after, .fa-duotone.fa-face-smile::after {content: "\f118\f118";}.fad.fa-smile::after, .fa-duotone.fa-smile::after {content: "\f118\f118";}.fad.fa-face-smile-beam::after, .fa-duotone.fa-face-smile-beam::after {content: "\f5b8\f5b8";}.fad.fa-smile-beam::after, .fa-duotone.fa-smile-beam::after {content: "\f5b8\f5b8";}.fad.fa-face-smile-halo::after, .fa-duotone.fa-face-smile-halo::after {content: "\e38f\e38f";}.fad.fa-face-smile-hearts::after, .fa-duotone.fa-face-smile-hearts::after {content: "\e390\e390";}.fad.fa-face-smile-horns::after, .fa-duotone.fa-face-smile-horns::after {content: "\e391\e391";}.fad.fa-face-smile-plus::after, .fa-duotone.fa-face-smile-plus::after {content: "\f5b9\f5b9";}.fad.fa-smile-plus::after, .fa-duotone.fa-smile-plus::after {content: "\f5b9\f5b9";}.fad.fa-face-smile-relaxed::after, .fa-duotone.fa-face-smile-relaxed::after {content: "\e392\e392";}.fad.fa-face-smile-tear::after, .fa-duotone.fa-face-smile-tear::after {content: "\e393\e393";}.fad.fa-face-smile-tongue::after, .fa-duotone.fa-face-smile-tongue::after {content: "\e394\e394";}.fad.fa-face-smile-upside-down::after, .fa-duotone.fa-face-smile-upside-down::after {content: "\e395\e395";}.fad.fa-face-smile-wink::after, .fa-duotone.fa-face-smile-wink::after {content: "\f4da\f4da";}.fad.fa-smile-wink::after, .fa-duotone.fa-smile-wink::after {content: "\f4da\f4da";}.fad.fa-face-smiling-hands::after, .fa-duotone.fa-face-smiling-hands::after {content: "\e396\e396";}.fad.fa-face-smirking::after, .fa-duotone.fa-face-smirking::after {content: "\e397\e397";}.fad.fa-face-spiral-eyes::after, .fa-duotone.fa-face-spiral-eyes::after {content: "\e485\e485";}.fad.fa-face-sunglasses::after, .fa-duotone.fa-face-sunglasses::after {content: "\e398\e398";}.fad.fa-face-surprise::after, .fa-duotone.fa-face-surprise::after {content: "\f5c2\f5c2";}.fad.fa-surprise::after, .fa-duotone.fa-surprise::after {content: "\f5c2\f5c2";}.fad.fa-face-swear::after, .fa-duotone.fa-face-swear::after {content: "\e399\e399";}.fad.fa-face-thermometer::after, .fa-duotone.fa-face-thermometer::after {content: "\e39a\e39a";}.fad.fa-face-thinking::after, .fa-duotone.fa-face-thinking::after {content: "\e39b\e39b";}.fad.fa-face-tired::after, .fa-duotone.fa-face-tired::after {content: "\f5c8\f5c8";}.fad.fa-tired::after, .fa-duotone.fa-tired::after {content: "\f5c8\f5c8";}.fad.fa-face-tissue::after, .fa-duotone.fa-face-tissue::after {content: "\e39c\e39c";}.fad.fa-face-tongue-money::after, .fa-duotone.fa-face-tongue-money::after {content: "\e39d\e39d";}.fad.fa-face-tongue-sweat::after, .fa-duotone.fa-face-tongue-sweat::after {content: "\e39e\e39e";}.fad.fa-face-unamused::after, .fa-duotone.fa-face-unamused::after {content: "\e39f\e39f";}.fad.fa-face-viewfinder::after, .fa-duotone.fa-face-viewfinder::after {content: "\e2ff\e2ff";}.fad.fa-face-vomit::after, .fa-duotone.fa-face-vomit::after {content: "\e3a0\e3a0";}.fad.fa-face-weary::after, .fa-duotone.fa-face-weary::after {content: "\e3a1\e3a1";}.fad.fa-face-woozy::after, .fa-duotone.fa-face-woozy::after {content: "\e3a2\e3a2";}.fad.fa-face-worried::after, .fa-duotone.fa-face-worried::after {content: "\e3a3\e3a3";}.fad.fa-face-zany::after, .fa-duotone.fa-face-zany::after {content: "\e3a4\e3a4";}.fad.fa-face-zipper::after, .fa-duotone.fa-face-zipper::after {content: "\e3a5\e3a5";}.fad.fa-falafel::after, .fa-duotone.fa-falafel::after {content: "\e40a\e40a";}.fad.fa-family::after, .fa-duotone.fa-family::after {content: "\e300\e300";}.fad.fa-family-dress::after, .fa-duotone.fa-family-dress::after {content: "\e301\e301";}.fad.fa-family-pants::after, .fa-duotone.fa-family-pants::after {content: "\e302\e302";}.fad.fa-fan::after, .fa-duotone.fa-fan::after {content: "\f863\f863";}.fad.fa-fan-table::after, .fa-duotone.fa-fan-table::after {content: "\e004\e004";}.fad.fa-farm::after, .fa-duotone.fa-farm::after {content: "\f864\f864";}.fad.fa-barn-silo::after, .fa-duotone.fa-barn-silo::after {content: "\f864\f864";}.fad.fa-faucet::after, .fa-duotone.fa-faucet::after {content: "\e005\e005";}.fad.fa-faucet-drip::after, .fa-duotone.fa-faucet-drip::after {content: "\e006\e006";}.fad.fa-fax::after, .fa-duotone.fa-fax::after {content: "\f1ac\f1ac";}.fad.fa-feather::after, .fa-duotone.fa-feather::after {content: "\f52d\f52d";}.fad.fa-feather-pointed::after, .fa-duotone.fa-feather-pointed::after {content: "\f56b\f56b";}.fad.fa-feather-alt::after, .fa-duotone.fa-feather-alt::after {content: "\f56b\f56b";}.fad.fa-fence::after, .fa-duotone.fa-fence::after {content: "\e303\e303";}.fad.fa-ferris-wheel::after, .fa-duotone.fa-ferris-wheel::after {content: "\e174\e174";}.fad.fa-ferry::after, .fa-duotone.fa-ferry::after {content: "\e4ea\e4ea";}.fad.fa-field-hockey-stick-ball::after, .fa-duotone.fa-field-hockey-stick-ball::after {content: "\f44c\f44c";}.fad.fa-field-hockey::after, .fa-duotone.fa-field-hockey::after {content: "\f44c\f44c";}.fad.fa-file::after, .fa-duotone.fa-file::after {content: "\f15b\f15b";}.fad.fa-file-arrow-down::after, .fa-duotone.fa-file-arrow-down::after {content: "\f56d\f56d";}.fad.fa-file-download::after, .fa-duotone.fa-file-download::after {content: "\f56d\f56d";}.fad.fa-file-arrow-up::after, .fa-duotone.fa-file-arrow-up::after {content: "\f574\f574";}.fad.fa-file-upload::after, .fa-duotone.fa-file-upload::after {content: "\f574\f574";}.fad.fa-file-audio::after, .fa-duotone.fa-file-audio::after {content: "\f1c7\f1c7";}.fad.fa-file-binary::after, .fa-duotone.fa-file-binary::after {content: "\e175\e175";}.fad.fa-file-certificate::after, .fa-duotone.fa-file-certificate::after {content: "\f5f3\f5f3";}.fad.fa-file-award::after, .fa-duotone.fa-file-award::after {content: "\f5f3\f5f3";}.fad.fa-file-chart-column::after, .fa-duotone.fa-file-chart-column::after {content: "\f659\f659";}.fad.fa-file-chart-line::after, .fa-duotone.fa-file-chart-line::after {content: "\f659\f659";}.fad.fa-file-chart-pie::after, .fa-duotone.fa-file-chart-pie::after {content: "\f65a\f65a";}.fad.fa-file-check::after, .fa-duotone.fa-file-check::after {content: "\f316\f316";}.fad.fa-file-circle-check::after, .fa-duotone.fa-file-circle-check::after {content: "\e493\e493";}.fad.fa-file-circle-exclamation::after, .fa-duotone.fa-file-circle-exclamation::after {content: "\e4eb\e4eb";}.fad.fa-file-circle-info::after, .fa-duotone.fa-file-circle-info::after {content: "\e4ec\e4ec";}.fad.fa-file-circle-minus::after, .fa-duotone.fa-file-circle-minus::after {content: "\e4ed\e4ed";}.fad.fa-file-circle-plus::after, .fa-duotone.fa-file-circle-plus::after {content: "\e4ee\e4ee";}.fad.fa-file-circle-question::after, .fa-duotone.fa-file-circle-question::after {content: "\e4ef\e4ef";}.fad.fa-file-circle-xmark::after, .fa-duotone.fa-file-circle-xmark::after {content: "\e494\e494";}.fad.fa-file-code::after, .fa-duotone.fa-file-code::after {content: "\f1c9\f1c9";}.fad.fa-file-contract::after, .fa-duotone.fa-file-contract::after {content: "\f56c\f56c";}.fad.fa-file-csv::after, .fa-duotone.fa-file-csv::after {content: "\f6dd\f6dd";}.fad.fa-file-dashed-line::after, .fa-duotone.fa-file-dashed-line::after {content: "\f877\f877";}.fad.fa-page-break::after, .fa-duotone.fa-page-break::after {content: "\f877\f877";}.fad.fa-file-excel::after, .fa-duotone.fa-file-excel::after {content: "\f1c3\f1c3";}.fad.fa-file-exclamation::after, .fa-duotone.fa-file-exclamation::after {content: "\f31a\f31a";}.fad.fa-file-export::after, .fa-duotone.fa-file-export::after {content: "\f56e\f56e";}.fad.fa-arrow-right-from-file::after, .fa-duotone.fa-arrow-right-from-file::after {content: "\f56e\f56e";}.fad.fa-file-heart::after, .fa-duotone.fa-file-heart::after {content: "\e176\e176";}.fad.fa-file-image::after, .fa-duotone.fa-file-image::after {content: "\f1c5\f1c5";}.fad.fa-file-import::after, .fa-duotone.fa-file-import::after {content: "\f56f\f56f";}.fad.fa-arrow-right-to-file::after, .fa-duotone.fa-arrow-right-to-file::after {content: "\f56f\f56f";}.fad.fa-file-invoice::after, .fa-duotone.fa-file-invoice::after {content: "\f570\f570";}.fad.fa-file-invoice-dollar::after, .fa-duotone.fa-file-invoice-dollar::after {content: "\f571\f571";}.fad.fa-file-lines::after, .fa-duotone.fa-file-lines::after {content: "\f15c\f15c";}.fad.fa-file-alt::after, .fa-duotone.fa-file-alt::after {content: "\f15c\f15c";}.fad.fa-file-text::after, .fa-duotone.fa-file-text::after {content: "\f15c\f15c";}.fad.fa-file-lock::after, .fa-duotone.fa-file-lock::after {content: "\e3a6\e3a6";}.fad.fa-file-magnifying-glass::after, .fa-duotone.fa-file-magnifying-glass::after {content: "\f865\f865";}.fad.fa-file-search::after, .fa-duotone.fa-file-search::after {content: "\f865\f865";}.fad.fa-file-medical::after, .fa-duotone.fa-file-medical::after {content: "\f477\f477";}.fad.fa-file-minus::after, .fa-duotone.fa-file-minus::after {content: "\f318\f318";}.fad.fa-file-music::after, .fa-duotone.fa-file-music::after {content: "\f8b6\f8b6";}.fad.fa-file-pdf::after, .fa-duotone.fa-file-pdf::after {content: "\f1c1\f1c1";}.fad.fa-file-pen::after, .fa-duotone.fa-file-pen::after {content: "\f31c\f31c";}.fad.fa-file-edit::after, .fa-duotone.fa-file-edit::after {content: "\f31c\f31c";}.fad.fa-file-plus::after, .fa-duotone.fa-file-plus::after {content: "\f319\f319";}.fad.fa-file-plus-minus::after, .fa-duotone.fa-file-plus-minus::after {content: "\e177\e177";}.fad.fa-file-powerpoint::after, .fa-duotone.fa-file-powerpoint::after {content: "\f1c4\f1c4";}.fad.fa-file-prescription::after, .fa-duotone.fa-file-prescription::after {content: "\f572\f572";}.fad.fa-file-shield::after, .fa-duotone.fa-file-shield::after {content: "\e4f0\e4f0";}.fad.fa-file-signature::after, .fa-duotone.fa-file-signature::after {content: "\f573\f573";}.fad.fa-file-slash::after, .fa-duotone.fa-file-slash::after {content: "\e3a7\e3a7";}.fad.fa-file-spreadsheet::after, .fa-duotone.fa-file-spreadsheet::after {content: "\f65b\f65b";}.fad.fa-file-user::after, .fa-duotone.fa-file-user::after {content: "\f65c\f65c";}.fad.fa-file-video::after, .fa-duotone.fa-file-video::after {content: "\f1c8\f1c8";}.fad.fa-file-waveform::after, .fa-duotone.fa-file-waveform::after {content: "\f478\f478";}.fad.fa-file-medical-alt::after, .fa-duotone.fa-file-medical-alt::after {content: "\f478\f478";}.fad.fa-file-word::after, .fa-duotone.fa-file-word::after {content: "\f1c2\f1c2";}.fad.fa-file-xmark::after, .fa-duotone.fa-file-xmark::after {content: "\f317\f317";}.fad.fa-file-times::after, .fa-duotone.fa-file-times::after {content: "\f317\f317";}.fad.fa-file-zipper::after, .fa-duotone.fa-file-zipper::after {content: "\f1c6\f1c6";}.fad.fa-file-archive::after, .fa-duotone.fa-file-archive::after {content: "\f1c6\f1c6";}.fad.fa-files::after, .fa-duotone.fa-files::after {content: "\e178\e178";}.fad.fa-files-medical::after, .fa-duotone.fa-files-medical::after {content: "\f7fd\f7fd";}.fad.fa-fill::after, .fa-duotone.fa-fill::after {content: "\f575\f575";}.fad.fa-fill-drip::after, .fa-duotone.fa-fill-drip::after {content: "\f576\f576";}.fad.fa-film::after, .fa-duotone.fa-film::after {content: "\f008\f008";}.fad.fa-film-canister::after, .fa-duotone.fa-film-canister::after {content: "\f8b7\f8b7";}.fad.fa-film-simple::after, .fa-duotone.fa-film-simple::after {content: "\f3a0\f3a0";}.fad.fa-film-alt::after, .fa-duotone.fa-film-alt::after {content: "\f3a0\f3a0";}.fad.fa-film-slash::after, .fa-duotone.fa-film-slash::after {content: "\e179\e179";}.fad.fa-films::after, .fa-duotone.fa-films::after {content: "\e17a\e17a";}.fad.fa-filter::after, .fa-duotone.fa-filter::after {content: "\f0b0\f0b0";}.fad.fa-filter-circle-dollar::after, .fa-duotone.fa-filter-circle-dollar::after {content: "\f662\f662";}.fad.fa-funnel-dollar::after, .fa-duotone.fa-funnel-dollar::after {content: "\f662\f662";}.fad.fa-filter-circle-xmark::after, .fa-duotone.fa-filter-circle-xmark::after {content: "\e17b\e17b";}.fad.fa-filter-list::after, .fa-duotone.fa-filter-list::after {content: "\e17c\e17c";}.fad.fa-filter-slash::after, .fa-duotone.fa-filter-slash::after {content: "\e17d\e17d";}.fad.fa-filters::after, .fa-duotone.fa-filters::after {content: "\e17e\e17e";}.fad.fa-fingerprint::after, .fa-duotone.fa-fingerprint::after {content: "\f577\f577";}.fad.fa-fire::after, .fa-duotone.fa-fire::after {content: "\f06d\f06d";}.fad.fa-fire-burner::after, .fa-duotone.fa-fire-burner::after {content: "\e4f1\e4f1";}.fad.fa-fire-extinguisher::after, .fa-duotone.fa-fire-extinguisher::after {content: "\f134\f134";}.fad.fa-fire-flame::after, .fa-duotone.fa-fire-flame::after {content: "\f6df\f6df";}.fad.fa-flame::after, .fa-duotone.fa-flame::after {content: "\f6df\f6df";}.fad.fa-fire-flame-curved::after, .fa-duotone.fa-fire-flame-curved::after {content: "\f7e4\f7e4";}.fad.fa-fire-alt::after, .fa-duotone.fa-fire-alt::after {content: "\f7e4\f7e4";}.fad.fa-fire-flame-simple::after, .fa-duotone.fa-fire-flame-simple::after {content: "\f46a\f46a";}.fad.fa-burn::after, .fa-duotone.fa-burn::after {content: "\f46a\f46a";}.fad.fa-fire-hydrant::after, .fa-duotone.fa-fire-hydrant::after {content: "\e17f\e17f";}.fad.fa-fire-smoke::after, .fa-duotone.fa-fire-smoke::after {content: "\f74b\f74b";}.fad.fa-fireplace::after, .fa-duotone.fa-fireplace::after {content: "\f79a\f79a";}.fad.fa-fish::after, .fa-duotone.fa-fish::after {content: "\f578\f578";}.fad.fa-fish-bones::after, .fa-duotone.fa-fish-bones::after {content: "\e304\e304";}.fad.fa-fish-cooked::after, .fa-duotone.fa-fish-cooked::after {content: "\f7fe\f7fe";}.fad.fa-fish-fins::after, .fa-duotone.fa-fish-fins::after {content: "\e4f2\e4f2";}.fad.fa-fishing-rod::after, .fa-duotone.fa-fishing-rod::after {content: "\e3a8\e3a8";}.fad.fa-flag::after, .fa-duotone.fa-flag::after {content: "\f024\f024";}.fad.fa-flag-checkered::after, .fa-duotone.fa-flag-checkered::after {content: "\f11e\f11e";}.fad.fa-flag-pennant::after, .fa-duotone.fa-flag-pennant::after {content: "\f456\f456";}.fad.fa-pennant::after, .fa-duotone.fa-pennant::after {content: "\f456\f456";}.fad.fa-flag-swallowtail::after, .fa-duotone.fa-flag-swallowtail::after {content: "\f74c\f74c";}.fad.fa-flag-alt::after, .fa-duotone.fa-flag-alt::after {content: "\f74c\f74c";}.fad.fa-flag-usa::after, .fa-duotone.fa-flag-usa::after {content: "\f74d\f74d";}.fad.fa-flashlight::after, .fa-duotone.fa-flashlight::after {content: "\f8b8\f8b8";}.fad.fa-flask::after, .fa-duotone.fa-flask::after {content: "\f0c3\f0c3";}.fad.fa-flask-round-poison::after, .fa-duotone.fa-flask-round-poison::after {content: "\f6e0\f6e0";}.fad.fa-flask-poison::after, .fa-duotone.fa-flask-poison::after {content: "\f6e0\f6e0";}.fad.fa-flask-round-potion::after, .fa-duotone.fa-flask-round-potion::after {content: "\f6e1\f6e1";}.fad.fa-flask-potion::after, .fa-duotone.fa-flask-potion::after {content: "\f6e1\f6e1";}.fad.fa-flask-vial::after, .fa-duotone.fa-flask-vial::after {content: "\e4f3\e4f3";}.fad.fa-flatbread::after, .fa-duotone.fa-flatbread::after {content: "\e40b\e40b";}.fad.fa-flatbread-stuffed::after, .fa-duotone.fa-flatbread-stuffed::after {content: "\e40c\e40c";}.fad.fa-floppy-disk::after, .fa-duotone.fa-floppy-disk::after {content: "\f0c7\f0c7";}.fad.fa-save::after, .fa-duotone.fa-save::after {content: "\f0c7\f0c7";}.fad.fa-floppy-disk-circle-arrow-right::after, .fa-duotone.fa-floppy-disk-circle-arrow-right::after {content: "\e180\e180";}.fad.fa-save-circle-arrow-right::after, .fa-duotone.fa-save-circle-arrow-right::after {content: "\e180\e180";}.fad.fa-floppy-disk-circle-xmark::after, .fa-duotone.fa-floppy-disk-circle-xmark::after {content: "\e181\e181";}.fad.fa-floppy-disk-times::after, .fa-duotone.fa-floppy-disk-times::after {content: "\e181\e181";}.fad.fa-save-circle-xmark::after, .fa-duotone.fa-save-circle-xmark::after {content: "\e181\e181";}.fad.fa-save-times::after, .fa-duotone.fa-save-times::after {content: "\e181\e181";}.fad.fa-floppy-disk-pen::after, .fa-duotone.fa-floppy-disk-pen::after {content: "\e182\e182";}.fad.fa-floppy-disks::after, .fa-duotone.fa-floppy-disks::after {content: "\e183\e183";}.fad.fa-florin-sign::after, .fa-duotone.fa-florin-sign::after {content: "\e184\e184";}.fad.fa-flower::after, .fa-duotone.fa-flower::after {content: "\f7ff\f7ff";}.fad.fa-flower-daffodil::after, .fa-duotone.fa-flower-daffodil::after {content: "\f800\f800";}.fad.fa-flower-tulip::after, .fa-duotone.fa-flower-tulip::after {content: "\f801\f801";}.fad.fa-flute::after, .fa-duotone.fa-flute::after {content: "\f8b9\f8b9";}.fad.fa-flux-capacitor::after, .fa-duotone.fa-flux-capacitor::after {content: "\f8ba\f8ba";}.fad.fa-flying-disc::after, .fa-duotone.fa-flying-disc::after {content: "\e3a9\e3a9";}.fad.fa-folder::after, .fa-duotone.fa-folder::after {content: "\f07b\f07b";}.fad.fa-folder-blank::after, .fa-duotone.fa-folder-blank::after {content: "\f07b\f07b";}.fad.fa-folder-arrow-down::after, .fa-duotone.fa-folder-arrow-down::after {content: "\e053\e053";}.fad.fa-folder-download::after, .fa-duotone.fa-folder-download::after {content: "\e053\e053";}.fad.fa-folder-arrow-up::after, .fa-duotone.fa-folder-arrow-up::after {content: "\e054\e054";}.fad.fa-folder-upload::after, .fa-duotone.fa-folder-upload::after {content: "\e054\e054";}.fad.fa-folder-bookmark::after, .fa-duotone.fa-folder-bookmark::after {content: "\e186\e186";}.fad.fa-folder-closed::after, .fa-duotone.fa-folder-closed::after {content: "\e185\e185";}.fad.fa-folder-gear::after, .fa-duotone.fa-folder-gear::after {content: "\e187\e187";}.fad.fa-folder-cog::after, .fa-duotone.fa-folder-cog::after {content: "\e187\e187";}.fad.fa-folder-grid::after, .fa-duotone.fa-folder-grid::after {content: "\e188\e188";}.fad.fa-folder-heart::after, .fa-duotone.fa-folder-heart::after {content: "\e189\e189";}.fad.fa-folder-image::after, .fa-duotone.fa-folder-image::after {content: "\e18a\e18a";}.fad.fa-folder-magnifying-glass::after, .fa-duotone.fa-folder-magnifying-glass::after {content: "\e18b\e18b";}.fad.fa-folder-search::after, .fa-duotone.fa-folder-search::after {content: "\e18b\e18b";}.fad.fa-folder-medical::after, .fa-duotone.fa-folder-medical::after {content: "\e18c\e18c";}.fad.fa-folder-minus::after, .fa-duotone.fa-folder-minus::after {content: "\f65d\f65d";}.fad.fa-folder-music::after, .fa-duotone.fa-folder-music::after {content: "\e18d\e18d";}.fad.fa-folder-open::after, .fa-duotone.fa-folder-open::after {content: "\f07c\f07c";}.fad.fa-folder-plus::after, .fa-duotone.fa-folder-plus::after {content: "\f65e\f65e";}.fad.fa-folder-tree::after, .fa-duotone.fa-folder-tree::after {content: "\f802\f802";}.fad.fa-folder-user::after, .fa-duotone.fa-folder-user::after {content: "\e18e\e18e";}.fad.fa-folder-xmark::after, .fa-duotone.fa-folder-xmark::after {content: "\f65f\f65f";}.fad.fa-folder-times::after, .fa-duotone.fa-folder-times::after {content: "\f65f\f65f";}.fad.fa-folders::after, .fa-duotone.fa-folders::after {content: "\f660\f660";}.fad.fa-fondue-pot::after, .fa-duotone.fa-fondue-pot::after {content: "\e40d\e40d";}.fad.fa-font::after, .fa-duotone.fa-font::after {content: "\f031\f031";}.fad.fa-font-case::after, .fa-duotone.fa-font-case::after {content: "\f866\f866";}.fad.fa-football::after, .fa-duotone.fa-football::after {content: "\f44e\f44e";}.fad.fa-football-ball::after, .fa-duotone.fa-football-ball::after {content: "\f44e\f44e";}.fad.fa-football-helmet::after, .fa-duotone.fa-football-helmet::after {content: "\f44f\f44f";}.fad.fa-fork::after, .fa-duotone.fa-fork::after {content: "\f2e3\f2e3";}.fad.fa-utensil-fork::after, .fa-duotone.fa-utensil-fork::after {content: "\f2e3\f2e3";}.fad.fa-fork-knife::after, .fa-duotone.fa-fork-knife::after {content: "\f2e6\f2e6";}.fad.fa-utensils-alt::after, .fa-duotone.fa-utensils-alt::after {content: "\f2e6\f2e6";}.fad.fa-forklift::after, .fa-duotone.fa-forklift::after {content: "\f47a\f47a";}.fad.fa-fort::after, .fa-duotone.fa-fort::after {content: "\e486\e486";}.fad.fa-forward::after, .fa-duotone.fa-forward::after {content: "\f04e\f04e";}.fad.fa-forward-fast::after, .fa-duotone.fa-forward-fast::after {content: "\f050\f050";}.fad.fa-fast-forward::after, .fa-duotone.fa-fast-forward::after {content: "\f050\f050";}.fad.fa-forward-step::after, .fa-duotone.fa-forward-step::after {content: "\f051\f051";}.fad.fa-step-forward::after, .fa-duotone.fa-step-forward::after {content: "\f051\f051";}.fad.fa-frame::after, .fa-duotone.fa-frame::after {content: "\e495\e495";}.fad.fa-franc-sign::after, .fa-duotone.fa-franc-sign::after {content: "\e18f\e18f";}.fad.fa-french-fries::after, .fa-duotone.fa-french-fries::after {content: "\f803\f803";}.fad.fa-frog::after, .fa-duotone.fa-frog::after {content: "\f52e\f52e";}.fad.fa-function::after, .fa-duotone.fa-function::after {content: "\f661\f661";}.fad.fa-futbol::after, .fa-duotone.fa-futbol::after {content: "\f1e3\f1e3";}.fad.fa-futbol-ball::after, .fa-duotone.fa-futbol-ball::after {content: "\f1e3\f1e3";}.fad.fa-soccer-ball::after, .fa-duotone.fa-soccer-ball::after {content: "\f1e3\f1e3";}.fad.fa-g::after, .fa-duotone.fa-g::after {content: "\47\47";}.fad.fa-galaxy::after, .fa-duotone.fa-galaxy::after {content: "\e008\e008";}.fad.fa-gallery-thumbnails::after, .fa-duotone.fa-gallery-thumbnails::after {content: "\e3aa\e3aa";}.fad.fa-game-board::after, .fa-duotone.fa-game-board::after {content: "\f867\f867";}.fad.fa-game-board-simple::after, .fa-duotone.fa-game-board-simple::after {content: "\f868\f868";}.fad.fa-game-board-alt::after, .fa-duotone.fa-game-board-alt::after {content: "\f868\f868";}.fad.fa-game-console-handheld::after, .fa-duotone.fa-game-console-handheld::after {content: "\f8bb\f8bb";}.fad.fa-gamepad::after, .fa-duotone.fa-gamepad::after {content: "\f11b\f11b";}.fad.fa-gamepad-modern::after, .fa-duotone.fa-gamepad-modern::after {content: "\f8bc\f8bc";}.fad.fa-gamepad-alt::after, .fa-duotone.fa-gamepad-alt::after {content: "\f8bc\f8bc";}.fad.fa-garage::after, .fa-duotone.fa-garage::after {content: "\e009\e009";}.fad.fa-garage-car::after, .fa-duotone.fa-garage-car::after {content: "\e00a\e00a";}.fad.fa-garage-open::after, .fa-duotone.fa-garage-open::after {content: "\e00b\e00b";}.fad.fa-garlic::after, .fa-duotone.fa-garlic::after {content: "\e40e\e40e";}.fad.fa-gas-pump::after, .fa-duotone.fa-gas-pump::after {content: "\f52f\f52f";}.fad.fa-gas-pump-slash::after, .fa-duotone.fa-gas-pump-slash::after {content: "\f5f4\f5f4";}.fad.fa-gauge::after, .fa-duotone.fa-gauge::after {content: "\f624\f624";}.fad.fa-dashboard::after, .fa-duotone.fa-dashboard::after {content: "\f624\f624";}.fad.fa-gauge-med::after, .fa-duotone.fa-gauge-med::after {content: "\f624\f624";}.fad.fa-tachometer-alt-average::after, .fa-duotone.fa-tachometer-alt-average::after {content: "\f624\f624";}.fad.fa-gauge-circle-bolt::after, .fa-duotone.fa-gauge-circle-bolt::after {content: "\e496\e496";}.fad.fa-gauge-circle-minus::after, .fa-duotone.fa-gauge-circle-minus::after {content: "\e497\e497";}.fad.fa-gauge-circle-plus::after, .fa-duotone.fa-gauge-circle-plus::after {content: "\e498\e498";}.fad.fa-gauge-high::after, .fa-duotone.fa-gauge-high::after {content: "\f625\f625";}.fad.fa-tachometer-alt::after, .fa-duotone.fa-tachometer-alt::after {content: "\f625\f625";}.fad.fa-tachometer-alt-fast::after, .fa-duotone.fa-tachometer-alt-fast::after {content: "\f625\f625";}.fad.fa-gauge-low::after, .fa-duotone.fa-gauge-low::after {content: "\f627\f627";}.fad.fa-tachometer-alt-slow::after, .fa-duotone.fa-tachometer-alt-slow::after {content: "\f627\f627";}.fad.fa-gauge-max::after, .fa-duotone.fa-gauge-max::after {content: "\f626\f626";}.fad.fa-tachometer-alt-fastest::after, .fa-duotone.fa-tachometer-alt-fastest::after {content: "\f626\f626";}.fad.fa-gauge-min::after, .fa-duotone.fa-gauge-min::after {content: "\f628\f628";}.fad.fa-tachometer-alt-slowest::after, .fa-duotone.fa-tachometer-alt-slowest::after {content: "\f628\f628";}.fad.fa-gauge-simple::after, .fa-duotone.fa-gauge-simple::after {content: "\f629\f629";}.fad.fa-gauge-simple-med::after, .fa-duotone.fa-gauge-simple-med::after {content: "\f629\f629";}.fad.fa-tachometer-average::after, .fa-duotone.fa-tachometer-average::after {content: "\f629\f629";}.fad.fa-gauge-simple-high::after, .fa-duotone.fa-gauge-simple-high::after {content: "\f62a\f62a";}.fad.fa-tachometer::after, .fa-duotone.fa-tachometer::after {content: "\f62a\f62a";}.fad.fa-tachometer-fast::after, .fa-duotone.fa-tachometer-fast::after {content: "\f62a\f62a";}.fad.fa-gauge-simple-low::after, .fa-duotone.fa-gauge-simple-low::after {content: "\f62c\f62c";}.fad.fa-tachometer-slow::after, .fa-duotone.fa-tachometer-slow::after {content: "\f62c\f62c";}.fad.fa-gauge-simple-max::after, .fa-duotone.fa-gauge-simple-max::after {content: "\f62b\f62b";}.fad.fa-tachometer-fastest::after, .fa-duotone.fa-tachometer-fastest::after {content: "\f62b\f62b";}.fad.fa-gauge-simple-min::after, .fa-duotone.fa-gauge-simple-min::after {content: "\f62d\f62d";}.fad.fa-tachometer-slowest::after, .fa-duotone.fa-tachometer-slowest::after {content: "\f62d\f62d";}.fad.fa-gavel::after, .fa-duotone.fa-gavel::after {content: "\f0e3\f0e3";}.fad.fa-legal::after, .fa-duotone.fa-legal::after {content: "\f0e3\f0e3";}.fad.fa-gear::after, .fa-duotone.fa-gear::after {content: "\f013\f013";}.fad.fa-cog::after, .fa-duotone.fa-cog::after {content: "\f013\f013";}.fad.fa-gears::after, .fa-duotone.fa-gears::after {content: "\f085\f085";}.fad.fa-cogs::after, .fa-duotone.fa-cogs::after {content: "\f085\f085";}.fad.fa-gem::after, .fa-duotone.fa-gem::after {content: "\f3a5\f3a5";}.fad.fa-genderless::after, .fa-duotone.fa-genderless::after {content: "\f22d\f22d";}.fad.fa-ghost::after, .fa-duotone.fa-ghost::after {content: "\f6e2\f6e2";}.fad.fa-gif::after, .fa-duotone.fa-gif::after {content: "\e190\e190";}.fad.fa-gift::after, .fa-duotone.fa-gift::after {content: "\f06b\f06b";}.fad.fa-gift-card::after, .fa-duotone.fa-gift-card::after {content: "\f663\f663";}.fad.fa-gifts::after, .fa-duotone.fa-gifts::after {content: "\f79c\f79c";}.fad.fa-gingerbread-man::after, .fa-duotone.fa-gingerbread-man::after {content: "\f79d\f79d";}.fad.fa-glass::after, .fa-duotone.fa-glass::after {content: "\f804\f804";}.fad.fa-glass-citrus::after, .fa-duotone.fa-glass-citrus::after {content: "\f869\f869";}.fad.fa-glass-empty::after, .fa-duotone.fa-glass-empty::after {content: "\e191\e191";}.fad.fa-glass-half::after, .fa-duotone.fa-glass-half::after {content: "\e192\e192";}.fad.fa-glass-half-empty::after, .fa-duotone.fa-glass-half-empty::after {content: "\e192\e192";}.fad.fa-glass-half-full::after, .fa-duotone.fa-glass-half-full::after {content: "\e192\e192";}.fad.fa-glass-water::after, .fa-duotone.fa-glass-water::after {content: "\e4f4\e4f4";}.fad.fa-glass-water-droplet::after, .fa-duotone.fa-glass-water-droplet::after {content: "\e4f5\e4f5";}.fad.fa-glasses::after, .fa-duotone.fa-glasses::after {content: "\f530\f530";}.fad.fa-glasses-round::after, .fa-duotone.fa-glasses-round::after {content: "\f5f5\f5f5";}.fad.fa-glasses-alt::after, .fa-duotone.fa-glasses-alt::after {content: "\f5f5\f5f5";}.fad.fa-globe::after, .fa-duotone.fa-globe::after {content: "\f0ac\f0ac";}.fad.fa-globe-snow::after, .fa-duotone.fa-globe-snow::after {content: "\f7a3\f7a3";}.fad.fa-globe-stand::after, .fa-duotone.fa-globe-stand::after {content: "\f5f6\f5f6";}.fad.fa-goal-net::after, .fa-duotone.fa-goal-net::after {content: "\e3ab\e3ab";}.fad.fa-golf-ball-tee::after, .fa-duotone.fa-golf-ball-tee::after {content: "\f450\f450";}.fad.fa-golf-ball::after, .fa-duotone.fa-golf-ball::after {content: "\f450\f450";}.fad.fa-golf-club::after, .fa-duotone.fa-golf-club::after {content: "\f451\f451";}.fad.fa-golf-flag-hole::after, .fa-duotone.fa-golf-flag-hole::after {content: "\e3ac\e3ac";}.fad.fa-gopuram::after, .fa-duotone.fa-gopuram::after {content: "\f664\f664";}.fad.fa-graduation-cap::after, .fa-duotone.fa-graduation-cap::after {content: "\f19d\f19d";}.fad.fa-mortar-board::after, .fa-duotone.fa-mortar-board::after {content: "\f19d\f19d";}.fad.fa-gramophone::after, .fa-duotone.fa-gramophone::after {content: "\f8bd\f8bd";}.fad.fa-grapes::after, .fa-duotone.fa-grapes::after {content: "\e306\e306";}.fad.fa-grate::after, .fa-duotone.fa-grate::after {content: "\e193\e193";}.fad.fa-grate-droplet::after, .fa-duotone.fa-grate-droplet::after {content: "\e194\e194";}.fad.fa-greater-than::after, .fa-duotone.fa-greater-than::after {content: "\3e\3e";}.fad.fa-greater-than-equal::after, .fa-duotone.fa-greater-than-equal::after {content: "\f532\f532";}.fad.fa-grid::after, .fa-duotone.fa-grid::after {content: "\e195\e195";}.fad.fa-grid-3::after, .fa-duotone.fa-grid-3::after {content: "\e195\e195";}.fad.fa-grid-2::after, .fa-duotone.fa-grid-2::after {content: "\e196\e196";}.fad.fa-grid-2-plus::after, .fa-duotone.fa-grid-2-plus::after {content: "\e197\e197";}.fad.fa-grid-4::after, .fa-duotone.fa-grid-4::after {content: "\e198\e198";}.fad.fa-grid-5::after, .fa-duotone.fa-grid-5::after {content: "\e199\e199";}.fad.fa-grid-dividers::after, .fa-duotone.fa-grid-dividers::after {content: "\e3ad\e3ad";}.fad.fa-grid-horizontal::after, .fa-duotone.fa-grid-horizontal::after {content: "\e307\e307";}.fad.fa-grip::after, .fa-duotone.fa-grip::after {content: "\f58d\f58d";}.fad.fa-grip-horizontal::after, .fa-duotone.fa-grip-horizontal::after {content: "\f58d\f58d";}.fad.fa-grip-dots::after, .fa-duotone.fa-grip-dots::after {content: "\e410\e410";}.fad.fa-grip-dots-vertical::after, .fa-duotone.fa-grip-dots-vertical::after {content: "\e411\e411";}.fad.fa-grip-lines::after, .fa-duotone.fa-grip-lines::after {content: "\f7a4\f7a4";}.fad.fa-grip-lines-vertical::after, .fa-duotone.fa-grip-lines-vertical::after {content: "\f7a5\f7a5";}.fad.fa-grip-vertical::after, .fa-duotone.fa-grip-vertical::after {content: "\f58e\f58e";}.fad.fa-group-arrows-rotate::after, .fa-duotone.fa-group-arrows-rotate::after {content: "\e4f6\e4f6";}.fad.fa-guarani-sign::after, .fa-duotone.fa-guarani-sign::after {content: "\e19a\e19a";}.fad.fa-guitar::after, .fa-duotone.fa-guitar::after {content: "\f7a6\f7a6";}.fad.fa-guitar-electric::after, .fa-duotone.fa-guitar-electric::after {content: "\f8be\f8be";}.fad.fa-guitars::after, .fa-duotone.fa-guitars::after {content: "\f8bf\f8bf";}.fad.fa-gun::after, .fa-duotone.fa-gun::after {content: "\e19b\e19b";}.fad.fa-gun-slash::after, .fa-duotone.fa-gun-slash::after {content: "\e19c\e19c";}.fad.fa-gun-squirt::after, .fa-duotone.fa-gun-squirt::after {content: "\e19d\e19d";}.fad.fa-h::after, .fa-duotone.fa-h::after {content: "\48\48";}.fad.fa-h1::after, .fa-duotone.fa-h1::after {content: "\f313\f313";}.fad.fa-h2::after, .fa-duotone.fa-h2::after {content: "\f314\f314";}.fad.fa-h3::after, .fa-duotone.fa-h3::after {content: "\f315\f315";}.fad.fa-h4::after, .fa-duotone.fa-h4::after {content: "\f86a\f86a";}.fad.fa-h5::after, .fa-duotone.fa-h5::after {content: "\e412\e412";}.fad.fa-h6::after, .fa-duotone.fa-h6::after {content: "\e413\e413";}.fad.fa-hammer::after, .fa-duotone.fa-hammer::after {content: "\f6e3\f6e3";}.fad.fa-hammer-crash::after, .fa-duotone.fa-hammer-crash::after {content: "\e414\e414";}.fad.fa-hammer-war::after, .fa-duotone.fa-hammer-war::after {content: "\f6e4\f6e4";}.fad.fa-hamsa::after, .fa-duotone.fa-hamsa::after {content: "\f665\f665";}.fad.fa-hand::after, .fa-duotone.fa-hand::after {content: "\f256\f256";}.fad.fa-hand-paper::after, .fa-duotone.fa-hand-paper::after {content: "\f256\f256";}.fad.fa-hand-back-fist::after, .fa-duotone.fa-hand-back-fist::after {content: "\f255\f255";}.fad.fa-hand-rock::after, .fa-duotone.fa-hand-rock::after {content: "\f255\f255";}.fad.fa-hand-back-point-down::after, .fa-duotone.fa-hand-back-point-down::after {content: "\e19e\e19e";}.fad.fa-hand-back-point-left::after, .fa-duotone.fa-hand-back-point-left::after {content: "\e19f\e19f";}.fad.fa-hand-back-point-ribbon::after, .fa-duotone.fa-hand-back-point-ribbon::after {content: "\e1a0\e1a0";}.fad.fa-hand-back-point-right::after, .fa-duotone.fa-hand-back-point-right::after {content: "\e1a1\e1a1";}.fad.fa-hand-back-point-up::after, .fa-duotone.fa-hand-back-point-up::after {content: "\e1a2\e1a2";}.fad.fa-hand-dots::after, .fa-duotone.fa-hand-dots::after {content: "\f461\f461";}.fad.fa-allergies::after, .fa-duotone.fa-allergies::after {content: "\f461\f461";}.fad.fa-hand-fingers-crossed::after, .fa-duotone.fa-hand-fingers-crossed::after {content: "\e1a3\e1a3";}.fad.fa-hand-fist::after, .fa-duotone.fa-hand-fist::after {content: "\f6de\f6de";}.fad.fa-fist-raised::after, .fa-duotone.fa-fist-raised::after {content: "\f6de\f6de";}.fad.fa-hand-heart::after, .fa-duotone.fa-hand-heart::after {content: "\f4bc\f4bc";}.fad.fa-hand-holding::after, .fa-duotone.fa-hand-holding::after {content: "\f4bd\f4bd";}.fad.fa-hand-holding-box::after, .fa-duotone.fa-hand-holding-box::after {content: "\f47b\f47b";}.fad.fa-hand-holding-dollar::after, .fa-duotone.fa-hand-holding-dollar::after {content: "\f4c0\f4c0";}.fad.fa-hand-holding-usd::after, .fa-duotone.fa-hand-holding-usd::after {content: "\f4c0\f4c0";}.fad.fa-hand-holding-droplet::after, .fa-duotone.fa-hand-holding-droplet::after {content: "\f4c1\f4c1";}.fad.fa-hand-holding-water::after, .fa-duotone.fa-hand-holding-water::after {content: "\f4c1\f4c1";}.fad.fa-hand-holding-hand::after, .fa-duotone.fa-hand-holding-hand::after {content: "\e4f7\e4f7";}.fad.fa-hand-holding-heart::after, .fa-duotone.fa-hand-holding-heart::after {content: "\f4be\f4be";}.fad.fa-hand-holding-magic::after, .fa-duotone.fa-hand-holding-magic::after {content: "\f6e5\f6e5";}.fad.fa-hand-holding-medical::after, .fa-duotone.fa-hand-holding-medical::after {content: "\e05c\e05c";}.fad.fa-hand-holding-seedling::after, .fa-duotone.fa-hand-holding-seedling::after {content: "\f4bf\f4bf";}.fad.fa-hand-holding-skull::after, .fa-duotone.fa-hand-holding-skull::after {content: "\e1a4\e1a4";}.fad.fa-hand-horns::after, .fa-duotone.fa-hand-horns::after {content: "\e1a9\e1a9";}.fad.fa-hand-lizard::after, .fa-duotone.fa-hand-lizard::after {content: "\f258\f258";}.fad.fa-hand-love::after, .fa-duotone.fa-hand-love::after {content: "\e1a5\e1a5";}.fad.fa-hand-middle-finger::after, .fa-duotone.fa-hand-middle-finger::after {content: "\f806\f806";}.fad.fa-hand-peace::after, .fa-duotone.fa-hand-peace::after {content: "\f25b\f25b";}.fad.fa-hand-point-down::after, .fa-duotone.fa-hand-point-down::after {content: "\f0a7\f0a7";}.fad.fa-hand-point-left::after, .fa-duotone.fa-hand-point-left::after {content: "\f0a5\f0a5";}.fad.fa-hand-point-ribbon::after, .fa-duotone.fa-hand-point-ribbon::after {content: "\e1a6\e1a6";}.fad.fa-hand-point-right::after, .fa-duotone.fa-hand-point-right::after {content: "\f0a4\f0a4";}.fad.fa-hand-point-up::after, .fa-duotone.fa-hand-point-up::after {content: "\f0a6\f0a6";}.fad.fa-hand-pointer::after, .fa-duotone.fa-hand-pointer::after {content: "\f25a\f25a";}.fad.fa-hand-scissors::after, .fa-duotone.fa-hand-scissors::after {content: "\f257\f257";}.fad.fa-hand-sparkles::after, .fa-duotone.fa-hand-sparkles::after {content: "\e05d\e05d";}.fad.fa-hand-spock::after, .fa-duotone.fa-hand-spock::after {content: "\f259\f259";}.fad.fa-hand-wave::after, .fa-duotone.fa-hand-wave::after {content: "\e1a7\e1a7";}.fad.fa-handcuffs::after, .fa-duotone.fa-handcuffs::after {content: "\e4f8\e4f8";}.fad.fa-hands::after, .fa-duotone.fa-hands::after {content: "\f2a7\f2a7";}.fad.fa-sign-language::after, .fa-duotone.fa-sign-language::after {content: "\f2a7\f2a7";}.fad.fa-signing::after, .fa-duotone.fa-signing::after {content: "\f2a7\f2a7";}.fad.fa-hands-asl-interpreting::after, .fa-duotone.fa-hands-asl-interpreting::after {content: "\f2a3\f2a3";}.fad.fa-american-sign-language-interpreting::after, .fa-duotone.fa-american-sign-language-interpreting::after {content: "\f2a3\f2a3";}.fad.fa-asl-interpreting::after, .fa-duotone.fa-asl-interpreting::after {content: "\f2a3\f2a3";}.fad.fa-hands-american-sign-language-interpreting::after, .fa-duotone.fa-hands-american-sign-language-interpreting::after {content: "\f2a3\f2a3";}.fad.fa-hands-bound::after, .fa-duotone.fa-hands-bound::after {content: "\e4f9\e4f9";}.fad.fa-hands-bubbles::after, .fa-duotone.fa-hands-bubbles::after {content: "\e05e\e05e";}.fad.fa-hands-wash::after, .fa-duotone.fa-hands-wash::after {content: "\e05e\e05e";}.fad.fa-hands-clapping::after, .fa-duotone.fa-hands-clapping::after {content: "\e1a8\e1a8";}.fad.fa-hands-holding::after, .fa-duotone.fa-hands-holding::after {content: "\f4c2\f4c2";}.fad.fa-hands-holding-child::after, .fa-duotone.fa-hands-holding-child::after {content: "\e4fa\e4fa";}.fad.fa-hands-holding-circle::after, .fa-duotone.fa-hands-holding-circle::after {content: "\e4fb\e4fb";}.fad.fa-hands-holding-diamond::after, .fa-duotone.fa-hands-holding-diamond::after {content: "\f47c\f47c";}.fad.fa-hand-receiving::after, .fa-duotone.fa-hand-receiving::after {content: "\f47c\f47c";}.fad.fa-hands-holding-dollar::after, .fa-duotone.fa-hands-holding-dollar::after {content: "\f4c5\f4c5";}.fad.fa-hands-usd::after, .fa-duotone.fa-hands-usd::after {content: "\f4c5\f4c5";}.fad.fa-hands-holding-heart::after, .fa-duotone.fa-hands-holding-heart::after {content: "\f4c3\f4c3";}.fad.fa-hands-heart::after, .fa-duotone.fa-hands-heart::after {content: "\f4c3\f4c3";}.fad.fa-hands-praying::after, .fa-duotone.fa-hands-praying::after {content: "\f684\f684";}.fad.fa-praying-hands::after, .fa-duotone.fa-praying-hands::after {content: "\f684\f684";}.fad.fa-handshake::after, .fa-duotone.fa-handshake::after {content: "\f2b5\f2b5";}.fad.fa-handshake-angle::after, .fa-duotone.fa-handshake-angle::after {content: "\f4c4\f4c4";}.fad.fa-hands-helping::after, .fa-duotone.fa-hands-helping::after {content: "\f4c4\f4c4";}.fad.fa-handshake-simple::after, .fa-duotone.fa-handshake-simple::after {content: "\f4c6\f4c6";}.fad.fa-handshake-alt::after, .fa-duotone.fa-handshake-alt::after {content: "\f4c6\f4c6";}.fad.fa-handshake-simple-slash::after, .fa-duotone.fa-handshake-simple-slash::after {content: "\e05f\e05f";}.fad.fa-handshake-alt-slash::after, .fa-duotone.fa-handshake-alt-slash::after {content: "\e05f\e05f";}.fad.fa-handshake-slash::after, .fa-duotone.fa-handshake-slash::after {content: "\e060\e060";}.fad.fa-hanukiah::after, .fa-duotone.fa-hanukiah::after {content: "\f6e6\f6e6";}.fad.fa-hard-drive::after, .fa-duotone.fa-hard-drive::after {content: "\f0a0\f0a0";}.fad.fa-hdd::after, .fa-duotone.fa-hdd::after {content: "\f0a0\f0a0";}.fad.fa-hashtag::after, .fa-duotone.fa-hashtag::after {content: "\23\23";}.fad.fa-hashtag-lock::after, .fa-duotone.fa-hashtag-lock::after {content: "\e415\e415";}.fad.fa-hat-chef::after, .fa-duotone.fa-hat-chef::after {content: "\f86b\f86b";}.fad.fa-hat-cowboy::after, .fa-duotone.fa-hat-cowboy::after {content: "\f8c0\f8c0";}.fad.fa-hat-cowboy-side::after, .fa-duotone.fa-hat-cowboy-side::after {content: "\f8c1\f8c1";}.fad.fa-hat-santa::after, .fa-duotone.fa-hat-santa::after {content: "\f7a7\f7a7";}.fad.fa-hat-winter::after, .fa-duotone.fa-hat-winter::after {content: "\f7a8\f7a8";}.fad.fa-hat-witch::after, .fa-duotone.fa-hat-witch::after {content: "\f6e7\f6e7";}.fad.fa-hat-wizard::after, .fa-duotone.fa-hat-wizard::after {content: "\f6e8\f6e8";}.fad.fa-head-side::after, .fa-duotone.fa-head-side::after {content: "\f6e9\f6e9";}.fad.fa-head-side-brain::after, .fa-duotone.fa-head-side-brain::after {content: "\f808\f808";}.fad.fa-head-side-cough::after, .fa-duotone.fa-head-side-cough::after {content: "\e061\e061";}.fad.fa-head-side-cough-slash::after, .fa-duotone.fa-head-side-cough-slash::after {content: "\e062\e062";}.fad.fa-head-side-goggles::after, .fa-duotone.fa-head-side-goggles::after {content: "\f6ea\f6ea";}.fad.fa-head-vr::after, .fa-duotone.fa-head-vr::after {content: "\f6ea\f6ea";}.fad.fa-head-side-headphones::after, .fa-duotone.fa-head-side-headphones::after {content: "\f8c2\f8c2";}.fad.fa-head-side-heart::after, .fa-duotone.fa-head-side-heart::after {content: "\e1aa\e1aa";}.fad.fa-head-side-mask::after, .fa-duotone.fa-head-side-mask::after {content: "\e063\e063";}.fad.fa-head-side-medical::after, .fa-duotone.fa-head-side-medical::after {content: "\f809\f809";}.fad.fa-head-side-virus::after, .fa-duotone.fa-head-side-virus::after {content: "\e064\e064";}.fad.fa-heading::after, .fa-duotone.fa-heading::after {content: "\f1dc\f1dc";}.fad.fa-header::after, .fa-duotone.fa-header::after {content: "\f1dc\f1dc";}.fad.fa-headphones::after, .fa-duotone.fa-headphones::after {content: "\f025\f025";}.fad.fa-headphones-simple::after, .fa-duotone.fa-headphones-simple::after {content: "\f58f\f58f";}.fad.fa-headphones-alt::after, .fa-duotone.fa-headphones-alt::after {content: "\f58f\f58f";}.fad.fa-headset::after, .fa-duotone.fa-headset::after {content: "\f590\f590";}.fad.fa-heart::after, .fa-duotone.fa-heart::after {content: "\f004\f004";}.fad.fa-heart-circle-bolt::after, .fa-duotone.fa-heart-circle-bolt::after {content: "\e4fc\e4fc";}.fad.fa-heart-circle-check::after, .fa-duotone.fa-heart-circle-check::after {content: "\e4fd\e4fd";}.fad.fa-heart-circle-exclamation::after, .fa-duotone.fa-heart-circle-exclamation::after {content: "\e4fe\e4fe";}.fad.fa-heart-circle-minus::after, .fa-duotone.fa-heart-circle-minus::after {content: "\e4ff\e4ff";}.fad.fa-heart-circle-plus::after, .fa-duotone.fa-heart-circle-plus::after {content: "\e500\e500";}.fad.fa-heart-circle-xmark::after, .fa-duotone.fa-heart-circle-xmark::after {content: "\e501\e501";}.fad.fa-heart-crack::after, .fa-duotone.fa-heart-crack::after {content: "\f7a9\f7a9";}.fad.fa-heart-broken::after, .fa-duotone.fa-heart-broken::after {content: "\f7a9\f7a9";}.fad.fa-heart-half::after, .fa-duotone.fa-heart-half::after {content: "\e1ab\e1ab";}.fad.fa-heart-half-stroke::after, .fa-duotone.fa-heart-half-stroke::after {content: "\e1ac\e1ac";}.fad.fa-heart-half-alt::after, .fa-duotone.fa-heart-half-alt::after {content: "\e1ac\e1ac";}.fad.fa-heart-pulse::after, .fa-duotone.fa-heart-pulse::after {content: "\f21e\f21e";}.fad.fa-heartbeat::after, .fa-duotone.fa-heartbeat::after {content: "\f21e\f21e";}.fad.fa-heat::after, .fa-duotone.fa-heat::after {content: "\e00c\e00c";}.fad.fa-helicopter::after, .fa-duotone.fa-helicopter::after {content: "\f533\f533";}.fad.fa-helicopter-symbol::after, .fa-duotone.fa-helicopter-symbol::after {content: "\e502\e502";}.fad.fa-helmet-battle::after, .fa-duotone.fa-helmet-battle::after {content: "\f6eb\f6eb";}.fad.fa-helmet-safety::after, .fa-duotone.fa-helmet-safety::after {content: "\f807\f807";}.fad.fa-hard-hat::after, .fa-duotone.fa-hard-hat::after {content: "\f807\f807";}.fad.fa-hat-hard::after, .fa-duotone.fa-hat-hard::after {content: "\f807\f807";}.fad.fa-helmet-un::after, .fa-duotone.fa-helmet-un::after {content: "\e503\e503";}.fad.fa-hexagon::after, .fa-duotone.fa-hexagon::after {content: "\f312\f312";}.fad.fa-hexagon-check::after, .fa-duotone.fa-hexagon-check::after {content: "\e416\e416";}.fad.fa-hexagon-divide::after, .fa-duotone.fa-hexagon-divide::after {content: "\e1ad\e1ad";}.fad.fa-hexagon-exclamation::after, .fa-duotone.fa-hexagon-exclamation::after {content: "\e417\e417";}.fad.fa-hexagon-image::after, .fa-duotone.fa-hexagon-image::after {content: "\e504\e504";}.fad.fa-hexagon-minus::after, .fa-duotone.fa-hexagon-minus::after {content: "\f307\f307";}.fad.fa-minus-hexagon::after, .fa-duotone.fa-minus-hexagon::after {content: "\f307\f307";}.fad.fa-hexagon-plus::after, .fa-duotone.fa-hexagon-plus::after {content: "\f300\f300";}.fad.fa-plus-hexagon::after, .fa-duotone.fa-plus-hexagon::after {content: "\f300\f300";}.fad.fa-hexagon-vertical-nft::after, .fa-duotone.fa-hexagon-vertical-nft::after {content: "\e505\e505";}.fad.fa-hexagon-vertical-nft-slanted::after, .fa-duotone.fa-hexagon-vertical-nft-slanted::after {content: "\e506\e506";}.fad.fa-hexagon-xmark::after, .fa-duotone.fa-hexagon-xmark::after {content: "\f2ee\f2ee";}.fad.fa-times-hexagon::after, .fa-duotone.fa-times-hexagon::after {content: "\f2ee\f2ee";}.fad.fa-xmark-hexagon::after, .fa-duotone.fa-xmark-hexagon::after {content: "\f2ee\f2ee";}.fad.fa-high-definition::after, .fa-duotone.fa-high-definition::after {content: "\e1ae\e1ae";}.fad.fa-rectangle-hd::after, .fa-duotone.fa-rectangle-hd::after {content: "\e1ae\e1ae";}.fad.fa-highlighter::after, .fa-duotone.fa-highlighter::after {content: "\f591\f591";}.fad.fa-highlighter-line::after, .fa-duotone.fa-highlighter-line::after {content: "\e1af\e1af";}.fad.fa-hill-avalanche::after, .fa-duotone.fa-hill-avalanche::after {content: "\e507\e507";}.fad.fa-hill-rockslide::after, .fa-duotone.fa-hill-rockslide::after {content: "\e508\e508";}.fad.fa-hippo::after, .fa-duotone.fa-hippo::after {content: "\f6ed\f6ed";}.fad.fa-hockey-mask::after, .fa-duotone.fa-hockey-mask::after {content: "\f6ee\f6ee";}.fad.fa-hockey-puck::after, .fa-duotone.fa-hockey-puck::after {content: "\f453\f453";}.fad.fa-hockey-stick-puck::after, .fa-duotone.fa-hockey-stick-puck::after {content: "\e3ae\e3ae";}.fad.fa-hockey-sticks::after, .fa-duotone.fa-hockey-sticks::after {content: "\f454\f454";}.fad.fa-holly-berry::after, .fa-duotone.fa-holly-berry::after {content: "\f7aa\f7aa";}.fad.fa-honey-pot::after, .fa-duotone.fa-honey-pot::after {content: "\e418\e418";}.fad.fa-hood-cloak::after, .fa-duotone.fa-hood-cloak::after {content: "\f6ef\f6ef";}.fad.fa-horizontal-rule::after, .fa-duotone.fa-horizontal-rule::after {content: "\f86c\f86c";}.fad.fa-horse::after, .fa-duotone.fa-horse::after {content: "\f6f0\f6f0";}.fad.fa-horse-head::after, .fa-duotone.fa-horse-head::after {content: "\f7ab\f7ab";}.fad.fa-horse-saddle::after, .fa-duotone.fa-horse-saddle::after {content: "\f8c3\f8c3";}.fad.fa-hose::after, .fa-duotone.fa-hose::after {content: "\e419\e419";}.fad.fa-hose-reel::after, .fa-duotone.fa-hose-reel::after {content: "\e41a\e41a";}.fad.fa-hospital::after, .fa-duotone.fa-hospital::after {content: "\f0f8\f0f8";}.fad.fa-hospital-alt::after, .fa-duotone.fa-hospital-alt::after {content: "\f0f8\f0f8";}.fad.fa-hospital-wide::after, .fa-duotone.fa-hospital-wide::after {content: "\f0f8\f0f8";}.fad.fa-hospital-user::after, .fa-duotone.fa-hospital-user::after {content: "\f80d\f80d";}.fad.fa-hospitals::after, .fa-duotone.fa-hospitals::after {content: "\f80e\f80e";}.fad.fa-hot-tub-person::after, .fa-duotone.fa-hot-tub-person::after {content: "\f593\f593";}.fad.fa-hot-tub::after, .fa-duotone.fa-hot-tub::after {content: "\f593\f593";}.fad.fa-hotdog::after, .fa-duotone.fa-hotdog::after {content: "\f80f\f80f";}.fad.fa-hotel::after, .fa-duotone.fa-hotel::after {content: "\f594\f594";}.fad.fa-hourglass::after, .fa-duotone.fa-hourglass::after {content: "\f254\f254";}.fad.fa-hourglass-2::after, .fa-duotone.fa-hourglass-2::after {content: "\f254\f254";}.fad.fa-hourglass-half::after, .fa-duotone.fa-hourglass-half::after {content: "\f254\f254";}.fad.fa-hourglass-clock::after, .fa-duotone.fa-hourglass-clock::after {content: "\e41b\e41b";}.fad.fa-hourglass-empty::after, .fa-duotone.fa-hourglass-empty::after {content: "\f252\f252";}.fad.fa-hourglass-end::after, .fa-duotone.fa-hourglass-end::after {content: "\f253\f253";}.fad.fa-hourglass-3::after, .fa-duotone.fa-hourglass-3::after {content: "\f253\f253";}.fad.fa-hourglass-start::after, .fa-duotone.fa-hourglass-start::after {content: "\f251\f251";}.fad.fa-hourglass-1::after, .fa-duotone.fa-hourglass-1::after {content: "\f251\f251";}.fad.fa-house::after, .fa-duotone.fa-house::after {content: "\f015\f015";}.fad.fa-home::after, .fa-duotone.fa-home::after {content: "\f015\f015";}.fad.fa-home-alt::after, .fa-duotone.fa-home-alt::after {content: "\f015\f015";}.fad.fa-home-lg-alt::after, .fa-duotone.fa-home-lg-alt::after {content: "\f015\f015";}.fad.fa-house-blank::after, .fa-duotone.fa-house-blank::after {content: "\e487\e487";}.fad.fa-home-blank::after, .fa-duotone.fa-home-blank::after {content: "\e487\e487";}.fad.fa-house-building::after, .fa-duotone.fa-house-building::after {content: "\e1b1\e1b1";}.fad.fa-house-chimney::after, .fa-duotone.fa-house-chimney::after {content: "\e3af\e3af";}.fad.fa-home-lg::after, .fa-duotone.fa-home-lg::after {content: "\e3af\e3af";}.fad.fa-house-chimney-blank::after, .fa-duotone.fa-house-chimney-blank::after {content: "\e3b0\e3b0";}.fad.fa-house-chimney-crack::after, .fa-duotone.fa-house-chimney-crack::after {content: "\f6f1\f6f1";}.fad.fa-house-damage::after, .fa-duotone.fa-house-damage::after {content: "\f6f1\f6f1";}.fad.fa-house-chimney-heart::after, .fa-duotone.fa-house-chimney-heart::after {content: "\e1b2\e1b2";}.fad.fa-house-chimney-medical::after, .fa-duotone.fa-house-chimney-medical::after {content: "\f7f2\f7f2";}.fad.fa-clinic-medical::after, .fa-duotone.fa-clinic-medical::after {content: "\f7f2\f7f2";}.fad.fa-house-chimney-user::after, .fa-duotone.fa-house-chimney-user::after {content: "\e065\e065";}.fad.fa-house-chimney-window::after, .fa-duotone.fa-house-chimney-window::after {content: "\e00d\e00d";}.fad.fa-house-circle-check::after, .fa-duotone.fa-house-circle-check::after {content: "\e509\e509";}.fad.fa-house-circle-exclamation::after, .fa-duotone.fa-house-circle-exclamation::after {content: "\e50a\e50a";}.fad.fa-house-circle-xmark::after, .fa-duotone.fa-house-circle-xmark::after {content: "\e50b\e50b";}.fad.fa-house-crack::after, .fa-duotone.fa-house-crack::after {content: "\e3b1\e3b1";}.fad.fa-house-day::after, .fa-duotone.fa-house-day::after {content: "\e00e\e00e";}.fad.fa-house-fire::after, .fa-duotone.fa-house-fire::after {content: "\e50c\e50c";}.fad.fa-house-flag::after, .fa-duotone.fa-house-flag::after {content: "\e50d\e50d";}.fad.fa-house-flood-water::after, .fa-duotone.fa-house-flood-water::after {content: "\e50e\e50e";}.fad.fa-house-flood-water-circle-arrow-right::after, .fa-duotone.fa-house-flood-water-circle-arrow-right::after {content: "\e50f\e50f";}.fad.fa-house-heart::after, .fa-duotone.fa-house-heart::after {content: "\f4c9\f4c9";}.fad.fa-home-heart::after, .fa-duotone.fa-home-heart::after {content: "\f4c9\f4c9";}.fad.fa-house-laptop::after, .fa-duotone.fa-house-laptop::after {content: "\e066\e066";}.fad.fa-laptop-house::after, .fa-duotone.fa-laptop-house::after {content: "\e066\e066";}.fad.fa-house-lock::after, .fa-duotone.fa-house-lock::after {content: "\e510\e510";}.fad.fa-house-medical::after, .fa-duotone.fa-house-medical::after {content: "\e3b2\e3b2";}.fad.fa-house-medical-circle-check::after, .fa-duotone.fa-house-medical-circle-check::after {content: "\e511\e511";}.fad.fa-house-medical-circle-exclamation::after, .fa-duotone.fa-house-medical-circle-exclamation::after {content: "\e512\e512";}.fad.fa-house-medical-circle-xmark::after, .fa-duotone.fa-house-medical-circle-xmark::after {content: "\e513\e513";}.fad.fa-house-medical-flag::after, .fa-duotone.fa-house-medical-flag::after {content: "\e514\e514";}.fad.fa-house-night::after, .fa-duotone.fa-house-night::after {content: "\e010\e010";}.fad.fa-house-person-leave::after, .fa-duotone.fa-house-person-leave::after {content: "\e00f\e00f";}.fad.fa-house-leave::after, .fa-duotone.fa-house-leave::after {content: "\e00f\e00f";}.fad.fa-house-person-depart::after, .fa-duotone.fa-house-person-depart::after {content: "\e00f\e00f";}.fad.fa-house-person-return::after, .fa-duotone.fa-house-person-return::after {content: "\e011\e011";}.fad.fa-house-person-arrive::after, .fa-duotone.fa-house-person-arrive::after {content: "\e011\e011";}.fad.fa-house-return::after, .fa-duotone.fa-house-return::after {content: "\e011\e011";}.fad.fa-house-signal::after, .fa-duotone.fa-house-signal::after {content: "\e012\e012";}.fad.fa-house-tree::after, .fa-duotone.fa-house-tree::after {content: "\e1b3\e1b3";}.fad.fa-house-tsunami::after, .fa-duotone.fa-house-tsunami::after {content: "\e515\e515";}.fad.fa-house-turret::after, .fa-duotone.fa-house-turret::after {content: "\e1b4\e1b4";}.fad.fa-house-user::after, .fa-duotone.fa-house-user::after {content: "\e1b0\e1b0";}.fad.fa-home-user::after, .fa-duotone.fa-home-user::after {content: "\e1b0\e1b0";}.fad.fa-house-water::after, .fa-duotone.fa-house-water::after {content: "\f74f\f74f";}.fad.fa-house-flood::after, .fa-duotone.fa-house-flood::after {content: "\f74f\f74f";}.fad.fa-house-window::after, .fa-duotone.fa-house-window::after {content: "\e3b3\e3b3";}.fad.fa-hryvnia-sign::after, .fa-duotone.fa-hryvnia-sign::after {content: "\f6f2\f6f2";}.fad.fa-hryvnia::after, .fa-duotone.fa-hryvnia::after {content: "\f6f2\f6f2";}.fad.fa-hundred-points::after, .fa-duotone.fa-hundred-points::after {content: "\e41c\e41c";}.fad.fa-100::after, .fa-duotone.fa-100::after {content: "\e41c\e41c";}.fad.fa-hurricane::after, .fa-duotone.fa-hurricane::after {content: "\f751\f751";}.fad.fa-hyphen::after, .fa-duotone.fa-hyphen::after {content: "\2d\2d";}.fad.fa-i::after, .fa-duotone.fa-i::after {content: "\49\49";}.fad.fa-i-cursor::after, .fa-duotone.fa-i-cursor::after {content: "\f246\f246";}.fad.fa-ice-cream::after, .fa-duotone.fa-ice-cream::after {content: "\f810\f810";}.fad.fa-ice-skate::after, .fa-duotone.fa-ice-skate::after {content: "\f7ac\f7ac";}.fad.fa-icicles::after, .fa-duotone.fa-icicles::after {content: "\f7ad\f7ad";}.fad.fa-icons::after, .fa-duotone.fa-icons::after {content: "\f86d\f86d";}.fad.fa-heart-music-camera-bolt::after, .fa-duotone.fa-heart-music-camera-bolt::after {content: "\f86d\f86d";}.fad.fa-id-badge::after, .fa-duotone.fa-id-badge::after {content: "\f2c1\f2c1";}.fad.fa-id-card::after, .fa-duotone.fa-id-card::after {content: "\f2c2\f2c2";}.fad.fa-drivers-license::after, .fa-duotone.fa-drivers-license::after {content: "\f2c2\f2c2";}.fad.fa-id-card-clip::after, .fa-duotone.fa-id-card-clip::after {content: "\f47f\f47f";}.fad.fa-id-card-alt::after, .fa-duotone.fa-id-card-alt::after {content: "\f47f\f47f";}.fad.fa-igloo::after, .fa-duotone.fa-igloo::after {content: "\f7ae\f7ae";}.fad.fa-image::after, .fa-duotone.fa-image::after {content: "\f03e\f03e";}.fad.fa-image-landscape::after, .fa-duotone.fa-image-landscape::after {content: "\e1b5\e1b5";}.fad.fa-landscape::after, .fa-duotone.fa-landscape::after {content: "\e1b5\e1b5";}.fad.fa-image-polaroid::after, .fa-duotone.fa-image-polaroid::after {content: "\f8c4\f8c4";}.fad.fa-image-polaroid-user::after, .fa-duotone.fa-image-polaroid-user::after {content: "\e1b6\e1b6";}.fad.fa-image-portrait::after, .fa-duotone.fa-image-portrait::after {content: "\f3e0\f3e0";}.fad.fa-portrait::after, .fa-duotone.fa-portrait::after {content: "\f3e0\f3e0";}.fad.fa-image-slash::after, .fa-duotone.fa-image-slash::after {content: "\e1b7\e1b7";}.fad.fa-image-user::after, .fa-duotone.fa-image-user::after {content: "\e1b8\e1b8";}.fad.fa-images::after, .fa-duotone.fa-images::after {content: "\f302\f302";}.fad.fa-images-user::after, .fa-duotone.fa-images-user::after {content: "\e1b9\e1b9";}.fad.fa-inbox::after, .fa-duotone.fa-inbox::after {content: "\f01c\f01c";}.fad.fa-inbox-full::after, .fa-duotone.fa-inbox-full::after {content: "\e1ba\e1ba";}.fad.fa-inbox-in::after, .fa-duotone.fa-inbox-in::after {content: "\f310\f310";}.fad.fa-inbox-arrow-down::after, .fa-duotone.fa-inbox-arrow-down::after {content: "\f310\f310";}.fad.fa-inbox-out::after, .fa-duotone.fa-inbox-out::after {content: "\f311\f311";}.fad.fa-inbox-arrow-up::after, .fa-duotone.fa-inbox-arrow-up::after {content: "\f311\f311";}.fad.fa-inboxes::after, .fa-duotone.fa-inboxes::after {content: "\e1bb\e1bb";}.fad.fa-indent::after, .fa-duotone.fa-indent::after {content: "\f03c\f03c";}.fad.fa-indian-rupee-sign::after, .fa-duotone.fa-indian-rupee-sign::after {content: "\e1bc\e1bc";}.fad.fa-indian-rupee::after, .fa-duotone.fa-indian-rupee::after {content: "\e1bc\e1bc";}.fad.fa-inr::after, .fa-duotone.fa-inr::after {content: "\e1bc\e1bc";}.fad.fa-industry::after, .fa-duotone.fa-industry::after {content: "\f275\f275";}.fad.fa-industry-windows::after, .fa-duotone.fa-industry-windows::after {content: "\f3b3\f3b3";}.fad.fa-industry-alt::after, .fa-duotone.fa-industry-alt::after {content: "\f3b3\f3b3";}.fad.fa-infinity::after, .fa-duotone.fa-infinity::after {content: "\f534\f534";}.fad.fa-info::after, .fa-duotone.fa-info::after {content: "\f129\f129";}.fad.fa-inhaler::after, .fa-duotone.fa-inhaler::after {content: "\f5f9\f5f9";}.fad.fa-input-numeric::after, .fa-duotone.fa-input-numeric::after {content: "\e1bd\e1bd";}.fad.fa-input-pipe::after, .fa-duotone.fa-input-pipe::after {content: "\e1be\e1be";}.fad.fa-input-text::after, .fa-duotone.fa-input-text::after {content: "\e1bf\e1bf";}.fad.fa-integral::after, .fa-duotone.fa-integral::after {content: "\f667\f667";}.fad.fa-intersection::after, .fa-duotone.fa-intersection::after {content: "\f668\f668";}.fad.fa-island-tropical::after, .fa-duotone.fa-island-tropical::after {content: "\f811\f811";}.fad.fa-island-tree-palm::after, .fa-duotone.fa-island-tree-palm::after {content: "\f811\f811";}.fad.fa-italic::after, .fa-duotone.fa-italic::after {content: "\f033\f033";}.fad.fa-j::after, .fa-duotone.fa-j::after {content: "\4a\4a";}.fad.fa-jack-o-lantern::after, .fa-duotone.fa-jack-o-lantern::after {content: "\f30e\f30e";}.fad.fa-jar::after, .fa-duotone.fa-jar::after {content: "\e516\e516";}.fad.fa-jar-wheat::after, .fa-duotone.fa-jar-wheat::after {content: "\e517\e517";}.fad.fa-jedi::after, .fa-duotone.fa-jedi::after {content: "\f669\f669";}.fad.fa-jet-fighter::after, .fa-duotone.fa-jet-fighter::after {content: "\f0fb\f0fb";}.fad.fa-fighter-jet::after, .fa-duotone.fa-fighter-jet::after {content: "\f0fb\f0fb";}.fad.fa-jet-fighter-up::after, .fa-duotone.fa-jet-fighter-up::after {content: "\e518\e518";}.fad.fa-joint::after, .fa-duotone.fa-joint::after {content: "\f595\f595";}.fad.fa-joystick::after, .fa-duotone.fa-joystick::after {content: "\f8c5\f8c5";}.fad.fa-jug::after, .fa-duotone.fa-jug::after {content: "\f8c6\f8c6";}.fad.fa-jug-detergent::after, .fa-duotone.fa-jug-detergent::after {content: "\e519\e519";}.fad.fa-k::after, .fa-duotone.fa-k::after {content: "\4b\4b";}.fad.fa-kaaba::after, .fa-duotone.fa-kaaba::after {content: "\f66b\f66b";}.fad.fa-kazoo::after, .fa-duotone.fa-kazoo::after {content: "\f8c7\f8c7";}.fad.fa-kerning::after, .fa-duotone.fa-kerning::after {content: "\f86f\f86f";}.fad.fa-key::after, .fa-duotone.fa-key::after {content: "\f084\f084";}.fad.fa-key-skeleton::after, .fa-duotone.fa-key-skeleton::after {content: "\f6f3\f6f3";}.fad.fa-key-skeleton-left-right::after, .fa-duotone.fa-key-skeleton-left-right::after {content: "\e3b4\e3b4";}.fad.fa-keyboard::after, .fa-duotone.fa-keyboard::after {content: "\f11c\f11c";}.fad.fa-keyboard-brightness::after, .fa-duotone.fa-keyboard-brightness::after {content: "\e1c0\e1c0";}.fad.fa-keyboard-brightness-low::after, .fa-duotone.fa-keyboard-brightness-low::after {content: "\e1c1\e1c1";}.fad.fa-keyboard-down::after, .fa-duotone.fa-keyboard-down::after {content: "\e1c2\e1c2";}.fad.fa-keyboard-left::after, .fa-duotone.fa-keyboard-left::after {content: "\e1c3\e1c3";}.fad.fa-keynote::after, .fa-duotone.fa-keynote::after {content: "\f66c\f66c";}.fad.fa-khanda::after, .fa-duotone.fa-khanda::after {content: "\f66d\f66d";}.fad.fa-kidneys::after, .fa-duotone.fa-kidneys::after {content: "\f5fb\f5fb";}.fad.fa-kip-sign::after, .fa-duotone.fa-kip-sign::after {content: "\e1c4\e1c4";}.fad.fa-kit-medical::after, .fa-duotone.fa-kit-medical::after {content: "\f479\f479";}.fad.fa-first-aid::after, .fa-duotone.fa-first-aid::after {content: "\f479\f479";}.fad.fa-kitchen-set::after, .fa-duotone.fa-kitchen-set::after {content: "\e51a\e51a";}.fad.fa-kite::after, .fa-duotone.fa-kite::after {content: "\f6f4\f6f4";}.fad.fa-kiwi-bird::after, .fa-duotone.fa-kiwi-bird::after {content: "\f535\f535";}.fad.fa-kiwi-fruit::after, .fa-duotone.fa-kiwi-fruit::after {content: "\e30c\e30c";}.fad.fa-knife::after, .fa-duotone.fa-knife::after {content: "\f2e4\f2e4";}.fad.fa-utensil-knife::after, .fa-duotone.fa-utensil-knife::after {content: "\f2e4\f2e4";}.fad.fa-knife-kitchen::after, .fa-duotone.fa-knife-kitchen::after {content: "\f6f5\f6f5";}.fad.fa-l::after, .fa-duotone.fa-l::after {content: "\4c\4c";}.fad.fa-lacrosse-stick::after, .fa-duotone.fa-lacrosse-stick::after {content: "\e3b5\e3b5";}.fad.fa-lacrosse-stick-ball::after, .fa-duotone.fa-lacrosse-stick-ball::after {content: "\e3b6\e3b6";}.fad.fa-lambda::after, .fa-duotone.fa-lambda::after {content: "\f66e\f66e";}.fad.fa-lamp::after, .fa-duotone.fa-lamp::after {content: "\f4ca\f4ca";}.fad.fa-lamp-desk::after, .fa-duotone.fa-lamp-desk::after {content: "\e014\e014";}.fad.fa-lamp-floor::after, .fa-duotone.fa-lamp-floor::after {content: "\e015\e015";}.fad.fa-lamp-street::after, .fa-duotone.fa-lamp-street::after {content: "\e1c5\e1c5";}.fad.fa-land-mine-on::after, .fa-duotone.fa-land-mine-on::after {content: "\e51b\e51b";}.fad.fa-landmark::after, .fa-duotone.fa-landmark::after {content: "\f66f\f66f";}.fad.fa-landmark-dome::after, .fa-duotone.fa-landmark-dome::after {content: "\f752\f752";}.fad.fa-landmark-alt::after, .fa-duotone.fa-landmark-alt::after {content: "\f752\f752";}.fad.fa-landmark-flag::after, .fa-duotone.fa-landmark-flag::after {content: "\e51c\e51c";}.fad.fa-language::after, .fa-duotone.fa-language::after {content: "\f1ab\f1ab";}.fad.fa-laptop::after, .fa-duotone.fa-laptop::after {content: "\f109\f109";}.fad.fa-laptop-arrow-down::after, .fa-duotone.fa-laptop-arrow-down::after {content: "\e1c6\e1c6";}.fad.fa-laptop-code::after, .fa-duotone.fa-laptop-code::after {content: "\f5fc\f5fc";}.fad.fa-laptop-file::after, .fa-duotone.fa-laptop-file::after {content: "\e51d\e51d";}.fad.fa-laptop-medical::after, .fa-duotone.fa-laptop-medical::after {content: "\f812\f812";}.fad.fa-laptop-mobile::after, .fa-duotone.fa-laptop-mobile::after {content: "\f87a\f87a";}.fad.fa-phone-laptop::after, .fa-duotone.fa-phone-laptop::after {content: "\f87a\f87a";}.fad.fa-laptop-slash::after, .fa-duotone.fa-laptop-slash::after {content: "\e1c7\e1c7";}.fad.fa-lari-sign::after, .fa-duotone.fa-lari-sign::after {content: "\e1c8\e1c8";}.fad.fa-lasso::after, .fa-duotone.fa-lasso::after {content: "\f8c8\f8c8";}.fad.fa-lasso-sparkles::after, .fa-duotone.fa-lasso-sparkles::after {content: "\e1c9\e1c9";}.fad.fa-layer-group::after, .fa-duotone.fa-layer-group::after {content: "\f5fd\f5fd";}.fad.fa-layer-minus::after, .fa-duotone.fa-layer-minus::after {content: "\f5fe\f5fe";}.fad.fa-layer-group-minus::after, .fa-duotone.fa-layer-group-minus::after {content: "\f5fe\f5fe";}.fad.fa-layer-plus::after, .fa-duotone.fa-layer-plus::after {content: "\f5ff\f5ff";}.fad.fa-layer-group-plus::after, .fa-duotone.fa-layer-group-plus::after {content: "\f5ff\f5ff";}.fad.fa-leaf::after, .fa-duotone.fa-leaf::after {content: "\f06c\f06c";}.fad.fa-leaf-heart::after, .fa-duotone.fa-leaf-heart::after {content: "\f4cb\f4cb";}.fad.fa-leaf-maple::after, .fa-duotone.fa-leaf-maple::after {content: "\f6f6\f6f6";}.fad.fa-leaf-oak::after, .fa-duotone.fa-leaf-oak::after {content: "\f6f7\f6f7";}.fad.fa-leafy-green::after, .fa-duotone.fa-leafy-green::after {content: "\e41d\e41d";}.fad.fa-left::after, .fa-duotone.fa-left::after {content: "\f355\f355";}.fad.fa-arrow-alt-left::after, .fa-duotone.fa-arrow-alt-left::after {content: "\f355\f355";}.fad.fa-left-from-line::after, .fa-duotone.fa-left-from-line::after {content: "\f348\f348";}.fad.fa-arrow-alt-from-right::after, .fa-duotone.fa-arrow-alt-from-right::after {content: "\f348\f348";}.fad.fa-left-long::after, .fa-duotone.fa-left-long::after {content: "\f30a\f30a";}.fad.fa-long-arrow-alt-left::after, .fa-duotone.fa-long-arrow-alt-left::after {content: "\f30a\f30a";}.fad.fa-left-long-to-line::after, .fa-duotone.fa-left-long-to-line::after {content: "\e41e\e41e";}.fad.fa-left-right::after, .fa-duotone.fa-left-right::after {content: "\f337\f337";}.fad.fa-arrows-alt-h::after, .fa-duotone.fa-arrows-alt-h::after {content: "\f337\f337";}.fad.fa-left-to-line::after, .fa-duotone.fa-left-to-line::after {content: "\f34b\f34b";}.fad.fa-arrow-alt-to-left::after, .fa-duotone.fa-arrow-alt-to-left::after {content: "\f34b\f34b";}.fad.fa-lemon::after, .fa-duotone.fa-lemon::after {content: "\f094\f094";}.fad.fa-less-than::after, .fa-duotone.fa-less-than::after {content: "\3c\3c";}.fad.fa-less-than-equal::after, .fa-duotone.fa-less-than-equal::after {content: "\f537\f537";}.fad.fa-life-ring::after, .fa-duotone.fa-life-ring::after {content: "\f1cd\f1cd";}.fad.fa-light-ceiling::after, .fa-duotone.fa-light-ceiling::after {content: "\e016\e016";}.fad.fa-light-emergency::after, .fa-duotone.fa-light-emergency::after {content: "\e41f\e41f";}.fad.fa-light-emergency-on::after, .fa-duotone.fa-light-emergency-on::after {content: "\e420\e420";}.fad.fa-light-switch::after, .fa-duotone.fa-light-switch::after {content: "\e017\e017";}.fad.fa-light-switch-off::after, .fa-duotone.fa-light-switch-off::after {content: "\e018\e018";}.fad.fa-light-switch-on::after, .fa-duotone.fa-light-switch-on::after {content: "\e019\e019";}.fad.fa-lightbulb::after, .fa-duotone.fa-lightbulb::after {content: "\f0eb\f0eb";}.fad.fa-lightbulb-dollar::after, .fa-duotone.fa-lightbulb-dollar::after {content: "\f670\f670";}.fad.fa-lightbulb-exclamation::after, .fa-duotone.fa-lightbulb-exclamation::after {content: "\f671\f671";}.fad.fa-lightbulb-exclamation-on::after, .fa-duotone.fa-lightbulb-exclamation-on::after {content: "\e1ca\e1ca";}.fad.fa-lightbulb-on::after, .fa-duotone.fa-lightbulb-on::after {content: "\f672\f672";}.fad.fa-lightbulb-slash::after, .fa-duotone.fa-lightbulb-slash::after {content: "\f673\f673";}.fad.fa-lights-holiday::after, .fa-duotone.fa-lights-holiday::after {content: "\f7b2\f7b2";}.fad.fa-line-columns::after, .fa-duotone.fa-line-columns::after {content: "\f870\f870";}.fad.fa-line-height::after, .fa-duotone.fa-line-height::after {content: "\f871\f871";}.fad.fa-lines-leaning::after, .fa-duotone.fa-lines-leaning::after {content: "\e51e\e51e";}.fad.fa-link::after, .fa-duotone.fa-link::after {content: "\f0c1\f0c1";}.fad.fa-chain::after, .fa-duotone.fa-chain::after {content: "\f0c1\f0c1";}.fad.fa-link-horizontal::after, .fa-duotone.fa-link-horizontal::after {content: "\e1cb\e1cb";}.fad.fa-chain-horizontal::after, .fa-duotone.fa-chain-horizontal::after {content: "\e1cb\e1cb";}.fad.fa-link-horizontal-slash::after, .fa-duotone.fa-link-horizontal-slash::after {content: "\e1cc\e1cc";}.fad.fa-chain-horizontal-slash::after, .fa-duotone.fa-chain-horizontal-slash::after {content: "\e1cc\e1cc";}.fad.fa-link-simple::after, .fa-duotone.fa-link-simple::after {content: "\e1cd\e1cd";}.fad.fa-link-simple-slash::after, .fa-duotone.fa-link-simple-slash::after {content: "\e1ce\e1ce";}.fad.fa-link-slash::after, .fa-duotone.fa-link-slash::after {content: "\f127\f127";}.fad.fa-chain-broken::after, .fa-duotone.fa-chain-broken::after {content: "\f127\f127";}.fad.fa-chain-slash::after, .fa-duotone.fa-chain-slash::after {content: "\f127\f127";}.fad.fa-unlink::after, .fa-duotone.fa-unlink::after {content: "\f127\f127";}.fad.fa-lips::after, .fa-duotone.fa-lips::after {content: "\f600\f600";}.fad.fa-lira-sign::after, .fa-duotone.fa-lira-sign::after {content: "\f195\f195";}.fad.fa-list::after, .fa-duotone.fa-list::after {content: "\f03a\f03a";}.fad.fa-list-squares::after, .fa-duotone.fa-list-squares::after {content: "\f03a\f03a";}.fad.fa-list-check::after, .fa-duotone.fa-list-check::after {content: "\f0ae\f0ae";}.fad.fa-tasks::after, .fa-duotone.fa-tasks::after {content: "\f0ae\f0ae";}.fad.fa-list-dropdown::after, .fa-duotone.fa-list-dropdown::after {content: "\e1cf\e1cf";}.fad.fa-list-music::after, .fa-duotone.fa-list-music::after {content: "\f8c9\f8c9";}.fad.fa-list-ol::after, .fa-duotone.fa-list-ol::after {content: "\f0cb\f0cb";}.fad.fa-list-1-2::after, .fa-duotone.fa-list-1-2::after {content: "\f0cb\f0cb";}.fad.fa-list-numeric::after, .fa-duotone.fa-list-numeric::after {content: "\f0cb\f0cb";}.fad.fa-list-radio::after, .fa-duotone.fa-list-radio::after {content: "\e1d0\e1d0";}.fad.fa-list-timeline::after, .fa-duotone.fa-list-timeline::after {content: "\e1d1\e1d1";}.fad.fa-list-tree::after, .fa-duotone.fa-list-tree::after {content: "\e1d2\e1d2";}.fad.fa-list-ul::after, .fa-duotone.fa-list-ul::after {content: "\f0ca\f0ca";}.fad.fa-list-dots::after, .fa-duotone.fa-list-dots::after {content: "\f0ca\f0ca";}.fad.fa-litecoin-sign::after, .fa-duotone.fa-litecoin-sign::after {content: "\e1d3\e1d3";}.fad.fa-loader::after, .fa-duotone.fa-loader::after {content: "\e1d4\e1d4";}.fad.fa-lobster::after, .fa-duotone.fa-lobster::after {content: "\e421\e421";}.fad.fa-location-arrow::after, .fa-duotone.fa-location-arrow::after {content: "\f124\f124";}.fad.fa-location-check::after, .fa-duotone.fa-location-check::after {content: "\f606\f606";}.fad.fa-map-marker-check::after, .fa-duotone.fa-map-marker-check::after {content: "\f606\f606";}.fad.fa-location-crosshairs::after, .fa-duotone.fa-location-crosshairs::after {content: "\f601\f601";}.fad.fa-location::after, .fa-duotone.fa-location::after {content: "\f601\f601";}.fad.fa-location-crosshairs-slash::after, .fa-duotone.fa-location-crosshairs-slash::after {content: "\f603\f603";}.fad.fa-location-slash::after, .fa-duotone.fa-location-slash::after {content: "\f603\f603";}.fad.fa-location-dot::after, .fa-duotone.fa-location-dot::after {content: "\f3c5\f3c5";}.fad.fa-map-marker-alt::after, .fa-duotone.fa-map-marker-alt::after {content: "\f3c5\f3c5";}.fad.fa-location-dot-slash::after, .fa-duotone.fa-location-dot-slash::after {content: "\f605\f605";}.fad.fa-map-marker-alt-slash::after, .fa-duotone.fa-map-marker-alt-slash::after {content: "\f605\f605";}.fad.fa-location-exclamation::after, .fa-duotone.fa-location-exclamation::after {content: "\f608\f608";}.fad.fa-map-marker-exclamation::after, .fa-duotone.fa-map-marker-exclamation::after {content: "\f608\f608";}.fad.fa-location-minus::after, .fa-duotone.fa-location-minus::after {content: "\f609\f609";}.fad.fa-map-marker-minus::after, .fa-duotone.fa-map-marker-minus::after {content: "\f609\f609";}.fad.fa-location-pen::after, .fa-duotone.fa-location-pen::after {content: "\f607\f607";}.fad.fa-map-marker-edit::after, .fa-duotone.fa-map-marker-edit::after {content: "\f607\f607";}.fad.fa-location-pin::after, .fa-duotone.fa-location-pin::after {content: "\f041\f041";}.fad.fa-map-marker::after, .fa-duotone.fa-map-marker::after {content: "\f041\f041";}.fad.fa-location-pin-lock::after, .fa-duotone.fa-location-pin-lock::after {content: "\e51f\e51f";}.fad.fa-location-pin-slash::after, .fa-duotone.fa-location-pin-slash::after {content: "\f60c\f60c";}.fad.fa-map-marker-slash::after, .fa-duotone.fa-map-marker-slash::after {content: "\f60c\f60c";}.fad.fa-location-plus::after, .fa-duotone.fa-location-plus::after {content: "\f60a\f60a";}.fad.fa-map-marker-plus::after, .fa-duotone.fa-map-marker-plus::after {content: "\f60a\f60a";}.fad.fa-location-question::after, .fa-duotone.fa-location-question::after {content: "\f60b\f60b";}.fad.fa-map-marker-question::after, .fa-duotone.fa-map-marker-question::after {content: "\f60b\f60b";}.fad.fa-location-smile::after, .fa-duotone.fa-location-smile::after {content: "\f60d\f60d";}.fad.fa-map-marker-smile::after, .fa-duotone.fa-map-marker-smile::after {content: "\f60d\f60d";}.fad.fa-location-xmark::after, .fa-duotone.fa-location-xmark::after {content: "\f60e\f60e";}.fad.fa-map-marker-times::after, .fa-duotone.fa-map-marker-times::after {content: "\f60e\f60e";}.fad.fa-map-marker-xmark::after, .fa-duotone.fa-map-marker-xmark::after {content: "\f60e\f60e";}.fad.fa-lock::after, .fa-duotone.fa-lock::after {content: "\f023\f023";}.fad.fa-lock-a::after, .fa-duotone.fa-lock-a::after {content: "\e422\e422";}.fad.fa-lock-hashtag::after, .fa-duotone.fa-lock-hashtag::after {content: "\e423\e423";}.fad.fa-lock-keyhole::after, .fa-duotone.fa-lock-keyhole::after {content: "\f30d\f30d";}.fad.fa-lock-alt::after, .fa-duotone.fa-lock-alt::after {content: "\f30d\f30d";}.fad.fa-lock-keyhole-open::after, .fa-duotone.fa-lock-keyhole-open::after {content: "\f3c2\f3c2";}.fad.fa-lock-open-alt::after, .fa-duotone.fa-lock-open-alt::after {content: "\f3c2\f3c2";}.fad.fa-lock-open::after, .fa-duotone.fa-lock-open::after {content: "\f3c1\f3c1";}.fad.fa-locust::after, .fa-duotone.fa-locust::after {content: "\e520\e520";}.fad.fa-lollipop::after, .fa-duotone.fa-lollipop::after {content: "\e424\e424";}.fad.fa-lollypop::after, .fa-duotone.fa-lollypop::after {content: "\e424\e424";}.fad.fa-loveseat::after, .fa-duotone.fa-loveseat::after {content: "\f4cc\f4cc";}.fad.fa-couch-small::after, .fa-duotone.fa-couch-small::after {content: "\f4cc\f4cc";}.fad.fa-luchador-mask::after, .fa-duotone.fa-luchador-mask::after {content: "\f455\f455";}.fad.fa-luchador::after, .fa-duotone.fa-luchador::after {content: "\f455\f455";}.fad.fa-mask-luchador::after, .fa-duotone.fa-mask-luchador::after {content: "\f455\f455";}.fad.fa-lungs::after, .fa-duotone.fa-lungs::after {content: "\f604\f604";}.fad.fa-lungs-virus::after, .fa-duotone.fa-lungs-virus::after {content: "\e067\e067";}.fad.fa-m::after, .fa-duotone.fa-m::after {content: "\4d\4d";}.fad.fa-mace::after, .fa-duotone.fa-mace::after {content: "\f6f8\f6f8";}.fad.fa-magnet::after, .fa-duotone.fa-magnet::after {content: "\f076\f076";}.fad.fa-magnifying-glass::after, .fa-duotone.fa-magnifying-glass::after {content: "\f002\f002";}.fad.fa-search::after, .fa-duotone.fa-search::after {content: "\f002\f002";}.fad.fa-magnifying-glass-arrow-right::after, .fa-duotone.fa-magnifying-glass-arrow-right::after {content: "\e521\e521";}.fad.fa-magnifying-glass-chart::after, .fa-duotone.fa-magnifying-glass-chart::after {content: "\e522\e522";}.fad.fa-magnifying-glass-dollar::after, .fa-duotone.fa-magnifying-glass-dollar::after {content: "\f688\f688";}.fad.fa-search-dollar::after, .fa-duotone.fa-search-dollar::after {content: "\f688\f688";}.fad.fa-magnifying-glass-location::after, .fa-duotone.fa-magnifying-glass-location::after {content: "\f689\f689";}.fad.fa-search-location::after, .fa-duotone.fa-search-location::after {content: "\f689\f689";}.fad.fa-magnifying-glass-minus::after, .fa-duotone.fa-magnifying-glass-minus::after {content: "\f010\f010";}.fad.fa-search-minus::after, .fa-duotone.fa-search-minus::after {content: "\f010\f010";}.fad.fa-magnifying-glass-plus::after, .fa-duotone.fa-magnifying-glass-plus::after {content: "\f00e\f00e";}.fad.fa-search-plus::after, .fa-duotone.fa-search-plus::after {content: "\f00e\f00e";}.fad.fa-mailbox::after, .fa-duotone.fa-mailbox::after {content: "\f813\f813";}.fad.fa-manat-sign::after, .fa-duotone.fa-manat-sign::after {content: "\e1d5\e1d5";}.fad.fa-mandolin::after, .fa-duotone.fa-mandolin::after {content: "\f6f9\f6f9";}.fad.fa-mango::after, .fa-duotone.fa-mango::after {content: "\e30f\e30f";}.fad.fa-manhole::after, .fa-duotone.fa-manhole::after {content: "\e1d6\e1d6";}.fad.fa-map::after, .fa-duotone.fa-map::after {content: "\f279\f279";}.fad.fa-map-location::after, .fa-duotone.fa-map-location::after {content: "\f59f\f59f";}.fad.fa-map-marked::after, .fa-duotone.fa-map-marked::after {content: "\f59f\f59f";}.fad.fa-map-location-dot::after, .fa-duotone.fa-map-location-dot::after {content: "\f5a0\f5a0";}.fad.fa-map-marked-alt::after, .fa-duotone.fa-map-marked-alt::after {content: "\f5a0\f5a0";}.fad.fa-map-pin::after, .fa-duotone.fa-map-pin::after {content: "\f276\f276";}.fad.fa-marker::after, .fa-duotone.fa-marker::after {content: "\f5a1\f5a1";}.fad.fa-mars::after, .fa-duotone.fa-mars::after {content: "\f222\f222";}.fad.fa-mars-and-venus::after, .fa-duotone.fa-mars-and-venus::after {content: "\f224\f224";}.fad.fa-mars-and-venus-burst::after, .fa-duotone.fa-mars-and-venus-burst::after {content: "\e523\e523";}.fad.fa-mars-double::after, .fa-duotone.fa-mars-double::after {content: "\f227\f227";}.fad.fa-mars-stroke::after, .fa-duotone.fa-mars-stroke::after {content: "\f229\f229";}.fad.fa-mars-stroke-right::after, .fa-duotone.fa-mars-stroke-right::after {content: "\f22b\f22b";}.fad.fa-mars-stroke-h::after, .fa-duotone.fa-mars-stroke-h::after {content: "\f22b\f22b";}.fad.fa-mars-stroke-up::after, .fa-duotone.fa-mars-stroke-up::after {content: "\f22a\f22a";}.fad.fa-mars-stroke-v::after, .fa-duotone.fa-mars-stroke-v::after {content: "\f22a\f22a";}.fad.fa-martini-glass::after, .fa-duotone.fa-martini-glass::after {content: "\f57b\f57b";}.fad.fa-glass-martini-alt::after, .fa-duotone.fa-glass-martini-alt::after {content: "\f57b\f57b";}.fad.fa-martini-glass-citrus::after, .fa-duotone.fa-martini-glass-citrus::after {content: "\f561\f561";}.fad.fa-cocktail::after, .fa-duotone.fa-cocktail::after {content: "\f561\f561";}.fad.fa-martini-glass-empty::after, .fa-duotone.fa-martini-glass-empty::after {content: "\f000\f000";}.fad.fa-glass-martini::after, .fa-duotone.fa-glass-martini::after {content: "\f000\f000";}.fad.fa-mask::after, .fa-duotone.fa-mask::after {content: "\f6fa\f6fa";}.fad.fa-mask-face::after, .fa-duotone.fa-mask-face::after {content: "\e1d7\e1d7";}.fad.fa-mask-snorkel::after, .fa-duotone.fa-mask-snorkel::after {content: "\e3b7\e3b7";}.fad.fa-mask-ventilator::after, .fa-duotone.fa-mask-ventilator::after {content: "\e524\e524";}.fad.fa-masks-theater::after, .fa-duotone.fa-masks-theater::after {content: "\f630\f630";}.fad.fa-theater-masks::after, .fa-duotone.fa-theater-masks::after {content: "\f630\f630";}.fad.fa-mattress-pillow::after, .fa-duotone.fa-mattress-pillow::after {content: "\e525\e525";}.fad.fa-maximize::after, .fa-duotone.fa-maximize::after {content: "\f31e\f31e";}.fad.fa-expand-arrows-alt::after, .fa-duotone.fa-expand-arrows-alt::after {content: "\f31e\f31e";}.fad.fa-meat::after, .fa-duotone.fa-meat::after {content: "\f814\f814";}.fad.fa-medal::after, .fa-duotone.fa-medal::after {content: "\f5a2\f5a2";}.fad.fa-megaphone::after, .fa-duotone.fa-megaphone::after {content: "\f675\f675";}.fad.fa-melon::after, .fa-duotone.fa-melon::after {content: "\e310\e310";}.fad.fa-melon-slice::after, .fa-duotone.fa-melon-slice::after {content: "\e311\e311";}.fad.fa-memo::after, .fa-duotone.fa-memo::after {content: "\e1d8\e1d8";}.fad.fa-memo-circle-check::after, .fa-duotone.fa-memo-circle-check::after {content: "\e1d9\e1d9";}.fad.fa-memo-circle-info::after, .fa-duotone.fa-memo-circle-info::after {content: "\e49a\e49a";}.fad.fa-memo-pad::after, .fa-duotone.fa-memo-pad::after {content: "\e1da\e1da";}.fad.fa-memory::after, .fa-duotone.fa-memory::after {content: "\f538\f538";}.fad.fa-menorah::after, .fa-duotone.fa-menorah::after {content: "\f676\f676";}.fad.fa-mercury::after, .fa-duotone.fa-mercury::after {content: "\f223\f223";}.fad.fa-merge::after, .fa-duotone.fa-merge::after {content: "\e526\e526";}.fad.fa-message::after, .fa-duotone.fa-message::after {content: "\f27a\f27a";}.fad.fa-comment-alt::after, .fa-duotone.fa-comment-alt::after {content: "\f27a\f27a";}.fad.fa-message-arrow-down::after, .fa-duotone.fa-message-arrow-down::after {content: "\e1db\e1db";}.fad.fa-comment-alt-arrow-down::after, .fa-duotone.fa-comment-alt-arrow-down::after {content: "\e1db\e1db";}.fad.fa-message-arrow-up::after, .fa-duotone.fa-message-arrow-up::after {content: "\e1dc\e1dc";}.fad.fa-comment-alt-arrow-up::after, .fa-duotone.fa-comment-alt-arrow-up::after {content: "\e1dc\e1dc";}.fad.fa-message-arrow-up-right::after, .fa-duotone.fa-message-arrow-up-right::after {content: "\e1dd\e1dd";}.fad.fa-message-bot::after, .fa-duotone.fa-message-bot::after {content: "\e3b8\e3b8";}.fad.fa-message-captions::after, .fa-duotone.fa-message-captions::after {content: "\e1de\e1de";}.fad.fa-comment-alt-captions::after, .fa-duotone.fa-comment-alt-captions::after {content: "\e1de\e1de";}.fad.fa-message-check::after, .fa-duotone.fa-message-check::after {content: "\f4a2\f4a2";}.fad.fa-comment-alt-check::after, .fa-duotone.fa-comment-alt-check::after {content: "\f4a2\f4a2";}.fad.fa-message-code::after, .fa-duotone.fa-message-code::after {content: "\e1df\e1df";}.fad.fa-message-dollar::after, .fa-duotone.fa-message-dollar::after {content: "\f650\f650";}.fad.fa-comment-alt-dollar::after, .fa-duotone.fa-comment-alt-dollar::after {content: "\f650\f650";}.fad.fa-message-dots::after, .fa-duotone.fa-message-dots::after {content: "\f4a3\f4a3";}.fad.fa-comment-alt-dots::after, .fa-duotone.fa-comment-alt-dots::after {content: "\f4a3\f4a3";}.fad.fa-messaging::after, .fa-duotone.fa-messaging::after {content: "\f4a3\f4a3";}.fad.fa-message-exclamation::after, .fa-duotone.fa-message-exclamation::after {content: "\f4a5\f4a5";}.fad.fa-comment-alt-exclamation::after, .fa-duotone.fa-comment-alt-exclamation::after {content: "\f4a5\f4a5";}.fad.fa-message-image::after, .fa-duotone.fa-message-image::after {content: "\e1e0\e1e0";}.fad.fa-comment-alt-image::after, .fa-duotone.fa-comment-alt-image::after {content: "\e1e0\e1e0";}.fad.fa-message-lines::after, .fa-duotone.fa-message-lines::after {content: "\f4a6\f4a6";}.fad.fa-comment-alt-lines::after, .fa-duotone.fa-comment-alt-lines::after {content: "\f4a6\f4a6";}.fad.fa-message-medical::after, .fa-duotone.fa-message-medical::after {content: "\f7f4\f7f4";}.fad.fa-comment-alt-medical::after, .fa-duotone.fa-comment-alt-medical::after {content: "\f7f4\f7f4";}.fad.fa-message-middle::after, .fa-duotone.fa-message-middle::after {content: "\e1e1\e1e1";}.fad.fa-comment-middle-alt::after, .fa-duotone.fa-comment-middle-alt::after {content: "\e1e1\e1e1";}.fad.fa-message-middle-top::after, .fa-duotone.fa-message-middle-top::after {content: "\e1e2\e1e2";}.fad.fa-comment-middle-top-alt::after, .fa-duotone.fa-comment-middle-top-alt::after {content: "\e1e2\e1e2";}.fad.fa-message-minus::after, .fa-duotone.fa-message-minus::after {content: "\f4a7\f4a7";}.fad.fa-comment-alt-minus::after, .fa-duotone.fa-comment-alt-minus::after {content: "\f4a7\f4a7";}.fad.fa-message-music::after, .fa-duotone.fa-message-music::after {content: "\f8af\f8af";}.fad.fa-comment-alt-music::after, .fa-duotone.fa-comment-alt-music::after {content: "\f8af\f8af";}.fad.fa-message-pen::after, .fa-duotone.fa-message-pen::after {content: "\f4a4\f4a4";}.fad.fa-comment-alt-edit::after, .fa-duotone.fa-comment-alt-edit::after {content: "\f4a4\f4a4";}.fad.fa-message-edit::after, .fa-duotone.fa-message-edit::after {content: "\f4a4\f4a4";}.fad.fa-message-plus::after, .fa-duotone.fa-message-plus::after {content: "\f4a8\f4a8";}.fad.fa-comment-alt-plus::after, .fa-duotone.fa-comment-alt-plus::after {content: "\f4a8\f4a8";}.fad.fa-message-question::after, .fa-duotone.fa-message-question::after {content: "\e1e3\e1e3";}.fad.fa-message-quote::after, .fa-duotone.fa-message-quote::after {content: "\e1e4\e1e4";}.fad.fa-comment-alt-quote::after, .fa-duotone.fa-comment-alt-quote::after {content: "\e1e4\e1e4";}.fad.fa-message-slash::after, .fa-duotone.fa-message-slash::after {content: "\f4a9\f4a9";}.fad.fa-comment-alt-slash::after, .fa-duotone.fa-comment-alt-slash::after {content: "\f4a9\f4a9";}.fad.fa-message-smile::after, .fa-duotone.fa-message-smile::after {content: "\f4aa\f4aa";}.fad.fa-comment-alt-smile::after, .fa-duotone.fa-comment-alt-smile::after {content: "\f4aa\f4aa";}.fad.fa-message-sms::after, .fa-duotone.fa-message-sms::after {content: "\e1e5\e1e5";}.fad.fa-message-text::after, .fa-duotone.fa-message-text::after {content: "\e1e6\e1e6";}.fad.fa-comment-alt-text::after, .fa-duotone.fa-comment-alt-text::after {content: "\e1e6\e1e6";}.fad.fa-message-xmark::after, .fa-duotone.fa-message-xmark::after {content: "\f4ab\f4ab";}.fad.fa-comment-alt-times::after, .fa-duotone.fa-comment-alt-times::after {content: "\f4ab\f4ab";}.fad.fa-message-times::after, .fa-duotone.fa-message-times::after {content: "\f4ab\f4ab";}.fad.fa-messages::after, .fa-duotone.fa-messages::after {content: "\f4b6\f4b6";}.fad.fa-comments-alt::after, .fa-duotone.fa-comments-alt::after {content: "\f4b6\f4b6";}.fad.fa-messages-dollar::after, .fa-duotone.fa-messages-dollar::after {content: "\f652\f652";}.fad.fa-comments-alt-dollar::after, .fa-duotone.fa-comments-alt-dollar::after {content: "\f652\f652";}.fad.fa-messages-question::after, .fa-duotone.fa-messages-question::after {content: "\e1e7\e1e7";}.fad.fa-meteor::after, .fa-duotone.fa-meteor::after {content: "\f753\f753";}.fad.fa-meter::after, .fa-duotone.fa-meter::after {content: "\e1e8\e1e8";}.fad.fa-meter-bolt::after, .fa-duotone.fa-meter-bolt::after {content: "\e1e9\e1e9";}.fad.fa-meter-droplet::after, .fa-duotone.fa-meter-droplet::after {content: "\e1ea\e1ea";}.fad.fa-meter-fire::after, .fa-duotone.fa-meter-fire::after {content: "\e1eb\e1eb";}.fad.fa-microchip::after, .fa-duotone.fa-microchip::after {content: "\f2db\f2db";}.fad.fa-microchip-ai::after, .fa-duotone.fa-microchip-ai::after {content: "\e1ec\e1ec";}.fad.fa-microphone::after, .fa-duotone.fa-microphone::after {content: "\f130\f130";}.fad.fa-microphone-lines::after, .fa-duotone.fa-microphone-lines::after {content: "\f3c9\f3c9";}.fad.fa-microphone-alt::after, .fa-duotone.fa-microphone-alt::after {content: "\f3c9\f3c9";}.fad.fa-microphone-lines-slash::after, .fa-duotone.fa-microphone-lines-slash::after {content: "\f539\f539";}.fad.fa-microphone-alt-slash::after, .fa-duotone.fa-microphone-alt-slash::after {content: "\f539\f539";}.fad.fa-microphone-slash::after, .fa-duotone.fa-microphone-slash::after {content: "\f131\f131";}.fad.fa-microphone-stand::after, .fa-duotone.fa-microphone-stand::after {content: "\f8cb\f8cb";}.fad.fa-microscope::after, .fa-duotone.fa-microscope::after {content: "\f610\f610";}.fad.fa-microwave::after, .fa-duotone.fa-microwave::after {content: "\e01b\e01b";}.fad.fa-mill-sign::after, .fa-duotone.fa-mill-sign::after {content: "\e1ed\e1ed";}.fad.fa-minimize::after, .fa-duotone.fa-minimize::after {content: "\f78c\f78c";}.fad.fa-compress-arrows-alt::after, .fa-duotone.fa-compress-arrows-alt::after {content: "\f78c\f78c";}.fad.fa-minus::after, .fa-duotone.fa-minus::after {content: "\f068\f068";}.fad.fa-subtract::after, .fa-duotone.fa-subtract::after {content: "\f068\f068";}.fad.fa-mistletoe::after, .fa-duotone.fa-mistletoe::after {content: "\f7b4\f7b4";}.fad.fa-mitten::after, .fa-duotone.fa-mitten::after {content: "\f7b5\f7b5";}.fad.fa-mobile::after, .fa-duotone.fa-mobile::after {content: "\f3ce\f3ce";}.fad.fa-mobile-android::after, .fa-duotone.fa-mobile-android::after {content: "\f3ce\f3ce";}.fad.fa-mobile-phone::after, .fa-duotone.fa-mobile-phone::after {content: "\f3ce\f3ce";}.fad.fa-mobile-button::after, .fa-duotone.fa-mobile-button::after {content: "\f10b\f10b";}.fad.fa-mobile-notch::after, .fa-duotone.fa-mobile-notch::after {content: "\e1ee\e1ee";}.fad.fa-mobile-iphone::after, .fa-duotone.fa-mobile-iphone::after {content: "\e1ee\e1ee";}.fad.fa-mobile-retro::after, .fa-duotone.fa-mobile-retro::after {content: "\e527\e527";}.fad.fa-mobile-screen::after, .fa-duotone.fa-mobile-screen::after {content: "\f3cf\f3cf";}.fad.fa-mobile-android-alt::after, .fa-duotone.fa-mobile-android-alt::after {content: "\f3cf\f3cf";}.fad.fa-mobile-screen-button::after, .fa-duotone.fa-mobile-screen-button::after {content: "\f3cd\f3cd";}.fad.fa-mobile-alt::after, .fa-duotone.fa-mobile-alt::after {content: "\f3cd\f3cd";}.fad.fa-mobile-signal::after, .fa-duotone.fa-mobile-signal::after {content: "\e1ef\e1ef";}.fad.fa-mobile-signal-out::after, .fa-duotone.fa-mobile-signal-out::after {content: "\e1f0\e1f0";}.fad.fa-money-bill::after, .fa-duotone.fa-money-bill::after {content: "\f0d6\f0d6";}.fad.fa-money-bill-1::after, .fa-duotone.fa-money-bill-1::after {content: "\f3d1\f3d1";}.fad.fa-money-bill-alt::after, .fa-duotone.fa-money-bill-alt::after {content: "\f3d1\f3d1";}.fad.fa-money-bill-1-wave::after, .fa-duotone.fa-money-bill-1-wave::after {content: "\f53b\f53b";}.fad.fa-money-bill-wave-alt::after, .fa-duotone.fa-money-bill-wave-alt::after {content: "\f53b\f53b";}.fad.fa-money-bill-simple::after, .fa-duotone.fa-money-bill-simple::after {content: "\e1f1\e1f1";}.fad.fa-money-bill-simple-wave::after, .fa-duotone.fa-money-bill-simple-wave::after {content: "\e1f2\e1f2";}.fad.fa-money-bill-transfer::after, .fa-duotone.fa-money-bill-transfer::after {content: "\e528\e528";}.fad.fa-money-bill-trend-up::after, .fa-duotone.fa-money-bill-trend-up::after {content: "\e529\e529";}.fad.fa-money-bill-wave::after, .fa-duotone.fa-money-bill-wave::after {content: "\f53a\f53a";}.fad.fa-money-bill-wheat::after, .fa-duotone.fa-money-bill-wheat::after {content: "\e52a\e52a";}.fad.fa-money-bills::after, .fa-duotone.fa-money-bills::after {content: "\e1f3\e1f3";}.fad.fa-money-bills-simple::after, .fa-duotone.fa-money-bills-simple::after {content: "\e1f4\e1f4";}.fad.fa-money-bills-alt::after, .fa-duotone.fa-money-bills-alt::after {content: "\e1f4\e1f4";}.fad.fa-money-check::after, .fa-duotone.fa-money-check::after {content: "\f53c\f53c";}.fad.fa-money-check-dollar::after, .fa-duotone.fa-money-check-dollar::after {content: "\f53d\f53d";}.fad.fa-money-check-alt::after, .fa-duotone.fa-money-check-alt::after {content: "\f53d\f53d";}.fad.fa-money-check-dollar-pen::after, .fa-duotone.fa-money-check-dollar-pen::after {content: "\f873\f873";}.fad.fa-money-check-edit-alt::after, .fa-duotone.fa-money-check-edit-alt::after {content: "\f873\f873";}.fad.fa-money-check-pen::after, .fa-duotone.fa-money-check-pen::after {content: "\f872\f872";}.fad.fa-money-check-edit::after, .fa-duotone.fa-money-check-edit::after {content: "\f872\f872";}.fad.fa-money-from-bracket::after, .fa-duotone.fa-money-from-bracket::after {content: "\e312\e312";}.fad.fa-money-simple-from-bracket::after, .fa-duotone.fa-money-simple-from-bracket::after {content: "\e313\e313";}.fad.fa-monitor-waveform::after, .fa-duotone.fa-monitor-waveform::after {content: "\f611\f611";}.fad.fa-monitor-heart-rate::after, .fa-duotone.fa-monitor-heart-rate::after {content: "\f611\f611";}.fad.fa-monkey::after, .fa-duotone.fa-monkey::after {content: "\f6fb\f6fb";}.fad.fa-monument::after, .fa-duotone.fa-monument::after {content: "\f5a6\f5a6";}.fad.fa-moon::after, .fa-duotone.fa-moon::after {content: "\f186\f186";}.fad.fa-moon-cloud::after, .fa-duotone.fa-moon-cloud::after {content: "\f754\f754";}.fad.fa-moon-over-sun::after, .fa-duotone.fa-moon-over-sun::after {content: "\f74a\f74a";}.fad.fa-eclipse-alt::after, .fa-duotone.fa-eclipse-alt::after {content: "\f74a\f74a";}.fad.fa-moon-stars::after, .fa-duotone.fa-moon-stars::after {content: "\f755\f755";}.fad.fa-moped::after, .fa-duotone.fa-moped::after {content: "\e3b9\e3b9";}.fad.fa-mortar-pestle::after, .fa-duotone.fa-mortar-pestle::after {content: "\f5a7\f5a7";}.fad.fa-mosque::after, .fa-duotone.fa-mosque::after {content: "\f678\f678";}.fad.fa-mosquito::after, .fa-duotone.fa-mosquito::after {content: "\e52b\e52b";}.fad.fa-mosquito-net::after, .fa-duotone.fa-mosquito-net::after {content: "\e52c\e52c";}.fad.fa-motorcycle::after, .fa-duotone.fa-motorcycle::after {content: "\f21c\f21c";}.fad.fa-mound::after, .fa-duotone.fa-mound::after {content: "\e52d\e52d";}.fad.fa-mountain::after, .fa-duotone.fa-mountain::after {content: "\f6fc\f6fc";}.fad.fa-mountain-city::after, .fa-duotone.fa-mountain-city::after {content: "\e52e\e52e";}.fad.fa-mountain-sun::after, .fa-duotone.fa-mountain-sun::after {content: "\e52f\e52f";}.fad.fa-mountains::after, .fa-duotone.fa-mountains::after {content: "\f6fd\f6fd";}.fad.fa-mp3-player::after, .fa-duotone.fa-mp3-player::after {content: "\f8ce\f8ce";}.fad.fa-mug::after, .fa-duotone.fa-mug::after {content: "\f874\f874";}.fad.fa-mug-hot::after, .fa-duotone.fa-mug-hot::after {content: "\f7b6\f7b6";}.fad.fa-mug-marshmallows::after, .fa-duotone.fa-mug-marshmallows::after {content: "\f7b7\f7b7";}.fad.fa-mug-saucer::after, .fa-duotone.fa-mug-saucer::after {content: "\f0f4\f0f4";}.fad.fa-coffee::after, .fa-duotone.fa-coffee::after {content: "\f0f4\f0f4";}.fad.fa-mug-tea::after, .fa-duotone.fa-mug-tea::after {content: "\f875\f875";}.fad.fa-mug-tea-saucer::after, .fa-duotone.fa-mug-tea-saucer::after {content: "\e1f5\e1f5";}.fad.fa-mushroom::after, .fa-duotone.fa-mushroom::after {content: "\e425\e425";}.fad.fa-music::after, .fa-duotone.fa-music::after {content: "\f001\f001";}.fad.fa-music-note::after, .fa-duotone.fa-music-note::after {content: "\f8cf\f8cf";}.fad.fa-music-alt::after, .fa-duotone.fa-music-alt::after {content: "\f8cf\f8cf";}.fad.fa-music-note-slash::after, .fa-duotone.fa-music-note-slash::after {content: "\f8d0\f8d0";}.fad.fa-music-alt-slash::after, .fa-duotone.fa-music-alt-slash::after {content: "\f8d0\f8d0";}.fad.fa-music-slash::after, .fa-duotone.fa-music-slash::after {content: "\f8d1\f8d1";}.fad.fa-n::after, .fa-duotone.fa-n::after {content: "\4e\4e";}.fad.fa-naira-sign::after, .fa-duotone.fa-naira-sign::after {content: "\e1f6\e1f6";}.fad.fa-narwhal::after, .fa-duotone.fa-narwhal::after {content: "\f6fe\f6fe";}.fad.fa-nesting-dolls::after, .fa-duotone.fa-nesting-dolls::after {content: "\e3ba\e3ba";}.fad.fa-network-wired::after, .fa-duotone.fa-network-wired::after {content: "\f6ff\f6ff";}.fad.fa-neuter::after, .fa-duotone.fa-neuter::after {content: "\f22c\f22c";}.fad.fa-newspaper::after, .fa-duotone.fa-newspaper::after {content: "\f1ea\f1ea";}.fad.fa-nfc::after, .fa-duotone.fa-nfc::after {content: "\e1f7\e1f7";}.fad.fa-nfc-lock::after, .fa-duotone.fa-nfc-lock::after {content: "\e1f8\e1f8";}.fad.fa-nfc-magnifying-glass::after, .fa-duotone.fa-nfc-magnifying-glass::after {content: "\e1f9\e1f9";}.fad.fa-nfc-pen::after, .fa-duotone.fa-nfc-pen::after {content: "\e1fa\e1fa";}.fad.fa-nfc-signal::after, .fa-duotone.fa-nfc-signal::after {content: "\e1fb\e1fb";}.fad.fa-nfc-slash::after, .fa-duotone.fa-nfc-slash::after {content: "\e1fc\e1fc";}.fad.fa-nfc-trash::after, .fa-duotone.fa-nfc-trash::after {content: "\e1fd\e1fd";}.fad.fa-not-equal::after, .fa-duotone.fa-not-equal::after {content: "\f53e\f53e";}.fad.fa-notdef::after, .fa-duotone.fa-notdef::after {content: "\e1fe\e1fe";}.fad.fa-note::after, .fa-duotone.fa-note::after {content: "\e1ff\e1ff";}.fad.fa-note-medical::after, .fa-duotone.fa-note-medical::after {content: "\e200\e200";}.fad.fa-note-sticky::after, .fa-duotone.fa-note-sticky::after {content: "\f249\f249";}.fad.fa-sticky-note::after, .fa-duotone.fa-sticky-note::after {content: "\f249\f249";}.fad.fa-notebook::after, .fa-duotone.fa-notebook::after {content: "\e201\e201";}.fad.fa-notes::after, .fa-duotone.fa-notes::after {content: "\e202\e202";}.fad.fa-notes-medical::after, .fa-duotone.fa-notes-medical::after {content: "\f481\f481";}.fad.fa-o::after, .fa-duotone.fa-o::after {content: "\4f\4f";}.fad.fa-object-exclude::after, .fa-duotone.fa-object-exclude::after {content: "\e49c\e49c";}.fad.fa-object-group::after, .fa-duotone.fa-object-group::after {content: "\f247\f247";}.fad.fa-object-intersect::after, .fa-duotone.fa-object-intersect::after {content: "\e49d\e49d";}.fad.fa-object-subtract::after, .fa-duotone.fa-object-subtract::after {content: "\e49e\e49e";}.fad.fa-object-ungroup::after, .fa-duotone.fa-object-ungroup::after {content: "\f248\f248";}.fad.fa-object-union::after, .fa-duotone.fa-object-union::after {content: "\e49f\e49f";}.fad.fa-objects-align-bottom::after, .fa-duotone.fa-objects-align-bottom::after {content: "\e3bb\e3bb";}.fad.fa-objects-align-center-horizontal::after, .fa-duotone.fa-objects-align-center-horizontal::after {content: "\e3bc\e3bc";}.fad.fa-objects-align-center-vertical::after, .fa-duotone.fa-objects-align-center-vertical::after {content: "\e3bd\e3bd";}.fad.fa-objects-align-left::after, .fa-duotone.fa-objects-align-left::after {content: "\e3be\e3be";}.fad.fa-objects-align-right::after, .fa-duotone.fa-objects-align-right::after {content: "\e3bf\e3bf";}.fad.fa-objects-align-top::after, .fa-duotone.fa-objects-align-top::after {content: "\e3c0\e3c0";}.fad.fa-objects-column::after, .fa-duotone.fa-objects-column::after {content: "\e3c1\e3c1";}.fad.fa-octagon::after, .fa-duotone.fa-octagon::after {content: "\f306\f306";}.fad.fa-octagon-check::after, .fa-duotone.fa-octagon-check::after {content: "\e426\e426";}.fad.fa-octagon-divide::after, .fa-duotone.fa-octagon-divide::after {content: "\e203\e203";}.fad.fa-octagon-exclamation::after, .fa-duotone.fa-octagon-exclamation::after {content: "\e204\e204";}.fad.fa-octagon-minus::after, .fa-duotone.fa-octagon-minus::after {content: "\f308\f308";}.fad.fa-minus-octagon::after, .fa-duotone.fa-minus-octagon::after {content: "\f308\f308";}.fad.fa-octagon-plus::after, .fa-duotone.fa-octagon-plus::after {content: "\f301\f301";}.fad.fa-plus-octagon::after, .fa-duotone.fa-plus-octagon::after {content: "\f301\f301";}.fad.fa-octagon-xmark::after, .fa-duotone.fa-octagon-xmark::after {content: "\f2f0\f2f0";}.fad.fa-times-octagon::after, .fa-duotone.fa-times-octagon::after {content: "\f2f0\f2f0";}.fad.fa-xmark-octagon::after, .fa-duotone.fa-xmark-octagon::after {content: "\f2f0\f2f0";}.fad.fa-oil-can::after, .fa-duotone.fa-oil-can::after {content: "\f613\f613";}.fad.fa-oil-can-drip::after, .fa-duotone.fa-oil-can-drip::after {content: "\e205\e205";}.fad.fa-oil-temperature::after, .fa-duotone.fa-oil-temperature::after {content: "\f614\f614";}.fad.fa-oil-temp::after, .fa-duotone.fa-oil-temp::after {content: "\f614\f614";}.fad.fa-oil-well::after, .fa-duotone.fa-oil-well::after {content: "\e532\e532";}.fad.fa-olive::after, .fa-duotone.fa-olive::after {content: "\e316\e316";}.fad.fa-olive-branch::after, .fa-duotone.fa-olive-branch::after {content: "\e317\e317";}.fad.fa-om::after, .fa-duotone.fa-om::after {content: "\f679\f679";}.fad.fa-omega::after, .fa-duotone.fa-omega::after {content: "\f67a\f67a";}.fad.fa-onion::after, .fa-duotone.fa-onion::after {content: "\e427\e427";}.fad.fa-option::after, .fa-duotone.fa-option::after {content: "\e318\e318";}.fad.fa-ornament::after, .fa-duotone.fa-ornament::after {content: "\f7b8\f7b8";}.fad.fa-otter::after, .fa-duotone.fa-otter::after {content: "\f700\f700";}.fad.fa-outdent::after, .fa-duotone.fa-outdent::after {content: "\f03b\f03b";}.fad.fa-dedent::after, .fa-duotone.fa-dedent::after {content: "\f03b\f03b";}.fad.fa-outlet::after, .fa-duotone.fa-outlet::after {content: "\e01c\e01c";}.fad.fa-oven::after, .fa-duotone.fa-oven::after {content: "\e01d\e01d";}.fad.fa-overline::after, .fa-duotone.fa-overline::after {content: "\f876\f876";}.fad.fa-p::after, .fa-duotone.fa-p::after {content: "\50\50";}.fad.fa-page::after, .fa-duotone.fa-page::after {content: "\e428\e428";}.fad.fa-page-caret-down::after, .fa-duotone.fa-page-caret-down::after {content: "\e429\e429";}.fad.fa-file-caret-down::after, .fa-duotone.fa-file-caret-down::after {content: "\e429\e429";}.fad.fa-page-caret-up::after, .fa-duotone.fa-page-caret-up::after {content: "\e42a\e42a";}.fad.fa-file-caret-up::after, .fa-duotone.fa-file-caret-up::after {content: "\e42a\e42a";}.fad.fa-pager::after, .fa-duotone.fa-pager::after {content: "\f815\f815";}.fad.fa-paint-roller::after, .fa-duotone.fa-paint-roller::after {content: "\f5aa\f5aa";}.fad.fa-paintbrush::after, .fa-duotone.fa-paintbrush::after {content: "\f1fc\f1fc";}.fad.fa-paint-brush::after, .fa-duotone.fa-paint-brush::after {content: "\f1fc\f1fc";}.fad.fa-paintbrush-fine::after, .fa-duotone.fa-paintbrush-fine::after {content: "\f5a9\f5a9";}.fad.fa-paint-brush-alt::after, .fa-duotone.fa-paint-brush-alt::after {content: "\f5a9\f5a9";}.fad.fa-paint-brush-fine::after, .fa-duotone.fa-paint-brush-fine::after {content: "\f5a9\f5a9";}.fad.fa-paintbrush-alt::after, .fa-duotone.fa-paintbrush-alt::after {content: "\f5a9\f5a9";}.fad.fa-paintbrush-pencil::after, .fa-duotone.fa-paintbrush-pencil::after {content: "\e206\e206";}.fad.fa-palette::after, .fa-duotone.fa-palette::after {content: "\f53f\f53f";}.fad.fa-pallet::after, .fa-duotone.fa-pallet::after {content: "\f482\f482";}.fad.fa-pallet-box::after, .fa-duotone.fa-pallet-box::after {content: "\e208\e208";}.fad.fa-pallet-boxes::after, .fa-duotone.fa-pallet-boxes::after {content: "\f483\f483";}.fad.fa-palette-boxes::after, .fa-duotone.fa-palette-boxes::after {content: "\f483\f483";}.fad.fa-pallet-alt::after, .fa-duotone.fa-pallet-alt::after {content: "\f483\f483";}.fad.fa-pan-food::after, .fa-duotone.fa-pan-food::after {content: "\e42b\e42b";}.fad.fa-pan-frying::after, .fa-duotone.fa-pan-frying::after {content: "\e42c\e42c";}.fad.fa-pancakes::after, .fa-duotone.fa-pancakes::after {content: "\e42d\e42d";}.fad.fa-panel-ews::after, .fa-duotone.fa-panel-ews::after {content: "\e42e\e42e";}.fad.fa-panel-fire::after, .fa-duotone.fa-panel-fire::after {content: "\e42f\e42f";}.fad.fa-panorama::after, .fa-duotone.fa-panorama::after {content: "\e209\e209";}.fad.fa-paper-plane::after, .fa-duotone.fa-paper-plane::after {content: "\f1d8\f1d8";}.fad.fa-paper-plane-top::after, .fa-duotone.fa-paper-plane-top::after {content: "\e20a\e20a";}.fad.fa-paper-plane-alt::after, .fa-duotone.fa-paper-plane-alt::after {content: "\e20a\e20a";}.fad.fa-send::after, .fa-duotone.fa-send::after {content: "\e20a\e20a";}.fad.fa-paperclip::after, .fa-duotone.fa-paperclip::after {content: "\f0c6\f0c6";}.fad.fa-paperclip-vertical::after, .fa-duotone.fa-paperclip-vertical::after {content: "\e3c2\e3c2";}.fad.fa-parachute-box::after, .fa-duotone.fa-parachute-box::after {content: "\f4cd\f4cd";}.fad.fa-paragraph::after, .fa-duotone.fa-paragraph::after {content: "\f1dd\f1dd";}.fad.fa-paragraph-left::after, .fa-duotone.fa-paragraph-left::after {content: "\f878\f878";}.fad.fa-paragraph-rtl::after, .fa-duotone.fa-paragraph-rtl::after {content: "\f878\f878";}.fad.fa-party-bell::after, .fa-duotone.fa-party-bell::after {content: "\e31a\e31a";}.fad.fa-party-horn::after, .fa-duotone.fa-party-horn::after {content: "\e31b\e31b";}.fad.fa-passport::after, .fa-duotone.fa-passport::after {content: "\f5ab\f5ab";}.fad.fa-paste::after, .fa-duotone.fa-paste::after {content: "\f0ea\f0ea";}.fad.fa-file-clipboard::after, .fa-duotone.fa-file-clipboard::after {content: "\f0ea\f0ea";}.fad.fa-pause::after, .fa-duotone.fa-pause::after {content: "\f04c\f04c";}.fad.fa-paw::after, .fa-duotone.fa-paw::after {content: "\f1b0\f1b0";}.fad.fa-paw-claws::after, .fa-duotone.fa-paw-claws::after {content: "\f702\f702";}.fad.fa-paw-simple::after, .fa-duotone.fa-paw-simple::after {content: "\f701\f701";}.fad.fa-paw-alt::after, .fa-duotone.fa-paw-alt::after {content: "\f701\f701";}.fad.fa-peace::after, .fa-duotone.fa-peace::after {content: "\f67c\f67c";}.fad.fa-peach::after, .fa-duotone.fa-peach::after {content: "\e20b\e20b";}.fad.fa-peanut::after, .fa-duotone.fa-peanut::after {content: "\e430\e430";}.fad.fa-peanuts::after, .fa-duotone.fa-peanuts::after {content: "\e431\e431";}.fad.fa-peapod::after, .fa-duotone.fa-peapod::after {content: "\e31c\e31c";}.fad.fa-pear::after, .fa-duotone.fa-pear::after {content: "\e20c\e20c";}.fad.fa-pedestal::after, .fa-duotone.fa-pedestal::after {content: "\e20d\e20d";}.fad.fa-pegasus::after, .fa-duotone.fa-pegasus::after {content: "\f703\f703";}.fad.fa-pen::after, .fa-duotone.fa-pen::after {content: "\f304\f304";}.fad.fa-pen-circle::after, .fa-duotone.fa-pen-circle::after {content: "\e20e\e20e";}.fad.fa-pen-clip::after, .fa-duotone.fa-pen-clip::after {content: "\f305\f305";}.fad.fa-pen-alt::after, .fa-duotone.fa-pen-alt::after {content: "\f305\f305";}.fad.fa-pen-clip-slash::after, .fa-duotone.fa-pen-clip-slash::after {content: "\e20f\e20f";}.fad.fa-pen-alt-slash::after, .fa-duotone.fa-pen-alt-slash::after {content: "\e20f\e20f";}.fad.fa-pen-fancy::after, .fa-duotone.fa-pen-fancy::after {content: "\f5ac\f5ac";}.fad.fa-pen-fancy-slash::after, .fa-duotone.fa-pen-fancy-slash::after {content: "\e210\e210";}.fad.fa-pen-field::after, .fa-duotone.fa-pen-field::after {content: "\e211\e211";}.fad.fa-pen-line::after, .fa-duotone.fa-pen-line::after {content: "\e212\e212";}.fad.fa-pen-nib::after, .fa-duotone.fa-pen-nib::after {content: "\f5ad\f5ad";}.fad.fa-pen-nib-slash::after, .fa-duotone.fa-pen-nib-slash::after {content: "\e4a1\e4a1";}.fad.fa-pen-paintbrush::after, .fa-duotone.fa-pen-paintbrush::after {content: "\f618\f618";}.fad.fa-pencil-paintbrush::after, .fa-duotone.fa-pencil-paintbrush::after {content: "\f618\f618";}.fad.fa-pen-ruler::after, .fa-duotone.fa-pen-ruler::after {content: "\f5ae\f5ae";}.fad.fa-pencil-ruler::after, .fa-duotone.fa-pencil-ruler::after {content: "\f5ae\f5ae";}.fad.fa-pen-slash::after, .fa-duotone.fa-pen-slash::after {content: "\e213\e213";}.fad.fa-pen-swirl::after, .fa-duotone.fa-pen-swirl::after {content: "\e214\e214";}.fad.fa-pen-to-square::after, .fa-duotone.fa-pen-to-square::after {content: "\f044\f044";}.fad.fa-edit::after, .fa-duotone.fa-edit::after {content: "\f044\f044";}.fad.fa-pencil::after, .fa-duotone.fa-pencil::after {content: "\f303\f303";}.fad.fa-pencil-alt::after, .fa-duotone.fa-pencil-alt::after {content: "\f303\f303";}.fad.fa-pencil-slash::after, .fa-duotone.fa-pencil-slash::after {content: "\e215\e215";}.fad.fa-people::after, .fa-duotone.fa-people::after {content: "\e216\e216";}.fad.fa-people-arrows-left-right::after, .fa-duotone.fa-people-arrows-left-right::after {content: "\e068\e068";}.fad.fa-people-arrows::after, .fa-duotone.fa-people-arrows::after {content: "\e068\e068";}.fad.fa-people-carry-box::after, .fa-duotone.fa-people-carry-box::after {content: "\f4ce\f4ce";}.fad.fa-people-carry::after, .fa-duotone.fa-people-carry::after {content: "\f4ce\f4ce";}.fad.fa-people-dress::after, .fa-duotone.fa-people-dress::after {content: "\e217\e217";}.fad.fa-people-dress-simple::after, .fa-duotone.fa-people-dress-simple::after {content: "\e218\e218";}.fad.fa-people-group::after, .fa-duotone.fa-people-group::after {content: "\e533\e533";}.fad.fa-people-line::after, .fa-duotone.fa-people-line::after {content: "\e534\e534";}.fad.fa-people-pants::after, .fa-duotone.fa-people-pants::after {content: "\e219\e219";}.fad.fa-people-pants-simple::after, .fa-duotone.fa-people-pants-simple::after {content: "\e21a\e21a";}.fad.fa-people-pulling::after, .fa-duotone.fa-people-pulling::after {content: "\e535\e535";}.fad.fa-people-robbery::after, .fa-duotone.fa-people-robbery::after {content: "\e536\e536";}.fad.fa-people-roof::after, .fa-duotone.fa-people-roof::after {content: "\e537\e537";}.fad.fa-people-simple::after, .fa-duotone.fa-people-simple::after {content: "\e21b\e21b";}.fad.fa-pepper::after, .fa-duotone.fa-pepper::after {content: "\e432\e432";}.fad.fa-pepper-hot::after, .fa-duotone.fa-pepper-hot::after {content: "\f816\f816";}.fad.fa-percent::after, .fa-duotone.fa-percent::after {content: "\25\25";}.fad.fa-percentage::after, .fa-duotone.fa-percentage::after {content: "\25\25";}.fad.fa-period::after, .fa-duotone.fa-period::after {content: "\2e\2e";}.fad.fa-person::after, .fa-duotone.fa-person::after {content: "\f183\f183";}.fad.fa-male::after, .fa-duotone.fa-male::after {content: "\f183\f183";}.fad.fa-person-arrow-down-to-line::after, .fa-duotone.fa-person-arrow-down-to-line::after {content: "\e538\e538";}.fad.fa-person-arrow-up-from-line::after, .fa-duotone.fa-person-arrow-up-from-line::after {content: "\e539\e539";}.fad.fa-person-biking::after, .fa-duotone.fa-person-biking::after {content: "\f84a\f84a";}.fad.fa-biking::after, .fa-duotone.fa-biking::after {content: "\f84a\f84a";}.fad.fa-person-biking-mountain::after, .fa-duotone.fa-person-biking-mountain::after {content: "\f84b\f84b";}.fad.fa-biking-mountain::after, .fa-duotone.fa-biking-mountain::after {content: "\f84b\f84b";}.fad.fa-person-booth::after, .fa-duotone.fa-person-booth::after {content: "\f756\f756";}.fad.fa-person-breastfeeding::after, .fa-duotone.fa-person-breastfeeding::after {content: "\e53a\e53a";}.fad.fa-person-burst::after, .fa-duotone.fa-person-burst::after {content: "\e53b\e53b";}.fad.fa-person-cane::after, .fa-duotone.fa-person-cane::after {content: "\e53c\e53c";}.fad.fa-person-carry-box::after, .fa-duotone.fa-person-carry-box::after {content: "\f4cf\f4cf";}.fad.fa-person-carry::after, .fa-duotone.fa-person-carry::after {content: "\f4cf\f4cf";}.fad.fa-person-chalkboard::after, .fa-duotone.fa-person-chalkboard::after {content: "\e53d\e53d";}.fad.fa-person-circle-check::after, .fa-duotone.fa-person-circle-check::after {content: "\e53e\e53e";}.fad.fa-person-circle-exclamation::after, .fa-duotone.fa-person-circle-exclamation::after {content: "\e53f\e53f";}.fad.fa-person-circle-minus::after, .fa-duotone.fa-person-circle-minus::after {content: "\e540\e540";}.fad.fa-person-circle-plus::after, .fa-duotone.fa-person-circle-plus::after {content: "\e541\e541";}.fad.fa-person-circle-question::after, .fa-duotone.fa-person-circle-question::after {content: "\e542\e542";}.fad.fa-person-circle-xmark::after, .fa-duotone.fa-person-circle-xmark::after {content: "\e543\e543";}.fad.fa-person-digging::after, .fa-duotone.fa-person-digging::after {content: "\f85e\f85e";}.fad.fa-digging::after, .fa-duotone.fa-digging::after {content: "\f85e\f85e";}.fad.fa-person-dolly::after, .fa-duotone.fa-person-dolly::after {content: "\f4d0\f4d0";}.fad.fa-person-dolly-empty::after, .fa-duotone.fa-person-dolly-empty::after {content: "\f4d1\f4d1";}.fad.fa-person-dots-from-line::after, .fa-duotone.fa-person-dots-from-line::after {content: "\f470\f470";}.fad.fa-diagnoses::after, .fa-duotone.fa-diagnoses::after {content: "\f470\f470";}.fad.fa-person-dress::after, .fa-duotone.fa-person-dress::after {content: "\f182\f182";}.fad.fa-female::after, .fa-duotone.fa-female::after {content: "\f182\f182";}.fad.fa-person-dress-burst::after, .fa-duotone.fa-person-dress-burst::after {content: "\e544\e544";}.fad.fa-person-dress-simple::after, .fa-duotone.fa-person-dress-simple::after {content: "\e21c\e21c";}.fad.fa-person-drowning::after, .fa-duotone.fa-person-drowning::after {content: "\e545\e545";}.fad.fa-person-falling::after, .fa-duotone.fa-person-falling::after {content: "\e546\e546";}.fad.fa-person-falling-burst::after, .fa-duotone.fa-person-falling-burst::after {content: "\e547\e547";}.fad.fa-person-from-portal::after, .fa-duotone.fa-person-from-portal::after {content: "\e023\e023";}.fad.fa-portal-exit::after, .fa-duotone.fa-portal-exit::after {content: "\e023\e023";}.fad.fa-person-half-dress::after, .fa-duotone.fa-person-half-dress::after {content: "\e548\e548";}.fad.fa-person-harassing::after, .fa-duotone.fa-person-harassing::after {content: "\e549\e549";}.fad.fa-person-hiking::after, .fa-duotone.fa-person-hiking::after {content: "\f6ec\f6ec";}.fad.fa-hiking::after, .fa-duotone.fa-hiking::after {content: "\f6ec\f6ec";}.fad.fa-person-military-pointing::after, .fa-duotone.fa-person-military-pointing::after {content: "\e54a\e54a";}.fad.fa-person-military-rifle::after, .fa-duotone.fa-person-military-rifle::after {content: "\e54b\e54b";}.fad.fa-person-military-to-person::after, .fa-duotone.fa-person-military-to-person::after {content: "\e54c\e54c";}.fad.fa-person-pinball::after, .fa-duotone.fa-person-pinball::after {content: "\e21d\e21d";}.fad.fa-person-praying::after, .fa-duotone.fa-person-praying::after {content: "\f683\f683";}.fad.fa-pray::after, .fa-duotone.fa-pray::after {content: "\f683\f683";}.fad.fa-person-pregnant::after, .fa-duotone.fa-person-pregnant::after {content: "\e31e\e31e";}.fad.fa-person-rays::after, .fa-duotone.fa-person-rays::after {content: "\e54d\e54d";}.fad.fa-person-rifle::after, .fa-duotone.fa-person-rifle::after {content: "\e54e\e54e";}.fad.fa-person-running::after, .fa-duotone.fa-person-running::after {content: "\f70c\f70c";}.fad.fa-running::after, .fa-duotone.fa-running::after {content: "\f70c\f70c";}.fad.fa-person-seat::after, .fa-duotone.fa-person-seat::after {content: "\e21e\e21e";}.fad.fa-person-seat-reclined::after, .fa-duotone.fa-person-seat-reclined::after {content: "\e21f\e21f";}.fad.fa-person-shelter::after, .fa-duotone.fa-person-shelter::after {content: "\e54f\e54f";}.fad.fa-person-sign::after, .fa-duotone.fa-person-sign::after {content: "\f757\f757";}.fad.fa-person-simple::after, .fa-duotone.fa-person-simple::after {content: "\e220\e220";}.fad.fa-person-skating::after, .fa-duotone.fa-person-skating::after {content: "\f7c5\f7c5";}.fad.fa-skating::after, .fa-duotone.fa-skating::after {content: "\f7c5\f7c5";}.fad.fa-person-ski-jumping::after, .fa-duotone.fa-person-ski-jumping::after {content: "\f7c7\f7c7";}.fad.fa-ski-jump::after, .fa-duotone.fa-ski-jump::after {content: "\f7c7\f7c7";}.fad.fa-person-ski-lift::after, .fa-duotone.fa-person-ski-lift::after {content: "\f7c8\f7c8";}.fad.fa-ski-lift::after, .fa-duotone.fa-ski-lift::after {content: "\f7c8\f7c8";}.fad.fa-person-skiing::after, .fa-duotone.fa-person-skiing::after {content: "\f7c9\f7c9";}.fad.fa-skiing::after, .fa-duotone.fa-skiing::after {content: "\f7c9\f7c9";}.fad.fa-person-skiing-nordic::after, .fa-duotone.fa-person-skiing-nordic::after {content: "\f7ca\f7ca";}.fad.fa-skiing-nordic::after, .fa-duotone.fa-skiing-nordic::after {content: "\f7ca\f7ca";}.fad.fa-person-sledding::after, .fa-duotone.fa-person-sledding::after {content: "\f7cb\f7cb";}.fad.fa-sledding::after, .fa-duotone.fa-sledding::after {content: "\f7cb\f7cb";}.fad.fa-person-snowboarding::after, .fa-duotone.fa-person-snowboarding::after {content: "\f7ce\f7ce";}.fad.fa-snowboarding::after, .fa-duotone.fa-snowboarding::after {content: "\f7ce\f7ce";}.fad.fa-person-snowmobiling::after, .fa-duotone.fa-person-snowmobiling::after {content: "\f7d1\f7d1";}.fad.fa-snowmobile::after, .fa-duotone.fa-snowmobile::after {content: "\f7d1\f7d1";}.fad.fa-person-swimming::after, .fa-duotone.fa-person-swimming::after {content: "\f5c4\f5c4";}.fad.fa-swimmer::after, .fa-duotone.fa-swimmer::after {content: "\f5c4\f5c4";}.fad.fa-person-through-window::after, .fa-duotone.fa-person-through-window::after {content: "\e433\e433";}.fad.fa-person-to-door::after, .fa-duotone.fa-person-to-door::after {content: "\e550\e550";}.fad.fa-person-to-portal::after, .fa-duotone.fa-person-to-portal::after {content: "\e022\e022";}.fad.fa-portal-enter::after, .fa-duotone.fa-portal-enter::after {content: "\e022\e022";}.fad.fa-person-walking::after, .fa-duotone.fa-person-walking::after {content: "\f554\f554";}.fad.fa-walking::after, .fa-duotone.fa-walking::after {content: "\f554\f554";}.fad.fa-person-walking-arrow-loop-left::after, .fa-duotone.fa-person-walking-arrow-loop-left::after {content: "\e551\e551";}.fad.fa-person-walking-arrow-right::after, .fa-duotone.fa-person-walking-arrow-right::after {content: "\e552\e552";}.fad.fa-person-walking-dashed-line-arrow-right::after, .fa-duotone.fa-person-walking-dashed-line-arrow-right::after {content: "\e553\e553";}.fad.fa-person-walking-luggage::after, .fa-duotone.fa-person-walking-luggage::after {content: "\e554\e554";}.fad.fa-person-walking-with-cane::after, .fa-duotone.fa-person-walking-with-cane::after {content: "\f29d\f29d";}.fad.fa-blind::after, .fa-duotone.fa-blind::after {content: "\f29d\f29d";}.fad.fa-peseta-sign::after, .fa-duotone.fa-peseta-sign::after {content: "\e221\e221";}.fad.fa-peso-sign::after, .fa-duotone.fa-peso-sign::after {content: "\e222\e222";}.fad.fa-phone::after, .fa-duotone.fa-phone::after {content: "\f095\f095";}.fad.fa-phone-arrow-down-left::after, .fa-duotone.fa-phone-arrow-down-left::after {content: "\e223\e223";}.fad.fa-phone-arrow-down::after, .fa-duotone.fa-phone-arrow-down::after {content: "\e223\e223";}.fad.fa-phone-incoming::after, .fa-duotone.fa-phone-incoming::after {content: "\e223\e223";}.fad.fa-phone-arrow-up-right::after, .fa-duotone.fa-phone-arrow-up-right::after {content: "\e224\e224";}.fad.fa-phone-arrow-up::after, .fa-duotone.fa-phone-arrow-up::after {content: "\e224\e224";}.fad.fa-phone-outgoing::after, .fa-duotone.fa-phone-outgoing::after {content: "\e224\e224";}.fad.fa-phone-flip::after, .fa-duotone.fa-phone-flip::after {content: "\f879\f879";}.fad.fa-phone-alt::after, .fa-duotone.fa-phone-alt::after {content: "\f879\f879";}.fad.fa-phone-hangup::after, .fa-duotone.fa-phone-hangup::after {content: "\e225\e225";}.fad.fa-phone-intercom::after, .fa-duotone.fa-phone-intercom::after {content: "\e434\e434";}.fad.fa-phone-missed::after, .fa-duotone.fa-phone-missed::after {content: "\e226\e226";}.fad.fa-phone-office::after, .fa-duotone.fa-phone-office::after {content: "\f67d\f67d";}.fad.fa-phone-plus::after, .fa-duotone.fa-phone-plus::after {content: "\f4d2\f4d2";}.fad.fa-phone-rotary::after, .fa-duotone.fa-phone-rotary::after {content: "\f8d3\f8d3";}.fad.fa-phone-slash::after, .fa-duotone.fa-phone-slash::after {content: "\f3dd\f3dd";}.fad.fa-phone-volume::after, .fa-duotone.fa-phone-volume::after {content: "\f2a0\f2a0";}.fad.fa-volume-control-phone::after, .fa-duotone.fa-volume-control-phone::after {content: "\f2a0\f2a0";}.fad.fa-phone-xmark::after, .fa-duotone.fa-phone-xmark::after {content: "\e227\e227";}.fad.fa-photo-film::after, .fa-duotone.fa-photo-film::after {content: "\f87c\f87c";}.fad.fa-photo-video::after, .fa-duotone.fa-photo-video::after {content: "\f87c\f87c";}.fad.fa-photo-film-music::after, .fa-duotone.fa-photo-film-music::after {content: "\e228\e228";}.fad.fa-pi::after, .fa-duotone.fa-pi::after {content: "\f67e\f67e";}.fad.fa-piano::after, .fa-duotone.fa-piano::after {content: "\f8d4\f8d4";}.fad.fa-piano-keyboard::after, .fa-duotone.fa-piano-keyboard::after {content: "\f8d5\f8d5";}.fad.fa-pickleball::after, .fa-duotone.fa-pickleball::after {content: "\e435\e435";}.fad.fa-pie::after, .fa-duotone.fa-pie::after {content: "\f705\f705";}.fad.fa-pig::after, .fa-duotone.fa-pig::after {content: "\f706\f706";}.fad.fa-piggy-bank::after, .fa-duotone.fa-piggy-bank::after {content: "\f4d3\f4d3";}.fad.fa-pills::after, .fa-duotone.fa-pills::after {content: "\f484\f484";}.fad.fa-pinata::after, .fa-duotone.fa-pinata::after {content: "\e3c3\e3c3";}.fad.fa-pinball::after, .fa-duotone.fa-pinball::after {content: "\e229\e229";}.fad.fa-pineapple::after, .fa-duotone.fa-pineapple::after {content: "\e31f\e31f";}.fad.fa-pipe::after, .fa-duotone.fa-pipe::after {content: "\7c\7c";}.fad.fa-pipe-circle-check::after, .fa-duotone.fa-pipe-circle-check::after {content: "\e436\e436";}.fad.fa-pipe-collar::after, .fa-duotone.fa-pipe-collar::after {content: "\e437\e437";}.fad.fa-pipe-section::after, .fa-duotone.fa-pipe-section::after {content: "\e438\e438";}.fad.fa-pipe-smoking::after, .fa-duotone.fa-pipe-smoking::after {content: "\e3c4\e3c4";}.fad.fa-pipe-valve::after, .fa-duotone.fa-pipe-valve::after {content: "\e439\e439";}.fad.fa-pizza::after, .fa-duotone.fa-pizza::after {content: "\f817\f817";}.fad.fa-pizza-slice::after, .fa-duotone.fa-pizza-slice::after {content: "\f818\f818";}.fad.fa-place-of-worship::after, .fa-duotone.fa-place-of-worship::after {content: "\f67f\f67f";}.fad.fa-plane::after, .fa-duotone.fa-plane::after {content: "\f072\f072";}.fad.fa-plane-arrival::after, .fa-duotone.fa-plane-arrival::after {content: "\f5af\f5af";}.fad.fa-plane-circle-check::after, .fa-duotone.fa-plane-circle-check::after {content: "\e555\e555";}.fad.fa-plane-circle-exclamation::after, .fa-duotone.fa-plane-circle-exclamation::after {content: "\e556\e556";}.fad.fa-plane-circle-xmark::after, .fa-duotone.fa-plane-circle-xmark::after {content: "\e557\e557";}.fad.fa-plane-departure::after, .fa-duotone.fa-plane-departure::after {content: "\f5b0\f5b0";}.fad.fa-plane-engines::after, .fa-duotone.fa-plane-engines::after {content: "\f3de\f3de";}.fad.fa-plane-alt::after, .fa-duotone.fa-plane-alt::after {content: "\f3de\f3de";}.fad.fa-plane-lock::after, .fa-duotone.fa-plane-lock::after {content: "\e558\e558";}.fad.fa-plane-prop::after, .fa-duotone.fa-plane-prop::after {content: "\e22b\e22b";}.fad.fa-plane-slash::after, .fa-duotone.fa-plane-slash::after {content: "\e069\e069";}.fad.fa-plane-tail::after, .fa-duotone.fa-plane-tail::after {content: "\e22c\e22c";}.fad.fa-plane-up::after, .fa-duotone.fa-plane-up::after {content: "\e22d\e22d";}.fad.fa-plane-up-slash::after, .fa-duotone.fa-plane-up-slash::after {content: "\e22e\e22e";}.fad.fa-planet-moon::after, .fa-duotone.fa-planet-moon::after {content: "\e01f\e01f";}.fad.fa-planet-ringed::after, .fa-duotone.fa-planet-ringed::after {content: "\e020\e020";}.fad.fa-plant-wilt::after, .fa-duotone.fa-plant-wilt::after {content: "\e43b\e43b";}.fad.fa-plate-utensils::after, .fa-duotone.fa-plate-utensils::after {content: "\e559\e559";}.fad.fa-plate-wheat::after, .fa-duotone.fa-plate-wheat::after {content: "\e55a\e55a";}.fad.fa-play::after, .fa-duotone.fa-play::after {content: "\f04b\f04b";}.fad.fa-play-pause::after, .fa-duotone.fa-play-pause::after {content: "\e22f\e22f";}.fad.fa-plug::after, .fa-duotone.fa-plug::after {content: "\f1e6\f1e6";}.fad.fa-plug-circle-bolt::after, .fa-duotone.fa-plug-circle-bolt::after {content: "\e55b\e55b";}.fad.fa-plug-circle-check::after, .fa-duotone.fa-plug-circle-check::after {content: "\e55c\e55c";}.fad.fa-plug-circle-exclamation::after, .fa-duotone.fa-plug-circle-exclamation::after {content: "\e55d\e55d";}.fad.fa-plug-circle-minus::after, .fa-duotone.fa-plug-circle-minus::after {content: "\e55e\e55e";}.fad.fa-plug-circle-plus::after, .fa-duotone.fa-plug-circle-plus::after {content: "\e55f\e55f";}.fad.fa-plug-circle-xmark::after, .fa-duotone.fa-plug-circle-xmark::after {content: "\e560\e560";}.fad.fa-plus::after, .fa-duotone.fa-plus::after {content: "\2b\2b";}.fad.fa-add::after, .fa-duotone.fa-add::after {content: "\2b\2b";}.fad.fa-plus-large::after, .fa-duotone.fa-plus-large::after {content: "\e59e\e59e";}.fad.fa-plus-minus::after, .fa-duotone.fa-plus-minus::after {content: "\e43c\e43c";}.fad.fa-podcast::after, .fa-duotone.fa-podcast::after {content: "\f2ce\f2ce";}.fad.fa-podium::after, .fa-duotone.fa-podium::after {content: "\f680\f680";}.fad.fa-podium-star::after, .fa-duotone.fa-podium-star::after {content: "\f758\f758";}.fad.fa-police-box::after, .fa-duotone.fa-police-box::after {content: "\e021\e021";}.fad.fa-poll-people::after, .fa-duotone.fa-poll-people::after {content: "\f759\f759";}.fad.fa-pompebled::after, .fa-duotone.fa-pompebled::after {content: "\e43d\e43d";}.fad.fa-poo::after, .fa-duotone.fa-poo::after {content: "\f2fe\f2fe";}.fad.fa-poo-storm::after, .fa-duotone.fa-poo-storm::after {content: "\f75a\f75a";}.fad.fa-poo-bolt::after, .fa-duotone.fa-poo-bolt::after {content: "\f75a\f75a";}.fad.fa-pool-8-ball::after, .fa-duotone.fa-pool-8-ball::after {content: "\e3c5\e3c5";}.fad.fa-poop::after, .fa-duotone.fa-poop::after {content: "\f619\f619";}.fad.fa-popcorn::after, .fa-duotone.fa-popcorn::after {content: "\f819\f819";}.fad.fa-popsicle::after, .fa-duotone.fa-popsicle::after {content: "\e43e\e43e";}.fad.fa-pot-food::after, .fa-duotone.fa-pot-food::after {content: "\e43f\e43f";}.fad.fa-potato::after, .fa-duotone.fa-potato::after {content: "\e440\e440";}.fad.fa-power-off::after, .fa-duotone.fa-power-off::after {content: "\f011\f011";}.fad.fa-prescription::after, .fa-duotone.fa-prescription::after {content: "\f5b1\f5b1";}.fad.fa-prescription-bottle::after, .fa-duotone.fa-prescription-bottle::after {content: "\f485\f485";}.fad.fa-prescription-bottle-medical::after, .fa-duotone.fa-prescription-bottle-medical::after {content: "\f486\f486";}.fad.fa-prescription-bottle-alt::after, .fa-duotone.fa-prescription-bottle-alt::after {content: "\f486\f486";}.fad.fa-presentation-screen::after, .fa-duotone.fa-presentation-screen::after {content: "\f685\f685";}.fad.fa-presentation::after, .fa-duotone.fa-presentation::after {content: "\f685\f685";}.fad.fa-pretzel::after, .fa-duotone.fa-pretzel::after {content: "\e441\e441";}.fad.fa-print::after, .fa-duotone.fa-print::after {content: "\f02f\f02f";}.fad.fa-print-magnifying-glass::after, .fa-duotone.fa-print-magnifying-glass::after {content: "\f81a\f81a";}.fad.fa-print-search::after, .fa-duotone.fa-print-search::after {content: "\f81a\f81a";}.fad.fa-print-slash::after, .fa-duotone.fa-print-slash::after {content: "\f686\f686";}.fad.fa-projector::after, .fa-duotone.fa-projector::after {content: "\f8d6\f8d6";}.fad.fa-pump::after, .fa-duotone.fa-pump::after {content: "\e442\e442";}.fad.fa-pump-medical::after, .fa-duotone.fa-pump-medical::after {content: "\e06a\e06a";}.fad.fa-pump-soap::after, .fa-duotone.fa-pump-soap::after {content: "\e06b\e06b";}.fad.fa-pumpkin::after, .fa-duotone.fa-pumpkin::after {content: "\f707\f707";}.fad.fa-puzzle::after, .fa-duotone.fa-puzzle::after {content: "\e443\e443";}.fad.fa-puzzle-piece::after, .fa-duotone.fa-puzzle-piece::after {content: "\f12e\f12e";}.fad.fa-puzzle-piece-simple::after, .fa-duotone.fa-puzzle-piece-simple::after {content: "\e231\e231";}.fad.fa-puzzle-piece-alt::after, .fa-duotone.fa-puzzle-piece-alt::after {content: "\e231\e231";}.fad.fa-q::after, .fa-duotone.fa-q::after {content: "\51\51";}.fad.fa-qrcode::after, .fa-duotone.fa-qrcode::after {content: "\f029\f029";}.fad.fa-question::after, .fa-duotone.fa-question::after {content: "\3f\3f";}.fad.fa-quote-left::after, .fa-duotone.fa-quote-left::after {content: "\f10d\f10d";}.fad.fa-quote-left-alt::after, .fa-duotone.fa-quote-left-alt::after {content: "\f10d\f10d";}.fad.fa-quote-right::after, .fa-duotone.fa-quote-right::after {content: "\f10e\f10e";}.fad.fa-quote-right-alt::after, .fa-duotone.fa-quote-right-alt::after {content: "\f10e\f10e";}.fad.fa-quotes::after, .fa-duotone.fa-quotes::after {content: "\e234\e234";}.fad.fa-r::after, .fa-duotone.fa-r::after {content: "\52\52";}.fad.fa-rabbit::after, .fa-duotone.fa-rabbit::after {content: "\f708\f708";}.fad.fa-rabbit-running::after, .fa-duotone.fa-rabbit-running::after {content: "\f709\f709";}.fad.fa-rabbit-fast::after, .fa-duotone.fa-rabbit-fast::after {content: "\f709\f709";}.fad.fa-racquet::after, .fa-duotone.fa-racquet::after {content: "\f45a\f45a";}.fad.fa-radar::after, .fa-duotone.fa-radar::after {content: "\e024\e024";}.fad.fa-radiation::after, .fa-duotone.fa-radiation::after {content: "\f7b9\f7b9";}.fad.fa-radio::after, .fa-duotone.fa-radio::after {content: "\f8d7\f8d7";}.fad.fa-radio-tuner::after, .fa-duotone.fa-radio-tuner::after {content: "\f8d8\f8d8";}.fad.fa-radio-alt::after, .fa-duotone.fa-radio-alt::after {content: "\f8d8\f8d8";}.fad.fa-rainbow::after, .fa-duotone.fa-rainbow::after {content: "\f75b\f75b";}.fad.fa-raindrops::after, .fa-duotone.fa-raindrops::after {content: "\f75c\f75c";}.fad.fa-ram::after, .fa-duotone.fa-ram::after {content: "\f70a\f70a";}.fad.fa-ramp-loading::after, .fa-duotone.fa-ramp-loading::after {content: "\f4d4\f4d4";}.fad.fa-ranking-star::after, .fa-duotone.fa-ranking-star::after {content: "\e561\e561";}.fad.fa-raygun::after, .fa-duotone.fa-raygun::after {content: "\e025\e025";}.fad.fa-receipt::after, .fa-duotone.fa-receipt::after {content: "\f543\f543";}.fad.fa-record-vinyl::after, .fa-duotone.fa-record-vinyl::after {content: "\f8d9\f8d9";}.fad.fa-rectangle::after, .fa-duotone.fa-rectangle::after {content: "\f2fa\f2fa";}.fad.fa-rectangle-landscape::after, .fa-duotone.fa-rectangle-landscape::after {content: "\f2fa\f2fa";}.fad.fa-rectangle-ad::after, .fa-duotone.fa-rectangle-ad::after {content: "\f641\f641";}.fad.fa-ad::after, .fa-duotone.fa-ad::after {content: "\f641\f641";}.fad.fa-rectangle-barcode::after, .fa-duotone.fa-rectangle-barcode::after {content: "\f463\f463";}.fad.fa-barcode-alt::after, .fa-duotone.fa-barcode-alt::after {content: "\f463\f463";}.fad.fa-rectangle-code::after, .fa-duotone.fa-rectangle-code::after {content: "\e322\e322";}.fad.fa-rectangle-history::after, .fa-duotone.fa-rectangle-history::after {content: "\e4a2\e4a2";}.fad.fa-rectangle-history-circle-plus::after, .fa-duotone.fa-rectangle-history-circle-plus::after {content: "\e4a3\e4a3";}.fad.fa-rectangle-history-circle-user::after, .fa-duotone.fa-rectangle-history-circle-user::after {content: "\e4a4\e4a4";}.fad.fa-rectangle-list::after, .fa-duotone.fa-rectangle-list::after {content: "\f022\f022";}.fad.fa-list-alt::after, .fa-duotone.fa-list-alt::after {content: "\f022\f022";}.fad.fa-rectangle-pro::after, .fa-duotone.fa-rectangle-pro::after {content: "\e235\e235";}.fad.fa-pro::after, .fa-duotone.fa-pro::after {content: "\e235\e235";}.fad.fa-rectangle-terminal::after, .fa-duotone.fa-rectangle-terminal::after {content: "\e236\e236";}.fad.fa-rectangle-vertical::after, .fa-duotone.fa-rectangle-vertical::after {content: "\f2fb\f2fb";}.fad.fa-rectangle-portrait::after, .fa-duotone.fa-rectangle-portrait::after {content: "\f2fb\f2fb";}.fad.fa-rectangle-vertical-history::after, .fa-duotone.fa-rectangle-vertical-history::after {content: "\e237\e237";}.fad.fa-rectangle-wide::after, .fa-duotone.fa-rectangle-wide::after {content: "\f2fc\f2fc";}.fad.fa-rectangle-xmark::after, .fa-duotone.fa-rectangle-xmark::after {content: "\f410\f410";}.fad.fa-rectangle-times::after, .fa-duotone.fa-rectangle-times::after {content: "\f410\f410";}.fad.fa-times-rectangle::after, .fa-duotone.fa-times-rectangle::after {content: "\f410\f410";}.fad.fa-window-close::after, .fa-duotone.fa-window-close::after {content: "\f410\f410";}.fad.fa-rectangles-mixed::after, .fa-duotone.fa-rectangles-mixed::after {content: "\e323\e323";}.fad.fa-recycle::after, .fa-duotone.fa-recycle::after {content: "\f1b8\f1b8";}.fad.fa-reel::after, .fa-duotone.fa-reel::after {content: "\e238\e238";}.fad.fa-refrigerator::after, .fa-duotone.fa-refrigerator::after {content: "\e026\e026";}.fad.fa-registered::after, .fa-duotone.fa-registered::after {content: "\f25d\f25d";}.fad.fa-repeat::after, .fa-duotone.fa-repeat::after {content: "\f363\f363";}.fad.fa-repeat-1::after, .fa-duotone.fa-repeat-1::after {content: "\f365\f365";}.fad.fa-reply::after, .fa-duotone.fa-reply::after {content: "\f3e5\f3e5";}.fad.fa-mail-reply::after, .fa-duotone.fa-mail-reply::after {content: "\f3e5\f3e5";}.fad.fa-reply-all::after, .fa-duotone.fa-reply-all::after {content: "\f122\f122";}.fad.fa-mail-reply-all::after, .fa-duotone.fa-mail-reply-all::after {content: "\f122\f122";}.fad.fa-reply-clock::after, .fa-duotone.fa-reply-clock::after {content: "\e239\e239";}.fad.fa-reply-time::after, .fa-duotone.fa-reply-time::after {content: "\e239\e239";}.fad.fa-republican::after, .fa-duotone.fa-republican::after {content: "\f75e\f75e";}.fad.fa-restroom::after, .fa-duotone.fa-restroom::after {content: "\f7bd\f7bd";}.fad.fa-restroom-simple::after, .fa-duotone.fa-restroom-simple::after {content: "\e23a\e23a";}.fad.fa-retweet::after, .fa-duotone.fa-retweet::after {content: "\f079\f079";}.fad.fa-rhombus::after, .fa-duotone.fa-rhombus::after {content: "\e23b\e23b";}.fad.fa-ribbon::after, .fa-duotone.fa-ribbon::after {content: "\f4d6\f4d6";}.fad.fa-right::after, .fa-duotone.fa-right::after {content: "\f356\f356";}.fad.fa-arrow-alt-right::after, .fa-duotone.fa-arrow-alt-right::after {content: "\f356\f356";}.fad.fa-right-from-bracket::after, .fa-duotone.fa-right-from-bracket::after {content: "\f2f5\f2f5";}.fad.fa-sign-out-alt::after, .fa-duotone.fa-sign-out-alt::after {content: "\f2f5\f2f5";}.fad.fa-right-from-line::after, .fa-duotone.fa-right-from-line::after {content: "\f347\f347";}.fad.fa-arrow-alt-from-left::after, .fa-duotone.fa-arrow-alt-from-left::after {content: "\f347\f347";}.fad.fa-right-left::after, .fa-duotone.fa-right-left::after {content: "\f362\f362";}.fad.fa-exchange-alt::after, .fa-duotone.fa-exchange-alt::after {content: "\f362\f362";}.fad.fa-right-long::after, .fa-duotone.fa-right-long::after {content: "\f30b\f30b";}.fad.fa-long-arrow-alt-right::after, .fa-duotone.fa-long-arrow-alt-right::after {content: "\f30b\f30b";}.fad.fa-right-long-to-line::after, .fa-duotone.fa-right-long-to-line::after {content: "\e444\e444";}.fad.fa-right-to-bracket::after, .fa-duotone.fa-right-to-bracket::after {content: "\f2f6\f2f6";}.fad.fa-sign-in-alt::after, .fa-duotone.fa-sign-in-alt::after {content: "\f2f6\f2f6";}.fad.fa-right-to-line::after, .fa-duotone.fa-right-to-line::after {content: "\f34c\f34c";}.fad.fa-arrow-alt-to-right::after, .fa-duotone.fa-arrow-alt-to-right::after {content: "\f34c\f34c";}.fad.fa-ring::after, .fa-duotone.fa-ring::after {content: "\f70b\f70b";}.fad.fa-rings-wedding::after, .fa-duotone.fa-rings-wedding::after {content: "\f81b\f81b";}.fad.fa-road::after, .fa-duotone.fa-road::after {content: "\f018\f018";}.fad.fa-road-barrier::after, .fa-duotone.fa-road-barrier::after {content: "\e562\e562";}.fad.fa-road-bridge::after, .fa-duotone.fa-road-bridge::after {content: "\e563\e563";}.fad.fa-road-circle-check::after, .fa-duotone.fa-road-circle-check::after {content: "\e564\e564";}.fad.fa-road-circle-exclamation::after, .fa-duotone.fa-road-circle-exclamation::after {content: "\e565\e565";}.fad.fa-road-circle-xmark::after, .fa-duotone.fa-road-circle-xmark::after {content: "\e566\e566";}.fad.fa-road-lock::after, .fa-duotone.fa-road-lock::after {content: "\e567\e567";}.fad.fa-road-spikes::after, .fa-duotone.fa-road-spikes::after {content: "\e568\e568";}.fad.fa-robot::after, .fa-duotone.fa-robot::after {content: "\f544\f544";}.fad.fa-robot-astromech::after, .fa-duotone.fa-robot-astromech::after {content: "\e2d2\e2d2";}.fad.fa-rocket::after, .fa-duotone.fa-rocket::after {content: "\f135\f135";}.fad.fa-rocket-launch::after, .fa-duotone.fa-rocket-launch::after {content: "\e027\e027";}.fad.fa-roller-coaster::after, .fa-duotone.fa-roller-coaster::after {content: "\e324\e324";}.fad.fa-rotate::after, .fa-duotone.fa-rotate::after {content: "\f2f1\f2f1";}.fad.fa-sync-alt::after, .fa-duotone.fa-sync-alt::after {content: "\f2f1\f2f1";}.fad.fa-rotate-exclamation::after, .fa-duotone.fa-rotate-exclamation::after {content: "\e23c\e23c";}.fad.fa-rotate-left::after, .fa-duotone.fa-rotate-left::after {content: "\f2ea\f2ea";}.fad.fa-rotate-back::after, .fa-duotone.fa-rotate-back::after {content: "\f2ea\f2ea";}.fad.fa-rotate-backward::after, .fa-duotone.fa-rotate-backward::after {content: "\f2ea\f2ea";}.fad.fa-undo-alt::after, .fa-duotone.fa-undo-alt::after {content: "\f2ea\f2ea";}.fad.fa-rotate-right::after, .fa-duotone.fa-rotate-right::after {content: "\f2f9\f2f9";}.fad.fa-redo-alt::after, .fa-duotone.fa-redo-alt::after {content: "\f2f9\f2f9";}.fad.fa-rotate-forward::after, .fa-duotone.fa-rotate-forward::after {content: "\f2f9\f2f9";}.fad.fa-route::after, .fa-duotone.fa-route::after {content: "\f4d7\f4d7";}.fad.fa-route-highway::after, .fa-duotone.fa-route-highway::after {content: "\f61a\f61a";}.fad.fa-route-interstate::after, .fa-duotone.fa-route-interstate::after {content: "\f61b\f61b";}.fad.fa-router::after, .fa-duotone.fa-router::after {content: "\f8da\f8da";}.fad.fa-rss::after, .fa-duotone.fa-rss::after {content: "\f09e\f09e";}.fad.fa-feed::after, .fa-duotone.fa-feed::after {content: "\f09e\f09e";}.fad.fa-ruble-sign::after, .fa-duotone.fa-ruble-sign::after {content: "\f158\f158";}.fad.fa-rouble::after, .fa-duotone.fa-rouble::after {content: "\f158\f158";}.fad.fa-rub::after, .fa-duotone.fa-rub::after {content: "\f158\f158";}.fad.fa-ruble::after, .fa-duotone.fa-ruble::after {content: "\f158\f158";}.fad.fa-rug::after, .fa-duotone.fa-rug::after {content: "\e569\e569";}.fad.fa-rugby-ball::after, .fa-duotone.fa-rugby-ball::after {content: "\e3c6\e3c6";}.fad.fa-ruler::after, .fa-duotone.fa-ruler::after {content: "\f545\f545";}.fad.fa-ruler-combined::after, .fa-duotone.fa-ruler-combined::after {content: "\f546\f546";}.fad.fa-ruler-horizontal::after, .fa-duotone.fa-ruler-horizontal::after {content: "\f547\f547";}.fad.fa-ruler-triangle::after, .fa-duotone.fa-ruler-triangle::after {content: "\f61c\f61c";}.fad.fa-ruler-vertical::after, .fa-duotone.fa-ruler-vertical::after {content: "\f548\f548";}.fad.fa-rupee-sign::after, .fa-duotone.fa-rupee-sign::after {content: "\f156\f156";}.fad.fa-rupee::after, .fa-duotone.fa-rupee::after {content: "\f156\f156";}.fad.fa-rupiah-sign::after, .fa-duotone.fa-rupiah-sign::after {content: "\e23d\e23d";}.fad.fa-rv::after, .fa-duotone.fa-rv::after {content: "\f7be\f7be";}.fad.fa-s::after, .fa-duotone.fa-s::after {content: "\53\53";}.fad.fa-sack::after, .fa-duotone.fa-sack::after {content: "\f81c\f81c";}.fad.fa-sack-dollar::after, .fa-duotone.fa-sack-dollar::after {content: "\f81d\f81d";}.fad.fa-sack-xmark::after, .fa-duotone.fa-sack-xmark::after {content: "\e56a\e56a";}.fad.fa-sailboat::after, .fa-duotone.fa-sailboat::after {content: "\e445\e445";}.fad.fa-salad::after, .fa-duotone.fa-salad::after {content: "\f81e\f81e";}.fad.fa-bowl-salad::after, .fa-duotone.fa-bowl-salad::after {content: "\f81e\f81e";}.fad.fa-salt-shaker::after, .fa-duotone.fa-salt-shaker::after {content: "\e446\e446";}.fad.fa-sandwich::after, .fa-duotone.fa-sandwich::after {content: "\f81f\f81f";}.fad.fa-satellite::after, .fa-duotone.fa-satellite::after {content: "\f7bf\f7bf";}.fad.fa-satellite-dish::after, .fa-duotone.fa-satellite-dish::after {content: "\f7c0\f7c0";}.fad.fa-sausage::after, .fa-duotone.fa-sausage::after {content: "\f820\f820";}.fad.fa-saxophone::after, .fa-duotone.fa-saxophone::after {content: "\f8dc\f8dc";}.fad.fa-saxophone-fire::after, .fa-duotone.fa-saxophone-fire::after {content: "\f8db\f8db";}.fad.fa-sax-hot::after, .fa-duotone.fa-sax-hot::after {content: "\f8db\f8db";}.fad.fa-scale-balanced::after, .fa-duotone.fa-scale-balanced::after {content: "\f24e\f24e";}.fad.fa-balance-scale::after, .fa-duotone.fa-balance-scale::after {content: "\f24e\f24e";}.fad.fa-scale-unbalanced::after, .fa-duotone.fa-scale-unbalanced::after {content: "\f515\f515";}.fad.fa-balance-scale-left::after, .fa-duotone.fa-balance-scale-left::after {content: "\f515\f515";}.fad.fa-scale-unbalanced-flip::after, .fa-duotone.fa-scale-unbalanced-flip::after {content: "\f516\f516";}.fad.fa-balance-scale-right::after, .fa-duotone.fa-balance-scale-right::after {content: "\f516\f516";}.fad.fa-scalpel::after, .fa-duotone.fa-scalpel::after {content: "\f61d\f61d";}.fad.fa-scalpel-line-dashed::after, .fa-duotone.fa-scalpel-line-dashed::after {content: "\f61e\f61e";}.fad.fa-scalpel-path::after, .fa-duotone.fa-scalpel-path::after {content: "\f61e\f61e";}.fad.fa-scanner::after, .fa-duotone.fa-scanner::after {content: "\f8f3\f8f3";}.fad.fa-scanner-image::after, .fa-duotone.fa-scanner-image::after {content: "\f8f3\f8f3";}.fad.fa-scanner-gun::after, .fa-duotone.fa-scanner-gun::after {content: "\f488\f488";}.fad.fa-scanner-keyboard::after, .fa-duotone.fa-scanner-keyboard::after {content: "\f489\f489";}.fad.fa-scanner-touchscreen::after, .fa-duotone.fa-scanner-touchscreen::after {content: "\f48a\f48a";}.fad.fa-scarecrow::after, .fa-duotone.fa-scarecrow::after {content: "\f70d\f70d";}.fad.fa-scarf::after, .fa-duotone.fa-scarf::after {content: "\f7c1\f7c1";}.fad.fa-school::after, .fa-duotone.fa-school::after {content: "\f549\f549";}.fad.fa-school-circle-check::after, .fa-duotone.fa-school-circle-check::after {content: "\e56b\e56b";}.fad.fa-school-circle-exclamation::after, .fa-duotone.fa-school-circle-exclamation::after {content: "\e56c\e56c";}.fad.fa-school-circle-xmark::after, .fa-duotone.fa-school-circle-xmark::after {content: "\e56d\e56d";}.fad.fa-school-flag::after, .fa-duotone.fa-school-flag::after {content: "\e56e\e56e";}.fad.fa-school-lock::after, .fa-duotone.fa-school-lock::after {content: "\e56f\e56f";}.fad.fa-scissors::after, .fa-duotone.fa-scissors::after {content: "\f0c4\f0c4";}.fad.fa-cut::after, .fa-duotone.fa-cut::after {content: "\f0c4\f0c4";}.fad.fa-screen-users::after, .fa-duotone.fa-screen-users::after {content: "\f63d\f63d";}.fad.fa-users-class::after, .fa-duotone.fa-users-class::after {content: "\f63d\f63d";}.fad.fa-screencast::after, .fa-duotone.fa-screencast::after {content: "\e23e\e23e";}.fad.fa-screwdriver::after, .fa-duotone.fa-screwdriver::after {content: "\f54a\f54a";}.fad.fa-screwdriver-wrench::after, .fa-duotone.fa-screwdriver-wrench::after {content: "\f7d9\f7d9";}.fad.fa-tools::after, .fa-duotone.fa-tools::after {content: "\f7d9\f7d9";}.fad.fa-scribble::after, .fa-duotone.fa-scribble::after {content: "\e23f\e23f";}.fad.fa-scroll::after, .fa-duotone.fa-scroll::after {content: "\f70e\f70e";}.fad.fa-scroll-old::after, .fa-duotone.fa-scroll-old::after {content: "\f70f\f70f";}.fad.fa-scroll-torah::after, .fa-duotone.fa-scroll-torah::after {content: "\f6a0\f6a0";}.fad.fa-torah::after, .fa-duotone.fa-torah::after {content: "\f6a0\f6a0";}.fad.fa-scrubber::after, .fa-duotone.fa-scrubber::after {content: "\f2f8\f2f8";}.fad.fa-scythe::after, .fa-duotone.fa-scythe::after {content: "\f710\f710";}.fad.fa-sd-card::after, .fa-duotone.fa-sd-card::after {content: "\f7c2\f7c2";}.fad.fa-sd-cards::after, .fa-duotone.fa-sd-cards::after {content: "\e240\e240";}.fad.fa-seal::after, .fa-duotone.fa-seal::after {content: "\e241\e241";}.fad.fa-seal-exclamation::after, .fa-duotone.fa-seal-exclamation::after {content: "\e242\e242";}.fad.fa-seal-question::after, .fa-duotone.fa-seal-question::after {content: "\e243\e243";}.fad.fa-seat-airline::after, .fa-duotone.fa-seat-airline::after {content: "\e244\e244";}.fad.fa-section::after, .fa-duotone.fa-section::after {content: "\e447\e447";}.fad.fa-seedling::after, .fa-duotone.fa-seedling::after {content: "\f4d8\f4d8";}.fad.fa-sprout::after, .fa-duotone.fa-sprout::after {content: "\f4d8\f4d8";}.fad.fa-semicolon::after, .fa-duotone.fa-semicolon::after {content: "\3b\3b";}.fad.fa-send-back::after, .fa-duotone.fa-send-back::after {content: "\f87e\f87e";}.fad.fa-send-backward::after, .fa-duotone.fa-send-backward::after {content: "\f87f\f87f";}.fad.fa-sensor::after, .fa-duotone.fa-sensor::after {content: "\e028\e028";}.fad.fa-sensor-cloud::after, .fa-duotone.fa-sensor-cloud::after {content: "\e02c\e02c";}.fad.fa-sensor-smoke::after, .fa-duotone.fa-sensor-smoke::after {content: "\e02c\e02c";}.fad.fa-sensor-fire::after, .fa-duotone.fa-sensor-fire::after {content: "\e02a\e02a";}.fad.fa-sensor-on::after, .fa-duotone.fa-sensor-on::after {content: "\e02b\e02b";}.fad.fa-sensor-triangle-exclamation::after, .fa-duotone.fa-sensor-triangle-exclamation::after {content: "\e029\e029";}.fad.fa-sensor-alert::after, .fa-duotone.fa-sensor-alert::after {content: "\e029\e029";}.fad.fa-server::after, .fa-duotone.fa-server::after {content: "\f233\f233";}.fad.fa-shapes::after, .fa-duotone.fa-shapes::after {content: "\f61f\f61f";}.fad.fa-triangle-circle-square::after, .fa-duotone.fa-triangle-circle-square::after {content: "\f61f\f61f";}.fad.fa-share::after, .fa-duotone.fa-share::after {content: "\f064\f064";}.fad.fa-arrow-turn-right::after, .fa-duotone.fa-arrow-turn-right::after {content: "\f064\f064";}.fad.fa-mail-forward::after, .fa-duotone.fa-mail-forward::after {content: "\f064\f064";}.fad.fa-share-all::after, .fa-duotone.fa-share-all::after {content: "\f367\f367";}.fad.fa-share-from-square::after, .fa-duotone.fa-share-from-square::after {content: "\f14d\f14d";}.fad.fa-share-square::after, .fa-duotone.fa-share-square::after {content: "\f14d\f14d";}.fad.fa-share-nodes::after, .fa-duotone.fa-share-nodes::after {content: "\f1e0\f1e0";}.fad.fa-share-alt::after, .fa-duotone.fa-share-alt::after {content: "\f1e0\f1e0";}.fad.fa-sheep::after, .fa-duotone.fa-sheep::after {content: "\f711\f711";}.fad.fa-sheet-plastic::after, .fa-duotone.fa-sheet-plastic::after {content: "\e571\e571";}.fad.fa-shekel-sign::after, .fa-duotone.fa-shekel-sign::after {content: "\f20b\f20b";}.fad.fa-ils::after, .fa-duotone.fa-ils::after {content: "\f20b\f20b";}.fad.fa-shekel::after, .fa-duotone.fa-shekel::after {content: "\f20b\f20b";}.fad.fa-sheqel::after, .fa-duotone.fa-sheqel::after {content: "\f20b\f20b";}.fad.fa-sheqel-sign::after, .fa-duotone.fa-sheqel-sign::after {content: "\f20b\f20b";}.fad.fa-shelves::after, .fa-duotone.fa-shelves::after {content: "\f480\f480";}.fad.fa-inventory::after, .fa-duotone.fa-inventory::after {content: "\f480\f480";}.fad.fa-shelves-empty::after, .fa-duotone.fa-shelves-empty::after {content: "\e246\e246";}.fad.fa-shield::after, .fa-duotone.fa-shield::after {content: "\f132\f132";}.fad.fa-shield-blank::after, .fa-duotone.fa-shield-blank::after {content: "\f132\f132";}.fad.fa-shield-cat::after, .fa-duotone.fa-shield-cat::after {content: "\e572\e572";}.fad.fa-shield-check::after, .fa-duotone.fa-shield-check::after {content: "\f2f7\f2f7";}.fad.fa-shield-cross::after, .fa-duotone.fa-shield-cross::after {content: "\f712\f712";}.fad.fa-shield-dog::after, .fa-duotone.fa-shield-dog::after {content: "\e573\e573";}.fad.fa-shield-exclamation::after, .fa-duotone.fa-shield-exclamation::after {content: "\e247\e247";}.fad.fa-shield-halved::after, .fa-duotone.fa-shield-halved::after {content: "\f3ed\f3ed";}.fad.fa-shield-alt::after, .fa-duotone.fa-shield-alt::after {content: "\f3ed\f3ed";}.fad.fa-shield-heart::after, .fa-duotone.fa-shield-heart::after {content: "\e574\e574";}.fad.fa-shield-keyhole::after, .fa-duotone.fa-shield-keyhole::after {content: "\e248\e248";}.fad.fa-shield-minus::after, .fa-duotone.fa-shield-minus::after {content: "\e249\e249";}.fad.fa-shield-plus::after, .fa-duotone.fa-shield-plus::after {content: "\e24a\e24a";}.fad.fa-shield-quartered::after, .fa-duotone.fa-shield-quartered::after {content: "\e575\e575";}.fad.fa-shield-slash::after, .fa-duotone.fa-shield-slash::after {content: "\e24b\e24b";}.fad.fa-shield-virus::after, .fa-duotone.fa-shield-virus::after {content: "\e06c\e06c";}.fad.fa-shield-xmark::after, .fa-duotone.fa-shield-xmark::after {content: "\e24c\e24c";}.fad.fa-shield-times::after, .fa-duotone.fa-shield-times::after {content: "\e24c\e24c";}.fad.fa-ship::after, .fa-duotone.fa-ship::after {content: "\f21a\f21a";}.fad.fa-shirt::after, .fa-duotone.fa-shirt::after {content: "\f553\f553";}.fad.fa-t-shirt::after, .fa-duotone.fa-t-shirt::after {content: "\f553\f553";}.fad.fa-tshirt::after, .fa-duotone.fa-tshirt::after {content: "\f553\f553";}.fad.fa-shirt-long-sleeve::after, .fa-duotone.fa-shirt-long-sleeve::after {content: "\e3c7\e3c7";}.fad.fa-shirt-running::after, .fa-duotone.fa-shirt-running::after {content: "\e3c8\e3c8";}.fad.fa-shirt-tank-top::after, .fa-duotone.fa-shirt-tank-top::after {content: "\e3c9\e3c9";}.fad.fa-shish-kebab::after, .fa-duotone.fa-shish-kebab::after {content: "\f821\f821";}.fad.fa-shoe-prints::after, .fa-duotone.fa-shoe-prints::after {content: "\f54b\f54b";}.fad.fa-shop::after, .fa-duotone.fa-shop::after {content: "\f54f\f54f";}.fad.fa-store-alt::after, .fa-duotone.fa-store-alt::after {content: "\f54f\f54f";}.fad.fa-shop-lock::after, .fa-duotone.fa-shop-lock::after {content: "\e4a5\e4a5";}.fad.fa-shop-slash::after, .fa-duotone.fa-shop-slash::after {content: "\e070\e070";}.fad.fa-store-alt-slash::after, .fa-duotone.fa-store-alt-slash::after {content: "\e070\e070";}.fad.fa-shovel::after, .fa-duotone.fa-shovel::after {content: "\f713\f713";}.fad.fa-shovel-snow::after, .fa-duotone.fa-shovel-snow::after {content: "\f7c3\f7c3";}.fad.fa-shower::after, .fa-duotone.fa-shower::after {content: "\f2cc\f2cc";}.fad.fa-shower-down::after, .fa-duotone.fa-shower-down::after {content: "\e24d\e24d";}.fad.fa-shower-alt::after, .fa-duotone.fa-shower-alt::after {content: "\e24d\e24d";}.fad.fa-shredder::after, .fa-duotone.fa-shredder::after {content: "\f68a\f68a";}.fad.fa-shrimp::after, .fa-duotone.fa-shrimp::after {content: "\e448\e448";}.fad.fa-shuffle::after, .fa-duotone.fa-shuffle::after {content: "\f074\f074";}.fad.fa-random::after, .fa-duotone.fa-random::after {content: "\f074\f074";}.fad.fa-shutters::after, .fa-duotone.fa-shutters::after {content: "\e449\e449";}.fad.fa-shuttle-space::after, .fa-duotone.fa-shuttle-space::after {content: "\f197\f197";}.fad.fa-space-shuttle::after, .fa-duotone.fa-space-shuttle::after {content: "\f197\f197";}.fad.fa-shuttlecock::after, .fa-duotone.fa-shuttlecock::after {content: "\f45b\f45b";}.fad.fa-sickle::after, .fa-duotone.fa-sickle::after {content: "\f822\f822";}.fad.fa-sidebar::after, .fa-duotone.fa-sidebar::after {content: "\e24e\e24e";}.fad.fa-sidebar-flip::after, .fa-duotone.fa-sidebar-flip::after {content: "\e24f\e24f";}.fad.fa-sigma::after, .fa-duotone.fa-sigma::after {content: "\f68b\f68b";}.fad.fa-sign-hanging::after, .fa-duotone.fa-sign-hanging::after {content: "\f4d9\f4d9";}.fad.fa-sign::after, .fa-duotone.fa-sign::after {content: "\f4d9\f4d9";}.fad.fa-signal::after, .fa-duotone.fa-signal::after {content: "\f012\f012";}.fad.fa-signal-5::after, .fa-duotone.fa-signal-5::after {content: "\f012\f012";}.fad.fa-signal-perfect::after, .fa-duotone.fa-signal-perfect::after {content: "\f012\f012";}.fad.fa-signal-bars::after, .fa-duotone.fa-signal-bars::after {content: "\f690\f690";}.fad.fa-signal-alt::after, .fa-duotone.fa-signal-alt::after {content: "\f690\f690";}.fad.fa-signal-alt-4::after, .fa-duotone.fa-signal-alt-4::after {content: "\f690\f690";}.fad.fa-signal-bars-strong::after, .fa-duotone.fa-signal-bars-strong::after {content: "\f690\f690";}.fad.fa-signal-bars-fair::after, .fa-duotone.fa-signal-bars-fair::after {content: "\f692\f692";}.fad.fa-signal-alt-2::after, .fa-duotone.fa-signal-alt-2::after {content: "\f692\f692";}.fad.fa-signal-bars-good::after, .fa-duotone.fa-signal-bars-good::after {content: "\f693\f693";}.fad.fa-signal-alt-3::after, .fa-duotone.fa-signal-alt-3::after {content: "\f693\f693";}.fad.fa-signal-bars-slash::after, .fa-duotone.fa-signal-bars-slash::after {content: "\f694\f694";}.fad.fa-signal-alt-slash::after, .fa-duotone.fa-signal-alt-slash::after {content: "\f694\f694";}.fad.fa-signal-bars-weak::after, .fa-duotone.fa-signal-bars-weak::after {content: "\f691\f691";}.fad.fa-signal-alt-1::after, .fa-duotone.fa-signal-alt-1::after {content: "\f691\f691";}.fad.fa-signal-fair::after, .fa-duotone.fa-signal-fair::after {content: "\f68d\f68d";}.fad.fa-signal-2::after, .fa-duotone.fa-signal-2::after {content: "\f68d\f68d";}.fad.fa-signal-good::after, .fa-duotone.fa-signal-good::after {content: "\f68e\f68e";}.fad.fa-signal-3::after, .fa-duotone.fa-signal-3::after {content: "\f68e\f68e";}.fad.fa-signal-slash::after, .fa-duotone.fa-signal-slash::after {content: "\f695\f695";}.fad.fa-signal-stream::after, .fa-duotone.fa-signal-stream::after {content: "\f8dd\f8dd";}.fad.fa-signal-stream-slash::after, .fa-duotone.fa-signal-stream-slash::after {content: "\e250\e250";}.fad.fa-signal-strong::after, .fa-duotone.fa-signal-strong::after {content: "\f68f\f68f";}.fad.fa-signal-4::after, .fa-duotone.fa-signal-4::after {content: "\f68f\f68f";}.fad.fa-signal-weak::after, .fa-duotone.fa-signal-weak::after {content: "\f68c\f68c";}.fad.fa-signal-1::after, .fa-duotone.fa-signal-1::after {content: "\f68c\f68c";}.fad.fa-signature::after, .fa-duotone.fa-signature::after {content: "\f5b7\f5b7";}.fad.fa-signature-lock::after, .fa-duotone.fa-signature-lock::after {content: "\e3ca\e3ca";}.fad.fa-signature-slash::after, .fa-duotone.fa-signature-slash::after {content: "\e3cb\e3cb";}.fad.fa-signs-post::after, .fa-duotone.fa-signs-post::after {content: "\f277\f277";}.fad.fa-map-signs::after, .fa-duotone.fa-map-signs::after {content: "\f277\f277";}.fad.fa-sim-card::after, .fa-duotone.fa-sim-card::after {content: "\f7c4\f7c4";}.fad.fa-sim-cards::after, .fa-duotone.fa-sim-cards::after {content: "\e251\e251";}.fad.fa-sink::after, .fa-duotone.fa-sink::after {content: "\e06d\e06d";}.fad.fa-siren::after, .fa-duotone.fa-siren::after {content: "\e02d\e02d";}.fad.fa-siren-on::after, .fa-duotone.fa-siren-on::after {content: "\e02e\e02e";}.fad.fa-sitemap::after, .fa-duotone.fa-sitemap::after {content: "\f0e8\f0e8";}.fad.fa-skeleton::after, .fa-duotone.fa-skeleton::after {content: "\f620\f620";}.fad.fa-ski-boot::after, .fa-duotone.fa-ski-boot::after {content: "\e3cc\e3cc";}.fad.fa-ski-boot-ski::after, .fa-duotone.fa-ski-boot-ski::after {content: "\e3cd\e3cd";}.fad.fa-skull::after, .fa-duotone.fa-skull::after {content: "\f54c\f54c";}.fad.fa-skull-cow::after, .fa-duotone.fa-skull-cow::after {content: "\f8de\f8de";}.fad.fa-skull-crossbones::after, .fa-duotone.fa-skull-crossbones::after {content: "\f714\f714";}.fad.fa-slash::after, .fa-duotone.fa-slash::after {content: "\f715\f715";}.fad.fa-slash-back::after, .fa-duotone.fa-slash-back::after {content: "\5c\5c";}.fad.fa-slash-forward::after, .fa-duotone.fa-slash-forward::after {content: "\2f\2f";}.fad.fa-sleigh::after, .fa-duotone.fa-sleigh::after {content: "\f7cc\f7cc";}.fad.fa-slider::after, .fa-duotone.fa-slider::after {content: "\e252\e252";}.fad.fa-sliders::after, .fa-duotone.fa-sliders::after {content: "\f1de\f1de";}.fad.fa-sliders-h::after, .fa-duotone.fa-sliders-h::after {content: "\f1de\f1de";}.fad.fa-sliders-simple::after, .fa-duotone.fa-sliders-simple::after {content: "\e253\e253";}.fad.fa-sliders-up::after, .fa-duotone.fa-sliders-up::after {content: "\f3f1\f3f1";}.fad.fa-sliders-v::after, .fa-duotone.fa-sliders-v::after {content: "\f3f1\f3f1";}.fad.fa-slot-machine::after, .fa-duotone.fa-slot-machine::after {content: "\e3ce\e3ce";}.fad.fa-smog::after, .fa-duotone.fa-smog::after {content: "\f75f\f75f";}.fad.fa-smoke::after, .fa-duotone.fa-smoke::after {content: "\f760\f760";}.fad.fa-smoking::after, .fa-duotone.fa-smoking::after {content: "\f48d\f48d";}.fad.fa-snake::after, .fa-duotone.fa-snake::after {content: "\f716\f716";}.fad.fa-snooze::after, .fa-duotone.fa-snooze::after {content: "\f880\f880";}.fad.fa-zzz::after, .fa-duotone.fa-zzz::after {content: "\f880\f880";}.fad.fa-snow-blowing::after, .fa-duotone.fa-snow-blowing::after {content: "\f761\f761";}.fad.fa-snowflake::after, .fa-duotone.fa-snowflake::after {content: "\f2dc\f2dc";}.fad.fa-snowflakes::after, .fa-duotone.fa-snowflakes::after {content: "\f7cf\f7cf";}.fad.fa-snowman::after, .fa-duotone.fa-snowman::after {content: "\f7d0\f7d0";}.fad.fa-snowman-head::after, .fa-duotone.fa-snowman-head::after {content: "\f79b\f79b";}.fad.fa-frosty-head::after, .fa-duotone.fa-frosty-head::after {content: "\f79b\f79b";}.fad.fa-snowplow::after, .fa-duotone.fa-snowplow::after {content: "\f7d2\f7d2";}.fad.fa-soap::after, .fa-duotone.fa-soap::after {content: "\e06e\e06e";}.fad.fa-socks::after, .fa-duotone.fa-socks::after {content: "\f696\f696";}.fad.fa-soft-serve::after, .fa-duotone.fa-soft-serve::after {content: "\e400\e400";}.fad.fa-creemee::after, .fa-duotone.fa-creemee::after {content: "\e400\e400";}.fad.fa-solar-panel::after, .fa-duotone.fa-solar-panel::after {content: "\f5ba\f5ba";}.fad.fa-solar-system::after, .fa-duotone.fa-solar-system::after {content: "\e02f\e02f";}.fad.fa-sort::after, .fa-duotone.fa-sort::after {content: "\f0dc\f0dc";}.fad.fa-unsorted::after, .fa-duotone.fa-unsorted::after {content: "\f0dc\f0dc";}.fad.fa-sort-down::after, .fa-duotone.fa-sort-down::after {content: "\f0dd\f0dd";}.fad.fa-sort-desc::after, .fa-duotone.fa-sort-desc::after {content: "\f0dd\f0dd";}.fad.fa-sort-up::after, .fa-duotone.fa-sort-up::after {content: "\f0de\f0de";}.fad.fa-sort-asc::after, .fa-duotone.fa-sort-asc::after {content: "\f0de\f0de";}.fad.fa-spa::after, .fa-duotone.fa-spa::after {content: "\f5bb\f5bb";}.fad.fa-space-station-moon::after, .fa-duotone.fa-space-station-moon::after {content: "\e033\e033";}.fad.fa-space-station-moon-construction::after, .fa-duotone.fa-space-station-moon-construction::after {content: "\e034\e034";}.fad.fa-space-station-moon-alt::after, .fa-duotone.fa-space-station-moon-alt::after {content: "\e034\e034";}.fad.fa-spade::after, .fa-duotone.fa-spade::after {content: "\f2f4\f2f4";}.fad.fa-spaghetti-monster-flying::after, .fa-duotone.fa-spaghetti-monster-flying::after {content: "\f67b\f67b";}.fad.fa-pastafarianism::after, .fa-duotone.fa-pastafarianism::after {content: "\f67b\f67b";}.fad.fa-sparkles::after, .fa-duotone.fa-sparkles::after {content: "\f890\f890";}.fad.fa-speaker::after, .fa-duotone.fa-speaker::after {content: "\f8df\f8df";}.fad.fa-speakers::after, .fa-duotone.fa-speakers::after {content: "\f8e0\f8e0";}.fad.fa-spell-check::after, .fa-duotone.fa-spell-check::after {content: "\f891\f891";}.fad.fa-spider::after, .fa-duotone.fa-spider::after {content: "\f717\f717";}.fad.fa-spider-black-widow::after, .fa-duotone.fa-spider-black-widow::after {content: "\f718\f718";}.fad.fa-spider-web::after, .fa-duotone.fa-spider-web::after {content: "\f719\f719";}.fad.fa-spinner::after, .fa-duotone.fa-spinner::after {content: "\f110\f110";}.fad.fa-spinner-third::after, .fa-duotone.fa-spinner-third::after {content: "\f3f4\f3f4";}.fad.fa-split::after, .fa-duotone.fa-split::after {content: "\e254\e254";}.fad.fa-splotch::after, .fa-duotone.fa-splotch::after {content: "\f5bc\f5bc";}.fad.fa-spoon::after, .fa-duotone.fa-spoon::after {content: "\f2e5\f2e5";}.fad.fa-utensil-spoon::after, .fa-duotone.fa-utensil-spoon::after {content: "\f2e5\f2e5";}.fad.fa-sportsball::after, .fa-duotone.fa-sportsball::after {content: "\e44b\e44b";}.fad.fa-spray-can::after, .fa-duotone.fa-spray-can::after {content: "\f5bd\f5bd";}.fad.fa-spray-can-sparkles::after, .fa-duotone.fa-spray-can-sparkles::after {content: "\f5d0\f5d0";}.fad.fa-air-freshener::after, .fa-duotone.fa-air-freshener::after {content: "\f5d0\f5d0";}.fad.fa-sprinkler::after, .fa-duotone.fa-sprinkler::after {content: "\e035\e035";}.fad.fa-sprinkler-ceiling::after, .fa-duotone.fa-sprinkler-ceiling::after {content: "\e44c\e44c";}.fad.fa-square::after, .fa-duotone.fa-square::after {content: "\f0c8\f0c8";}.fad.fa-square-0::after, .fa-duotone.fa-square-0::after {content: "\e255\e255";}.fad.fa-square-1::after, .fa-duotone.fa-square-1::after {content: "\e256\e256";}.fad.fa-square-2::after, .fa-duotone.fa-square-2::after {content: "\e257\e257";}.fad.fa-square-3::after, .fa-duotone.fa-square-3::after {content: "\e258\e258";}.fad.fa-square-4::after, .fa-duotone.fa-square-4::after {content: "\e259\e259";}.fad.fa-square-5::after, .fa-duotone.fa-square-5::after {content: "\e25a\e25a";}.fad.fa-square-6::after, .fa-duotone.fa-square-6::after {content: "\e25b\e25b";}.fad.fa-square-7::after, .fa-duotone.fa-square-7::after {content: "\e25c\e25c";}.fad.fa-square-8::after, .fa-duotone.fa-square-8::after {content: "\e25d\e25d";}.fad.fa-square-9::after, .fa-duotone.fa-square-9::after {content: "\e25e\e25e";}.fad.fa-square-a::after, .fa-duotone.fa-square-a::after {content: "\e25f\e25f";}.fad.fa-square-a-lock::after, .fa-duotone.fa-square-a-lock::after {content: "\e44d\e44d";}.fad.fa-square-ampersand::after, .fa-duotone.fa-square-ampersand::after {content: "\e260\e260";}.fad.fa-square-arrow-down::after, .fa-duotone.fa-square-arrow-down::after {content: "\f339\f339";}.fad.fa-arrow-square-down::after, .fa-duotone.fa-arrow-square-down::after {content: "\f339\f339";}.fad.fa-square-arrow-down-left::after, .fa-duotone.fa-square-arrow-down-left::after {content: "\e261\e261";}.fad.fa-square-arrow-down-right::after, .fa-duotone.fa-square-arrow-down-right::after {content: "\e262\e262";}.fad.fa-square-arrow-left::after, .fa-duotone.fa-square-arrow-left::after {content: "\f33a\f33a";}.fad.fa-arrow-square-left::after, .fa-duotone.fa-arrow-square-left::after {content: "\f33a\f33a";}.fad.fa-square-arrow-right::after, .fa-duotone.fa-square-arrow-right::after {content: "\f33b\f33b";}.fad.fa-arrow-square-right::after, .fa-duotone.fa-arrow-square-right::after {content: "\f33b\f33b";}.fad.fa-square-arrow-up::after, .fa-duotone.fa-square-arrow-up::after {content: "\f33c\f33c";}.fad.fa-arrow-square-up::after, .fa-duotone.fa-arrow-square-up::after {content: "\f33c\f33c";}.fad.fa-square-arrow-up-left::after, .fa-duotone.fa-square-arrow-up-left::after {content: "\e263\e263";}.fad.fa-square-arrow-up-right::after, .fa-duotone.fa-square-arrow-up-right::after {content: "\f14c\f14c";}.fad.fa-external-link-square::after, .fa-duotone.fa-external-link-square::after {content: "\f14c\f14c";}.fad.fa-square-b::after, .fa-duotone.fa-square-b::after {content: "\e264\e264";}.fad.fa-square-bolt::after, .fa-duotone.fa-square-bolt::after {content: "\e265\e265";}.fad.fa-square-c::after, .fa-duotone.fa-square-c::after {content: "\e266\e266";}.fad.fa-square-caret-down::after, .fa-duotone.fa-square-caret-down::after {content: "\f150\f150";}.fad.fa-caret-square-down::after, .fa-duotone.fa-caret-square-down::after {content: "\f150\f150";}.fad.fa-square-caret-left::after, .fa-duotone.fa-square-caret-left::after {content: "\f191\f191";}.fad.fa-caret-square-left::after, .fa-duotone.fa-caret-square-left::after {content: "\f191\f191";}.fad.fa-square-caret-right::after, .fa-duotone.fa-square-caret-right::after {content: "\f152\f152";}.fad.fa-caret-square-right::after, .fa-duotone.fa-caret-square-right::after {content: "\f152\f152";}.fad.fa-square-caret-up::after, .fa-duotone.fa-square-caret-up::after {content: "\f151\f151";}.fad.fa-caret-square-up::after, .fa-duotone.fa-caret-square-up::after {content: "\f151\f151";}.fad.fa-square-check::after, .fa-duotone.fa-square-check::after {content: "\f14a\f14a";}.fad.fa-check-square::after, .fa-duotone.fa-check-square::after {content: "\f14a\f14a";}.fad.fa-square-chevron-down::after, .fa-duotone.fa-square-chevron-down::after {content: "\f329\f329";}.fad.fa-chevron-square-down::after, .fa-duotone.fa-chevron-square-down::after {content: "\f329\f329";}.fad.fa-square-chevron-left::after, .fa-duotone.fa-square-chevron-left::after {content: "\f32a\f32a";}.fad.fa-chevron-square-left::after, .fa-duotone.fa-chevron-square-left::after {content: "\f32a\f32a";}.fad.fa-square-chevron-right::after, .fa-duotone.fa-square-chevron-right::after {content: "\f32b\f32b";}.fad.fa-chevron-square-right::after, .fa-duotone.fa-chevron-square-right::after {content: "\f32b\f32b";}.fad.fa-square-chevron-up::after, .fa-duotone.fa-square-chevron-up::after {content: "\f32c\f32c";}.fad.fa-chevron-square-up::after, .fa-duotone.fa-chevron-square-up::after {content: "\f32c\f32c";}.fad.fa-square-code::after, .fa-duotone.fa-square-code::after {content: "\e267\e267";}.fad.fa-square-d::after, .fa-duotone.fa-square-d::after {content: "\e268\e268";}.fad.fa-square-dashed::after, .fa-duotone.fa-square-dashed::after {content: "\e269\e269";}.fad.fa-square-divide::after, .fa-duotone.fa-square-divide::after {content: "\e26a\e26a";}.fad.fa-square-dollar::after, .fa-duotone.fa-square-dollar::after {content: "\f2e9\f2e9";}.fad.fa-dollar-square::after, .fa-duotone.fa-dollar-square::after {content: "\f2e9\f2e9";}.fad.fa-usd-square::after, .fa-duotone.fa-usd-square::after {content: "\f2e9\f2e9";}.fad.fa-square-down::after, .fa-duotone.fa-square-down::after {content: "\f350\f350";}.fad.fa-arrow-alt-square-down::after, .fa-duotone.fa-arrow-alt-square-down::after {content: "\f350\f350";}.fad.fa-square-down-left::after, .fa-duotone.fa-square-down-left::after {content: "\e26b\e26b";}.fad.fa-square-down-right::after, .fa-duotone.fa-square-down-right::after {content: "\e26c\e26c";}.fad.fa-square-e::after, .fa-duotone.fa-square-e::after {content: "\e26d\e26d";}.fad.fa-square-ellipsis::after, .fa-duotone.fa-square-ellipsis::after {content: "\e26e\e26e";}.fad.fa-square-ellipsis-vertical::after, .fa-duotone.fa-square-ellipsis-vertical::after {content: "\e26f\e26f";}.fad.fa-square-envelope::after, .fa-duotone.fa-square-envelope::after {content: "\f199\f199";}.fad.fa-envelope-square::after, .fa-duotone.fa-envelope-square::after {content: "\f199\f199";}.fad.fa-square-exclamation::after, .fa-duotone.fa-square-exclamation::after {content: "\f321\f321";}.fad.fa-exclamation-square::after, .fa-duotone.fa-exclamation-square::after {content: "\f321\f321";}.fad.fa-square-f::after, .fa-duotone.fa-square-f::after {content: "\e270\e270";}.fad.fa-square-fragile::after, .fa-duotone.fa-square-fragile::after {content: "\f49b\f49b";}.fad.fa-box-fragile::after, .fa-duotone.fa-box-fragile::after {content: "\f49b\f49b";}.fad.fa-square-wine-glass-crack::after, .fa-duotone.fa-square-wine-glass-crack::after {content: "\f49b\f49b";}.fad.fa-square-full::after, .fa-duotone.fa-square-full::after {content: "\f45c\f45c";}.fad.fa-square-g::after, .fa-duotone.fa-square-g::after {content: "\e271\e271";}.fad.fa-square-h::after, .fa-duotone.fa-square-h::after {content: "\f0fd\f0fd";}.fad.fa-h-square::after, .fa-duotone.fa-h-square::after {content: "\f0fd\f0fd";}.fad.fa-square-heart::after, .fa-duotone.fa-square-heart::after {content: "\f4c8\f4c8";}.fad.fa-heart-square::after, .fa-duotone.fa-heart-square::after {content: "\f4c8\f4c8";}.fad.fa-square-i::after, .fa-duotone.fa-square-i::after {content: "\e272\e272";}.fad.fa-square-info::after, .fa-duotone.fa-square-info::after {content: "\f30f\f30f";}.fad.fa-info-square::after, .fa-duotone.fa-info-square::after {content: "\f30f\f30f";}.fad.fa-square-j::after, .fa-duotone.fa-square-j::after {content: "\e273\e273";}.fad.fa-square-k::after, .fa-duotone.fa-square-k::after {content: "\e274\e274";}.fad.fa-square-kanban::after, .fa-duotone.fa-square-kanban::after {content: "\e488\e488";}.fad.fa-square-l::after, .fa-duotone.fa-square-l::after {content: "\e275\e275";}.fad.fa-square-left::after, .fa-duotone.fa-square-left::after {content: "\f351\f351";}.fad.fa-arrow-alt-square-left::after, .fa-duotone.fa-arrow-alt-square-left::after {content: "\f351\f351";}.fad.fa-square-list::after, .fa-duotone.fa-square-list::after {content: "\e489\e489";}.fad.fa-square-m::after, .fa-duotone.fa-square-m::after {content: "\e276\e276";}.fad.fa-square-minus::after, .fa-duotone.fa-square-minus::after {content: "\f146\f146";}.fad.fa-minus-square::after, .fa-duotone.fa-minus-square::after {content: "\f146\f146";}.fad.fa-square-n::after, .fa-duotone.fa-square-n::after {content: "\e277\e277";}.fad.fa-square-nfi::after, .fa-duotone.fa-square-nfi::after {content: "\e576\e576";}.fad.fa-square-o::after, .fa-duotone.fa-square-o::after {content: "\e278\e278";}.fad.fa-square-p::after, .fa-duotone.fa-square-p::after {content: "\e279\e279";}.fad.fa-square-parking::after, .fa-duotone.fa-square-parking::after {content: "\f540\f540";}.fad.fa-parking::after, .fa-duotone.fa-parking::after {content: "\f540\f540";}.fad.fa-square-parking-slash::after, .fa-duotone.fa-square-parking-slash::after {content: "\f617\f617";}.fad.fa-parking-slash::after, .fa-duotone.fa-parking-slash::after {content: "\f617\f617";}.fad.fa-square-pen::after, .fa-duotone.fa-square-pen::after {content: "\f14b\f14b";}.fad.fa-pen-square::after, .fa-duotone.fa-pen-square::after {content: "\f14b\f14b";}.fad.fa-pencil-square::after, .fa-duotone.fa-pencil-square::after {content: "\f14b\f14b";}.fad.fa-square-person-confined::after, .fa-duotone.fa-square-person-confined::after {content: "\e577\e577";}.fad.fa-square-phone::after, .fa-duotone.fa-square-phone::after {content: "\f098\f098";}.fad.fa-phone-square::after, .fa-duotone.fa-phone-square::after {content: "\f098\f098";}.fad.fa-square-phone-flip::after, .fa-duotone.fa-square-phone-flip::after {content: "\f87b\f87b";}.fad.fa-phone-square-alt::after, .fa-duotone.fa-phone-square-alt::after {content: "\f87b\f87b";}.fad.fa-square-phone-hangup::after, .fa-duotone.fa-square-phone-hangup::after {content: "\e27a\e27a";}.fad.fa-phone-square-down::after, .fa-duotone.fa-phone-square-down::after {content: "\e27a\e27a";}.fad.fa-square-plus::after, .fa-duotone.fa-square-plus::after {content: "\f0fe\f0fe";}.fad.fa-plus-square::after, .fa-duotone.fa-plus-square::after {content: "\f0fe\f0fe";}.fad.fa-square-poll-horizontal::after, .fa-duotone.fa-square-poll-horizontal::after {content: "\f682\f682";}.fad.fa-poll-h::after, .fa-duotone.fa-poll-h::after {content: "\f682\f682";}.fad.fa-square-poll-vertical::after, .fa-duotone.fa-square-poll-vertical::after {content: "\f681\f681";}.fad.fa-poll::after, .fa-duotone.fa-poll::after {content: "\f681\f681";}.fad.fa-square-q::after, .fa-duotone.fa-square-q::after {content: "\e27b\e27b";}.fad.fa-square-quarters::after, .fa-duotone.fa-square-quarters::after {content: "\e44e\e44e";}.fad.fa-square-question::after, .fa-duotone.fa-square-question::after {content: "\f2fd\f2fd";}.fad.fa-question-square::after, .fa-duotone.fa-question-square::after {content: "\f2fd\f2fd";}.fad.fa-square-quote::after, .fa-duotone.fa-square-quote::after {content: "\e329\e329";}.fad.fa-square-r::after, .fa-duotone.fa-square-r::after {content: "\e27c\e27c";}.fad.fa-square-right::after, .fa-duotone.fa-square-right::after {content: "\f352\f352";}.fad.fa-arrow-alt-square-right::after, .fa-duotone.fa-arrow-alt-square-right::after {content: "\f352\f352";}.fad.fa-square-ring::after, .fa-duotone.fa-square-ring::after {content: "\e44f\e44f";}.fad.fa-square-root::after, .fa-duotone.fa-square-root::after {content: "\f697\f697";}.fad.fa-square-root-variable::after, .fa-duotone.fa-square-root-variable::after {content: "\f698\f698";}.fad.fa-square-root-alt::after, .fa-duotone.fa-square-root-alt::after {content: "\f698\f698";}.fad.fa-square-rss::after, .fa-duotone.fa-square-rss::after {content: "\f143\f143";}.fad.fa-rss-square::after, .fa-duotone.fa-rss-square::after {content: "\f143\f143";}.fad.fa-square-s::after, .fa-duotone.fa-square-s::after {content: "\e27d\e27d";}.fad.fa-square-share-nodes::after, .fa-duotone.fa-square-share-nodes::after {content: "\f1e1\f1e1";}.fad.fa-share-alt-square::after, .fa-duotone.fa-share-alt-square::after {content: "\f1e1\f1e1";}.fad.fa-square-sliders::after, .fa-duotone.fa-square-sliders::after {content: "\f3f0\f3f0";}.fad.fa-sliders-h-square::after, .fa-duotone.fa-sliders-h-square::after {content: "\f3f0\f3f0";}.fad.fa-square-sliders-vertical::after, .fa-duotone.fa-square-sliders-vertical::after {content: "\f3f2\f3f2";}.fad.fa-sliders-v-square::after, .fa-duotone.fa-sliders-v-square::after {content: "\f3f2\f3f2";}.fad.fa-square-small::after, .fa-duotone.fa-square-small::after {content: "\e27e\e27e";}.fad.fa-square-star::after, .fa-duotone.fa-square-star::after {content: "\e27f\e27f";}.fad.fa-square-t::after, .fa-duotone.fa-square-t::after {content: "\e280\e280";}.fad.fa-square-terminal::after, .fa-duotone.fa-square-terminal::after {content: "\e32a\e32a";}.fad.fa-square-this-way-up::after, .fa-duotone.fa-square-this-way-up::after {content: "\f49f\f49f";}.fad.fa-box-up::after, .fa-duotone.fa-box-up::after {content: "\f49f\f49f";}.fad.fa-square-u::after, .fa-duotone.fa-square-u::after {content: "\e281\e281";}.fad.fa-square-up::after, .fa-duotone.fa-square-up::after {content: "\f353\f353";}.fad.fa-arrow-alt-square-up::after, .fa-duotone.fa-arrow-alt-square-up::after {content: "\f353\f353";}.fad.fa-square-up-left::after, .fa-duotone.fa-square-up-left::after {content: "\e282\e282";}.fad.fa-square-up-right::after, .fa-duotone.fa-square-up-right::after {content: "\f360\f360";}.fad.fa-external-link-square-alt::after, .fa-duotone.fa-external-link-square-alt::after {content: "\f360\f360";}.fad.fa-square-user::after, .fa-duotone.fa-square-user::after {content: "\e283\e283";}.fad.fa-square-v::after, .fa-duotone.fa-square-v::after {content: "\e284\e284";}.fad.fa-square-virus::after, .fa-duotone.fa-square-virus::after {content: "\e578\e578";}.fad.fa-square-w::after, .fa-duotone.fa-square-w::after {content: "\e285\e285";}.fad.fa-square-x::after, .fa-duotone.fa-square-x::after {content: "\e286\e286";}.fad.fa-square-xmark::after, .fa-duotone.fa-square-xmark::after {content: "\f2d3\f2d3";}.fad.fa-times-square::after, .fa-duotone.fa-times-square::after {content: "\f2d3\f2d3";}.fad.fa-xmark-square::after, .fa-duotone.fa-xmark-square::after {content: "\f2d3\f2d3";}.fad.fa-square-y::after, .fa-duotone.fa-square-y::after {content: "\e287\e287";}.fad.fa-square-z::after, .fa-duotone.fa-square-z::after {content: "\e288\e288";}.fad.fa-squid::after, .fa-duotone.fa-squid::after {content: "\e450\e450";}.fad.fa-squirrel::after, .fa-duotone.fa-squirrel::after {content: "\f71a\f71a";}.fad.fa-staff::after, .fa-duotone.fa-staff::after {content: "\f71b\f71b";}.fad.fa-staff-aesculapius::after, .fa-duotone.fa-staff-aesculapius::after {content: "\e579\e579";}.fad.fa-rod-asclepius::after, .fa-duotone.fa-rod-asclepius::after {content: "\e579\e579";}.fad.fa-rod-snake::after, .fa-duotone.fa-rod-snake::after {content: "\e579\e579";}.fad.fa-staff-snake::after, .fa-duotone.fa-staff-snake::after {content: "\e579\e579";}.fad.fa-stairs::after, .fa-duotone.fa-stairs::after {content: "\e289\e289";}.fad.fa-stamp::after, .fa-duotone.fa-stamp::after {content: "\f5bf\f5bf";}.fad.fa-standard-definition::after, .fa-duotone.fa-standard-definition::after {content: "\e28a\e28a";}.fad.fa-rectangle-sd::after, .fa-duotone.fa-rectangle-sd::after {content: "\e28a\e28a";}.fad.fa-star::after, .fa-duotone.fa-star::after {content: "\f005\f005";}.fad.fa-star-and-crescent::after, .fa-duotone.fa-star-and-crescent::after {content: "\f699\f699";}.fad.fa-star-christmas::after, .fa-duotone.fa-star-christmas::after {content: "\f7d4\f7d4";}.fad.fa-star-exclamation::after, .fa-duotone.fa-star-exclamation::after {content: "\f2f3\f2f3";}.fad.fa-star-half::after, .fa-duotone.fa-star-half::after {content: "\f089\f089";}.fad.fa-star-half-stroke::after, .fa-duotone.fa-star-half-stroke::after {content: "\f5c0\f5c0";}.fad.fa-star-half-alt::after, .fa-duotone.fa-star-half-alt::after {content: "\f5c0\f5c0";}.fad.fa-star-of-david::after, .fa-duotone.fa-star-of-david::after {content: "\f69a\f69a";}.fad.fa-star-of-life::after, .fa-duotone.fa-star-of-life::after {content: "\f621\f621";}.fad.fa-star-sharp::after, .fa-duotone.fa-star-sharp::after {content: "\e28b\e28b";}.fad.fa-star-sharp-half::after, .fa-duotone.fa-star-sharp-half::after {content: "\e28c\e28c";}.fad.fa-star-sharp-half-stroke::after, .fa-duotone.fa-star-sharp-half-stroke::after {content: "\e28d\e28d";}.fad.fa-star-sharp-half-alt::after, .fa-duotone.fa-star-sharp-half-alt::after {content: "\e28d\e28d";}.fad.fa-star-shooting::after, .fa-duotone.fa-star-shooting::after {content: "\e036\e036";}.fad.fa-starfighter::after, .fa-duotone.fa-starfighter::after {content: "\e037\e037";}.fad.fa-starfighter-twin-ion-engine::after, .fa-duotone.fa-starfighter-twin-ion-engine::after {content: "\e038\e038";}.fad.fa-starfighter-alt::after, .fa-duotone.fa-starfighter-alt::after {content: "\e038\e038";}.fad.fa-starfighter-twin-ion-engine-advanced::after, .fa-duotone.fa-starfighter-twin-ion-engine-advanced::after {content: "\e28e\e28e";}.fad.fa-starfighter-alt-advanced::after, .fa-duotone.fa-starfighter-alt-advanced::after {content: "\e28e\e28e";}.fad.fa-stars::after, .fa-duotone.fa-stars::after {content: "\f762\f762";}.fad.fa-starship::after, .fa-duotone.fa-starship::after {content: "\e039\e039";}.fad.fa-starship-freighter::after, .fa-duotone.fa-starship-freighter::after {content: "\e03a\e03a";}.fad.fa-steak::after, .fa-duotone.fa-steak::after {content: "\f824\f824";}.fad.fa-steering-wheel::after, .fa-duotone.fa-steering-wheel::after {content: "\f622\f622";}.fad.fa-sterling-sign::after, .fa-duotone.fa-sterling-sign::after {content: "\f154\f154";}.fad.fa-gbp::after, .fa-duotone.fa-gbp::after {content: "\f154\f154";}.fad.fa-pound-sign::after, .fa-duotone.fa-pound-sign::after {content: "\f154\f154";}.fad.fa-stethoscope::after, .fa-duotone.fa-stethoscope::after {content: "\f0f1\f0f1";}.fad.fa-stocking::after, .fa-duotone.fa-stocking::after {content: "\f7d5\f7d5";}.fad.fa-stomach::after, .fa-duotone.fa-stomach::after {content: "\f623\f623";}.fad.fa-stop::after, .fa-duotone.fa-stop::after {content: "\f04d\f04d";}.fad.fa-stopwatch::after, .fa-duotone.fa-stopwatch::after {content: "\f2f2\f2f2";}.fad.fa-stopwatch-20::after, .fa-duotone.fa-stopwatch-20::after {content: "\e06f\e06f";}.fad.fa-store::after, .fa-duotone.fa-store::after {content: "\f54e\f54e";}.fad.fa-store-lock::after, .fa-duotone.fa-store-lock::after {content: "\e4a6\e4a6";}.fad.fa-store-slash::after, .fa-duotone.fa-store-slash::after {content: "\e071\e071";}.fad.fa-strawberry::after, .fa-duotone.fa-strawberry::after {content: "\e32b\e32b";}.fad.fa-street-view::after, .fa-duotone.fa-street-view::after {content: "\f21d\f21d";}.fad.fa-stretcher::after, .fa-duotone.fa-stretcher::after {content: "\f825\f825";}.fad.fa-strikethrough::after, .fa-duotone.fa-strikethrough::after {content: "\f0cc\f0cc";}.fad.fa-stroopwafel::after, .fa-duotone.fa-stroopwafel::after {content: "\f551\f551";}.fad.fa-subscript::after, .fa-duotone.fa-subscript::after {content: "\f12c\f12c";}.fad.fa-suitcase::after, .fa-duotone.fa-suitcase::after {content: "\f0f2\f0f2";}.fad.fa-suitcase-medical::after, .fa-duotone.fa-suitcase-medical::after {content: "\f0fa\f0fa";}.fad.fa-medkit::after, .fa-duotone.fa-medkit::after {content: "\f0fa\f0fa";}.fad.fa-suitcase-rolling::after, .fa-duotone.fa-suitcase-rolling::after {content: "\f5c1\f5c1";}.fad.fa-sun::after, .fa-duotone.fa-sun::after {content: "\f185\f185";}.fad.fa-sun-bright::after, .fa-duotone.fa-sun-bright::after {content: "\e28f\e28f";}.fad.fa-sun-alt::after, .fa-duotone.fa-sun-alt::after {content: "\e28f\e28f";}.fad.fa-sun-cloud::after, .fa-duotone.fa-sun-cloud::after {content: "\f763\f763";}.fad.fa-sun-dust::after, .fa-duotone.fa-sun-dust::after {content: "\f764\f764";}.fad.fa-sun-haze::after, .fa-duotone.fa-sun-haze::after {content: "\f765\f765";}.fad.fa-sun-plant-wilt::after, .fa-duotone.fa-sun-plant-wilt::after {content: "\e57a\e57a";}.fad.fa-sunglasses::after, .fa-duotone.fa-sunglasses::after {content: "\f892\f892";}.fad.fa-sunrise::after, .fa-duotone.fa-sunrise::after {content: "\f766\f766";}.fad.fa-sunset::after, .fa-duotone.fa-sunset::after {content: "\f767\f767";}.fad.fa-superscript::after, .fa-duotone.fa-superscript::after {content: "\f12b\f12b";}.fad.fa-sushi::after, .fa-duotone.fa-sushi::after {content: "\e48a\e48a";}.fad.fa-nigiri::after, .fa-duotone.fa-nigiri::after {content: "\e48a\e48a";}.fad.fa-sushi-roll::after, .fa-duotone.fa-sushi-roll::after {content: "\e48b\e48b";}.fad.fa-maki-roll::after, .fa-duotone.fa-maki-roll::after {content: "\e48b\e48b";}.fad.fa-makizushi::after, .fa-duotone.fa-makizushi::after {content: "\e48b\e48b";}.fad.fa-swatchbook::after, .fa-duotone.fa-swatchbook::after {content: "\f5c3\f5c3";}.fad.fa-sword::after, .fa-duotone.fa-sword::after {content: "\f71c\f71c";}.fad.fa-sword-laser::after, .fa-duotone.fa-sword-laser::after {content: "\e03b\e03b";}.fad.fa-sword-laser-alt::after, .fa-duotone.fa-sword-laser-alt::after {content: "\e03c\e03c";}.fad.fa-swords::after, .fa-duotone.fa-swords::after {content: "\f71d\f71d";}.fad.fa-swords-laser::after, .fa-duotone.fa-swords-laser::after {content: "\e03d\e03d";}.fad.fa-symbols::after, .fa-duotone.fa-symbols::after {content: "\f86e\f86e";}.fad.fa-icons-alt::after, .fa-duotone.fa-icons-alt::after {content: "\f86e\f86e";}.fad.fa-synagogue::after, .fa-duotone.fa-synagogue::after {content: "\f69b\f69b";}.fad.fa-syringe::after, .fa-duotone.fa-syringe::after {content: "\f48e\f48e";}.fad.fa-t::after, .fa-duotone.fa-t::after {content: "\54\54";}.fad.fa-table::after, .fa-duotone.fa-table::after {content: "\f0ce\f0ce";}.fad.fa-table-cells::after, .fa-duotone.fa-table-cells::after {content: "\f00a\f00a";}.fad.fa-th::after, .fa-duotone.fa-th::after {content: "\f00a\f00a";}.fad.fa-table-cells-large::after, .fa-duotone.fa-table-cells-large::after {content: "\f009\f009";}.fad.fa-th-large::after, .fa-duotone.fa-th-large::after {content: "\f009\f009";}.fad.fa-table-columns::after, .fa-duotone.fa-table-columns::after {content: "\f0db\f0db";}.fad.fa-columns::after, .fa-duotone.fa-columns::after {content: "\f0db\f0db";}.fad.fa-table-layout::after, .fa-duotone.fa-table-layout::after {content: "\e290\e290";}.fad.fa-table-list::after, .fa-duotone.fa-table-list::after {content: "\f00b\f00b";}.fad.fa-th-list::after, .fa-duotone.fa-th-list::after {content: "\f00b\f00b";}.fad.fa-table-picnic::after, .fa-duotone.fa-table-picnic::after {content: "\e32d\e32d";}.fad.fa-table-pivot::after, .fa-duotone.fa-table-pivot::after {content: "\e291\e291";}.fad.fa-table-rows::after, .fa-duotone.fa-table-rows::after {content: "\e292\e292";}.fad.fa-rows::after, .fa-duotone.fa-rows::after {content: "\e292\e292";}.fad.fa-table-tennis-paddle-ball::after, .fa-duotone.fa-table-tennis-paddle-ball::after {content: "\f45d\f45d";}.fad.fa-ping-pong-paddle-ball::after, .fa-duotone.fa-ping-pong-paddle-ball::after {content: "\f45d\f45d";}.fad.fa-table-tennis::after, .fa-duotone.fa-table-tennis::after {content: "\f45d\f45d";}.fad.fa-table-tree::after, .fa-duotone.fa-table-tree::after {content: "\e293\e293";}.fad.fa-tablet::after, .fa-duotone.fa-tablet::after {content: "\f3fb\f3fb";}.fad.fa-tablet-android::after, .fa-duotone.fa-tablet-android::after {content: "\f3fb\f3fb";}.fad.fa-tablet-button::after, .fa-duotone.fa-tablet-button::after {content: "\f10a\f10a";}.fad.fa-tablet-rugged::after, .fa-duotone.fa-tablet-rugged::after {content: "\f48f\f48f";}.fad.fa-tablet-screen::after, .fa-duotone.fa-tablet-screen::after {content: "\f3fc\f3fc";}.fad.fa-tablet-android-alt::after, .fa-duotone.fa-tablet-android-alt::after {content: "\f3fc\f3fc";}.fad.fa-tablet-screen-button::after, .fa-duotone.fa-tablet-screen-button::after {content: "\f3fa\f3fa";}.fad.fa-tablet-alt::after, .fa-duotone.fa-tablet-alt::after {content: "\f3fa\f3fa";}.fad.fa-tablets::after, .fa-duotone.fa-tablets::after {content: "\f490\f490";}.fad.fa-tachograph-digital::after, .fa-duotone.fa-tachograph-digital::after {content: "\f566\f566";}.fad.fa-digital-tachograph::after, .fa-duotone.fa-digital-tachograph::after {content: "\f566\f566";}.fad.fa-taco::after, .fa-duotone.fa-taco::after {content: "\f826\f826";}.fad.fa-tag::after, .fa-duotone.fa-tag::after {content: "\f02b\f02b";}.fad.fa-tags::after, .fa-duotone.fa-tags::after {content: "\f02c\f02c";}.fad.fa-tally::after, .fa-duotone.fa-tally::after {content: "\f69c\f69c";}.fad.fa-tally-5::after, .fa-duotone.fa-tally-5::after {content: "\f69c\f69c";}.fad.fa-tally-1::after, .fa-duotone.fa-tally-1::after {content: "\e294\e294";}.fad.fa-tally-2::after, .fa-duotone.fa-tally-2::after {content: "\e295\e295";}.fad.fa-tally-3::after, .fa-duotone.fa-tally-3::after {content: "\e296\e296";}.fad.fa-tally-4::after, .fa-duotone.fa-tally-4::after {content: "\e297\e297";}.fad.fa-tamale::after, .fa-duotone.fa-tamale::after {content: "\e451\e451";}.fad.fa-tank-water::after, .fa-duotone.fa-tank-water::after {content: "\e452\e452";}.fad.fa-tape::after, .fa-duotone.fa-tape::after {content: "\f4db\f4db";}.fad.fa-tarp::after, .fa-duotone.fa-tarp::after {content: "\e57b\e57b";}.fad.fa-tarp-droplet::after, .fa-duotone.fa-tarp-droplet::after {content: "\e57c\e57c";}.fad.fa-taxi::after, .fa-duotone.fa-taxi::after {content: "\f1ba\f1ba";}.fad.fa-cab::after, .fa-duotone.fa-cab::after {content: "\f1ba\f1ba";}.fad.fa-taxi-bus::after, .fa-duotone.fa-taxi-bus::after {content: "\e298\e298";}.fad.fa-teddy-bear::after, .fa-duotone.fa-teddy-bear::after {content: "\e3cf\e3cf";}.fad.fa-teeth::after, .fa-duotone.fa-teeth::after {content: "\f62e\f62e";}.fad.fa-teeth-open::after, .fa-duotone.fa-teeth-open::after {content: "\f62f\f62f";}.fad.fa-telescope::after, .fa-duotone.fa-telescope::after {content: "\e03e\e03e";}.fad.fa-temperature-arrow-down::after, .fa-duotone.fa-temperature-arrow-down::after {content: "\e03f\e03f";}.fad.fa-temperature-down::after, .fa-duotone.fa-temperature-down::after {content: "\e03f\e03f";}.fad.fa-temperature-arrow-up::after, .fa-duotone.fa-temperature-arrow-up::after {content: "\e040\e040";}.fad.fa-temperature-up::after, .fa-duotone.fa-temperature-up::after {content: "\e040\e040";}.fad.fa-temperature-empty::after, .fa-duotone.fa-temperature-empty::after {content: "\f2cb\f2cb";}.fad.fa-temperature-0::after, .fa-duotone.fa-temperature-0::after {content: "\f2cb\f2cb";}.fad.fa-thermometer-0::after, .fa-duotone.fa-thermometer-0::after {content: "\f2cb\f2cb";}.fad.fa-thermometer-empty::after, .fa-duotone.fa-thermometer-empty::after {content: "\f2cb\f2cb";}.fad.fa-temperature-full::after, .fa-duotone.fa-temperature-full::after {content: "\f2c7\f2c7";}.fad.fa-temperature-4::after, .fa-duotone.fa-temperature-4::after {content: "\f2c7\f2c7";}.fad.fa-thermometer-4::after, .fa-duotone.fa-thermometer-4::after {content: "\f2c7\f2c7";}.fad.fa-thermometer-full::after, .fa-duotone.fa-thermometer-full::after {content: "\f2c7\f2c7";}.fad.fa-temperature-half::after, .fa-duotone.fa-temperature-half::after {content: "\f2c9\f2c9";}.fad.fa-temperature-2::after, .fa-duotone.fa-temperature-2::after {content: "\f2c9\f2c9";}.fad.fa-thermometer-2::after, .fa-duotone.fa-thermometer-2::after {content: "\f2c9\f2c9";}.fad.fa-thermometer-half::after, .fa-duotone.fa-thermometer-half::after {content: "\f2c9\f2c9";}.fad.fa-temperature-high::after, .fa-duotone.fa-temperature-high::after {content: "\f769\f769";}.fad.fa-temperature-list::after, .fa-duotone.fa-temperature-list::after {content: "\e299\e299";}.fad.fa-temperature-low::after, .fa-duotone.fa-temperature-low::after {content: "\f76b\f76b";}.fad.fa-temperature-quarter::after, .fa-duotone.fa-temperature-quarter::after {content: "\f2ca\f2ca";}.fad.fa-temperature-1::after, .fa-duotone.fa-temperature-1::after {content: "\f2ca\f2ca";}.fad.fa-thermometer-1::after, .fa-duotone.fa-thermometer-1::after {content: "\f2ca\f2ca";}.fad.fa-thermometer-quarter::after, .fa-duotone.fa-thermometer-quarter::after {content: "\f2ca\f2ca";}.fad.fa-temperature-snow::after, .fa-duotone.fa-temperature-snow::after {content: "\f768\f768";}.fad.fa-temperature-frigid::after, .fa-duotone.fa-temperature-frigid::after {content: "\f768\f768";}.fad.fa-temperature-sun::after, .fa-duotone.fa-temperature-sun::after {content: "\f76a\f76a";}.fad.fa-temperature-hot::after, .fa-duotone.fa-temperature-hot::after {content: "\f76a\f76a";}.fad.fa-temperature-three-quarters::after, .fa-duotone.fa-temperature-three-quarters::after {content: "\f2c8\f2c8";}.fad.fa-temperature-3::after, .fa-duotone.fa-temperature-3::after {content: "\f2c8\f2c8";}.fad.fa-thermometer-3::after, .fa-duotone.fa-thermometer-3::after {content: "\f2c8\f2c8";}.fad.fa-thermometer-three-quarters::after, .fa-duotone.fa-thermometer-three-quarters::after {content: "\f2c8\f2c8";}.fad.fa-tenge-sign::after, .fa-duotone.fa-tenge-sign::after {content: "\f7d7\f7d7";}.fad.fa-tenge::after, .fa-duotone.fa-tenge::after {content: "\f7d7\f7d7";}.fad.fa-tennis-ball::after, .fa-duotone.fa-tennis-ball::after {content: "\f45e\f45e";}.fad.fa-tent::after, .fa-duotone.fa-tent::after {content: "\e57d\e57d";}.fad.fa-tent-arrow-down-to-line::after, .fa-duotone.fa-tent-arrow-down-to-line::after {content: "\e57e\e57e";}.fad.fa-tent-arrow-left-right::after, .fa-duotone.fa-tent-arrow-left-right::after {content: "\e57f\e57f";}.fad.fa-tent-arrow-turn-left::after, .fa-duotone.fa-tent-arrow-turn-left::after {content: "\e580\e580";}.fad.fa-tent-arrows-down::after, .fa-duotone.fa-tent-arrows-down::after {content: "\e581\e581";}.fad.fa-tents::after, .fa-duotone.fa-tents::after {content: "\e582\e582";}.fad.fa-terminal::after, .fa-duotone.fa-terminal::after {content: "\f120\f120";}.fad.fa-text::after, .fa-duotone.fa-text::after {content: "\f893\f893";}.fad.fa-text-height::after, .fa-duotone.fa-text-height::after {content: "\f034\f034";}.fad.fa-text-size::after, .fa-duotone.fa-text-size::after {content: "\f894\f894";}.fad.fa-text-slash::after, .fa-duotone.fa-text-slash::after {content: "\f87d\f87d";}.fad.fa-remove-format::after, .fa-duotone.fa-remove-format::after {content: "\f87d\f87d";}.fad.fa-text-width::after, .fa-duotone.fa-text-width::after {content: "\f035\f035";}.fad.fa-thermometer::after, .fa-duotone.fa-thermometer::after {content: "\f491\f491";}.fad.fa-theta::after, .fa-duotone.fa-theta::after {content: "\f69e\f69e";}.fad.fa-thought-bubble::after, .fa-duotone.fa-thought-bubble::after {content: "\e32e\e32e";}.fad.fa-thumbs-down::after, .fa-duotone.fa-thumbs-down::after {content: "\f165\f165";}.fad.fa-thumbs-up::after, .fa-duotone.fa-thumbs-up::after {content: "\f164\f164";}.fad.fa-thumbtack::after, .fa-duotone.fa-thumbtack::after {content: "\f08d\f08d";}.fad.fa-thumb-tack::after, .fa-duotone.fa-thumb-tack::after {content: "\f08d\f08d";}.fad.fa-tick::after, .fa-duotone.fa-tick::after {content: "\e32f\e32f";}.fad.fa-ticket::after, .fa-duotone.fa-ticket::after {content: "\f145\f145";}.fad.fa-ticket-airline::after, .fa-duotone.fa-ticket-airline::after {content: "\e29a\e29a";}.fad.fa-ticket-simple::after, .fa-duotone.fa-ticket-simple::after {content: "\f3ff\f3ff";}.fad.fa-ticket-alt::after, .fa-duotone.fa-ticket-alt::after {content: "\f3ff\f3ff";}.fad.fa-tickets-airline::after, .fa-duotone.fa-tickets-airline::after {content: "\e29b\e29b";}.fad.fa-tilde::after, .fa-duotone.fa-tilde::after {content: "\7e\7e";}.fad.fa-timeline::after, .fa-duotone.fa-timeline::after {content: "\e29c\e29c";}.fad.fa-timeline-arrow::after, .fa-duotone.fa-timeline-arrow::after {content: "\e29d\e29d";}.fad.fa-timer::after, .fa-duotone.fa-timer::after {content: "\e29e\e29e";}.fad.fa-tire::after, .fa-duotone.fa-tire::after {content: "\f631\f631";}.fad.fa-tire-flat::after, .fa-duotone.fa-tire-flat::after {content: "\f632\f632";}.fad.fa-tire-pressure-warning::after, .fa-duotone.fa-tire-pressure-warning::after {content: "\f633\f633";}.fad.fa-tire-rugged::after, .fa-duotone.fa-tire-rugged::after {content: "\f634\f634";}.fad.fa-toggle-off::after, .fa-duotone.fa-toggle-off::after {content: "\f204\f204";}.fad.fa-toggle-on::after, .fa-duotone.fa-toggle-on::after {content: "\f205\f205";}.fad.fa-toilet::after, .fa-duotone.fa-toilet::after {content: "\f7d8\f7d8";}.fad.fa-toilet-paper::after, .fa-duotone.fa-toilet-paper::after {content: "\f71e\f71e";}.fad.fa-toilet-paper-blank::after, .fa-duotone.fa-toilet-paper-blank::after {content: "\f71f\f71f";}.fad.fa-toilet-paper-alt::after, .fa-duotone.fa-toilet-paper-alt::after {content: "\f71f\f71f";}.fad.fa-toilet-paper-blank-under::after, .fa-duotone.fa-toilet-paper-blank-under::after {content: "\e29f\e29f";}.fad.fa-toilet-paper-reverse-alt::after, .fa-duotone.fa-toilet-paper-reverse-alt::after {content: "\e29f\e29f";}.fad.fa-toilet-paper-slash::after, .fa-duotone.fa-toilet-paper-slash::after {content: "\e072\e072";}.fad.fa-toilet-paper-under::after, .fa-duotone.fa-toilet-paper-under::after {content: "\e2a0\e2a0";}.fad.fa-toilet-paper-reverse::after, .fa-duotone.fa-toilet-paper-reverse::after {content: "\e2a0\e2a0";}.fad.fa-toilet-paper-under-slash::after, .fa-duotone.fa-toilet-paper-under-slash::after {content: "\e2a1\e2a1";}.fad.fa-toilet-paper-reverse-slash::after, .fa-duotone.fa-toilet-paper-reverse-slash::after {content: "\e2a1\e2a1";}.fad.fa-toilet-portable::after, .fa-duotone.fa-toilet-portable::after {content: "\e583\e583";}.fad.fa-toilets-portable::after, .fa-duotone.fa-toilets-portable::after {content: "\e584\e584";}.fad.fa-tomato::after, .fa-duotone.fa-tomato::after {content: "\e330\e330";}.fad.fa-tombstone::after, .fa-duotone.fa-tombstone::after {content: "\f720\f720";}.fad.fa-tombstone-blank::after, .fa-duotone.fa-tombstone-blank::after {content: "\f721\f721";}.fad.fa-tombstone-alt::after, .fa-duotone.fa-tombstone-alt::after {content: "\f721\f721";}.fad.fa-toolbox::after, .fa-duotone.fa-toolbox::after {content: "\f552\f552";}.fad.fa-tooth::after, .fa-duotone.fa-tooth::after {content: "\f5c9\f5c9";}.fad.fa-toothbrush::after, .fa-duotone.fa-toothbrush::after {content: "\f635\f635";}.fad.fa-torii-gate::after, .fa-duotone.fa-torii-gate::after {content: "\f6a1\f6a1";}.fad.fa-tornado::after, .fa-duotone.fa-tornado::after {content: "\f76f\f76f";}.fad.fa-tower-broadcast::after, .fa-duotone.fa-tower-broadcast::after {content: "\f519\f519";}.fad.fa-broadcast-tower::after, .fa-duotone.fa-broadcast-tower::after {content: "\f519\f519";}.fad.fa-tower-cell::after, .fa-duotone.fa-tower-cell::after {content: "\e585\e585";}.fad.fa-tower-control::after, .fa-duotone.fa-tower-control::after {content: "\e2a2\e2a2";}.fad.fa-tower-observation::after, .fa-duotone.fa-tower-observation::after {content: "\e586\e586";}.fad.fa-tractor::after, .fa-duotone.fa-tractor::after {content: "\f722\f722";}.fad.fa-trademark::after, .fa-duotone.fa-trademark::after {content: "\f25c\f25c";}.fad.fa-traffic-cone::after, .fa-duotone.fa-traffic-cone::after {content: "\f636\f636";}.fad.fa-traffic-light::after, .fa-duotone.fa-traffic-light::after {content: "\f637\f637";}.fad.fa-traffic-light-go::after, .fa-duotone.fa-traffic-light-go::after {content: "\f638\f638";}.fad.fa-traffic-light-slow::after, .fa-duotone.fa-traffic-light-slow::after {content: "\f639\f639";}.fad.fa-traffic-light-stop::after, .fa-duotone.fa-traffic-light-stop::after {content: "\f63a\f63a";}.fad.fa-trailer::after, .fa-duotone.fa-trailer::after {content: "\e041\e041";}.fad.fa-train::after, .fa-duotone.fa-train::after {content: "\f238\f238";}.fad.fa-train-subway::after, .fa-duotone.fa-train-subway::after {content: "\f239\f239";}.fad.fa-subway::after, .fa-duotone.fa-subway::after {content: "\f239\f239";}.fad.fa-train-subway-tunnel::after, .fa-duotone.fa-train-subway-tunnel::after {content: "\e2a3\e2a3";}.fad.fa-subway-tunnel::after, .fa-duotone.fa-subway-tunnel::after {content: "\e2a3\e2a3";}.fad.fa-train-track::after, .fa-duotone.fa-train-track::after {content: "\e453\e453";}.fad.fa-train-tram::after, .fa-duotone.fa-train-tram::after {content: "\f7da\f7da";}.fad.fa-tram::after, .fa-duotone.fa-tram::after {content: "\f7da\f7da";}.fad.fa-train-tunnel::after, .fa-duotone.fa-train-tunnel::after {content: "\e454\e454";}.fad.fa-transformer-bolt::after, .fa-duotone.fa-transformer-bolt::after {content: "\e2a4\e2a4";}.fad.fa-transgender::after, .fa-duotone.fa-transgender::after {content: "\f225\f225";}.fad.fa-transgender-alt::after, .fa-duotone.fa-transgender-alt::after {content: "\f225\f225";}.fad.fa-transporter::after, .fa-duotone.fa-transporter::after {content: "\e042\e042";}.fad.fa-transporter-1::after, .fa-duotone.fa-transporter-1::after {content: "\e043\e043";}.fad.fa-transporter-2::after, .fa-duotone.fa-transporter-2::after {content: "\e044\e044";}.fad.fa-transporter-3::after, .fa-duotone.fa-transporter-3::after {content: "\e045\e045";}.fad.fa-transporter-4::after, .fa-duotone.fa-transporter-4::after {content: "\e2a5\e2a5";}.fad.fa-transporter-5::after, .fa-duotone.fa-transporter-5::after {content: "\e2a6\e2a6";}.fad.fa-transporter-6::after, .fa-duotone.fa-transporter-6::after {content: "\e2a7\e2a7";}.fad.fa-transporter-7::after, .fa-duotone.fa-transporter-7::after {content: "\e2a8\e2a8";}.fad.fa-transporter-empty::after, .fa-duotone.fa-transporter-empty::after {content: "\e046\e046";}.fad.fa-trash::after, .fa-duotone.fa-trash::after {content: "\f1f8\f1f8";}.fad.fa-trash-arrow-up::after, .fa-duotone.fa-trash-arrow-up::after {content: "\f829\f829";}.fad.fa-trash-restore::after, .fa-duotone.fa-trash-restore::after {content: "\f829\f829";}.fad.fa-trash-can::after, .fa-duotone.fa-trash-can::after {content: "\f2ed\f2ed";}.fad.fa-trash-alt::after, .fa-duotone.fa-trash-alt::after {content: "\f2ed\f2ed";}.fad.fa-trash-can-arrow-up::after, .fa-duotone.fa-trash-can-arrow-up::after {content: "\f82a\f82a";}.fad.fa-trash-restore-alt::after, .fa-duotone.fa-trash-restore-alt::after {content: "\f82a\f82a";}.fad.fa-trash-can-check::after, .fa-duotone.fa-trash-can-check::after {content: "\e2a9\e2a9";}.fad.fa-trash-can-clock::after, .fa-duotone.fa-trash-can-clock::after {content: "\e2aa\e2aa";}.fad.fa-trash-can-list::after, .fa-duotone.fa-trash-can-list::after {content: "\e2ab\e2ab";}.fad.fa-trash-can-plus::after, .fa-duotone.fa-trash-can-plus::after {content: "\e2ac\e2ac";}.fad.fa-trash-can-slash::after, .fa-duotone.fa-trash-can-slash::after {content: "\e2ad\e2ad";}.fad.fa-trash-alt-slash::after, .fa-duotone.fa-trash-alt-slash::after {content: "\e2ad\e2ad";}.fad.fa-trash-can-undo::after, .fa-duotone.fa-trash-can-undo::after {content: "\f896\f896";}.fad.fa-trash-can-arrow-turn-left::after, .fa-duotone.fa-trash-can-arrow-turn-left::after {content: "\f896\f896";}.fad.fa-trash-undo-alt::after, .fa-duotone.fa-trash-undo-alt::after {content: "\f896\f896";}.fad.fa-trash-can-xmark::after, .fa-duotone.fa-trash-can-xmark::after {content: "\e2ae\e2ae";}.fad.fa-trash-check::after, .fa-duotone.fa-trash-check::after {content: "\e2af\e2af";}.fad.fa-trash-clock::after, .fa-duotone.fa-trash-clock::after {content: "\e2b0\e2b0";}.fad.fa-trash-list::after, .fa-duotone.fa-trash-list::after {content: "\e2b1\e2b1";}.fad.fa-trash-plus::after, .fa-duotone.fa-trash-plus::after {content: "\e2b2\e2b2";}.fad.fa-trash-slash::after, .fa-duotone.fa-trash-slash::after {content: "\e2b3\e2b3";}.fad.fa-trash-undo::after, .fa-duotone.fa-trash-undo::after {content: "\f895\f895";}.fad.fa-trash-arrow-turn-left::after, .fa-duotone.fa-trash-arrow-turn-left::after {content: "\f895\f895";}.fad.fa-trash-xmark::after, .fa-duotone.fa-trash-xmark::after {content: "\e2b4\e2b4";}.fad.fa-treasure-chest::after, .fa-duotone.fa-treasure-chest::after {content: "\f723\f723";}.fad.fa-tree::after, .fa-duotone.fa-tree::after {content: "\f1bb\f1bb";}.fad.fa-tree-christmas::after, .fa-duotone.fa-tree-christmas::after {content: "\f7db\f7db";}.fad.fa-tree-city::after, .fa-duotone.fa-tree-city::after {content: "\e587\e587";}.fad.fa-tree-deciduous::after, .fa-duotone.fa-tree-deciduous::after {content: "\f400\f400";}.fad.fa-tree-alt::after, .fa-duotone.fa-tree-alt::after {content: "\f400\f400";}.fad.fa-tree-decorated::after, .fa-duotone.fa-tree-decorated::after {content: "\f7dc\f7dc";}.fad.fa-tree-large::after, .fa-duotone.fa-tree-large::after {content: "\f7dd\f7dd";}.fad.fa-tree-palm::after, .fa-duotone.fa-tree-palm::after {content: "\f82b\f82b";}.fad.fa-trees::after, .fa-duotone.fa-trees::after {content: "\f724\f724";}.fad.fa-triangle::after, .fa-duotone.fa-triangle::after {content: "\f2ec\f2ec";}.fad.fa-triangle-exclamation::after, .fa-duotone.fa-triangle-exclamation::after {content: "\f071\f071";}.fad.fa-exclamation-triangle::after, .fa-duotone.fa-exclamation-triangle::after {content: "\f071\f071";}.fad.fa-warning::after, .fa-duotone.fa-warning::after {content: "\f071\f071";}.fad.fa-triangle-instrument::after, .fa-duotone.fa-triangle-instrument::after {content: "\f8e2\f8e2";}.fad.fa-triangle-music::after, .fa-duotone.fa-triangle-music::after {content: "\f8e2\f8e2";}.fad.fa-triangle-person-digging::after, .fa-duotone.fa-triangle-person-digging::after {content: "\f85d\f85d";}.fad.fa-construction::after, .fa-duotone.fa-construction::after {content: "\f85d\f85d";}.fad.fa-trillium::after, .fa-duotone.fa-trillium::after {content: "\e588\e588";}.fad.fa-trophy::after, .fa-duotone.fa-trophy::after {content: "\f091\f091";}.fad.fa-trophy-star::after, .fa-duotone.fa-trophy-star::after {content: "\f2eb\f2eb";}.fad.fa-trophy-alt::after, .fa-duotone.fa-trophy-alt::after {content: "\f2eb\f2eb";}.fad.fa-trowel::after, .fa-duotone.fa-trowel::after {content: "\e589\e589";}.fad.fa-trowel-bricks::after, .fa-duotone.fa-trowel-bricks::after {content: "\e58a\e58a";}.fad.fa-truck::after, .fa-duotone.fa-truck::after {content: "\f0d1\f0d1";}.fad.fa-truck-arrow-right::after, .fa-duotone.fa-truck-arrow-right::after {content: "\e58b\e58b";}.fad.fa-truck-bolt::after, .fa-duotone.fa-truck-bolt::after {content: "\e3d0\e3d0";}.fad.fa-truck-clock::after, .fa-duotone.fa-truck-clock::after {content: "\f48c\f48c";}.fad.fa-shipping-timed::after, .fa-duotone.fa-shipping-timed::after {content: "\f48c\f48c";}.fad.fa-truck-container::after, .fa-duotone.fa-truck-container::after {content: "\f4dc\f4dc";}.fad.fa-truck-container-empty::after, .fa-duotone.fa-truck-container-empty::after {content: "\e2b5\e2b5";}.fad.fa-truck-droplet::after, .fa-duotone.fa-truck-droplet::after {content: "\e58c\e58c";}.fad.fa-truck-fast::after, .fa-duotone.fa-truck-fast::after {content: "\f48b\f48b";}.fad.fa-shipping-fast::after, .fa-duotone.fa-shipping-fast::after {content: "\f48b\f48b";}.fad.fa-truck-field::after, .fa-duotone.fa-truck-field::after {content: "\e58d\e58d";}.fad.fa-truck-field-un::after, .fa-duotone.fa-truck-field-un::after {content: "\e58e\e58e";}.fad.fa-truck-flatbed::after, .fa-duotone.fa-truck-flatbed::after {content: "\e2b6\e2b6";}.fad.fa-truck-front::after, .fa-duotone.fa-truck-front::after {content: "\e2b7\e2b7";}.fad.fa-truck-medical::after, .fa-duotone.fa-truck-medical::after {content: "\f0f9\f0f9";}.fad.fa-ambulance::after, .fa-duotone.fa-ambulance::after {content: "\f0f9\f0f9";}.fad.fa-truck-monster::after, .fa-duotone.fa-truck-monster::after {content: "\f63b\f63b";}.fad.fa-truck-moving::after, .fa-duotone.fa-truck-moving::after {content: "\f4df\f4df";}.fad.fa-truck-pickup::after, .fa-duotone.fa-truck-pickup::after {content: "\f63c\f63c";}.fad.fa-truck-plane::after, .fa-duotone.fa-truck-plane::after {content: "\e58f\e58f";}.fad.fa-truck-plow::after, .fa-duotone.fa-truck-plow::after {content: "\f7de\f7de";}.fad.fa-truck-ramp::after, .fa-duotone.fa-truck-ramp::after {content: "\f4e0\f4e0";}.fad.fa-truck-ramp-box::after, .fa-duotone.fa-truck-ramp-box::after {content: "\f4de\f4de";}.fad.fa-truck-loading::after, .fa-duotone.fa-truck-loading::after {content: "\f4de\f4de";}.fad.fa-truck-ramp-couch::after, .fa-duotone.fa-truck-ramp-couch::after {content: "\f4dd\f4dd";}.fad.fa-truck-couch::after, .fa-duotone.fa-truck-couch::after {content: "\f4dd\f4dd";}.fad.fa-truck-tow::after, .fa-duotone.fa-truck-tow::after {content: "\e2b8\e2b8";}.fad.fa-trumpet::after, .fa-duotone.fa-trumpet::after {content: "\f8e3\f8e3";}.fad.fa-tty::after, .fa-duotone.fa-tty::after {content: "\f1e4\f1e4";}.fad.fa-teletype::after, .fa-duotone.fa-teletype::after {content: "\f1e4\f1e4";}.fad.fa-tty-answer::after, .fa-duotone.fa-tty-answer::after {content: "\e2b9\e2b9";}.fad.fa-teletype-answer::after, .fa-duotone.fa-teletype-answer::after {content: "\e2b9\e2b9";}.fad.fa-tugrik-sign::after, .fa-duotone.fa-tugrik-sign::after {content: "\e2ba\e2ba";}.fad.fa-turkey::after, .fa-duotone.fa-turkey::after {content: "\f725\f725";}.fad.fa-turkish-lira-sign::after, .fa-duotone.fa-turkish-lira-sign::after {content: "\e2bb\e2bb";}.fad.fa-try::after, .fa-duotone.fa-try::after {content: "\e2bb\e2bb";}.fad.fa-turkish-lira::after, .fa-duotone.fa-turkish-lira::after {content: "\e2bb\e2bb";}.fad.fa-turn-down::after, .fa-duotone.fa-turn-down::after {content: "\f3be\f3be";}.fad.fa-level-down-alt::after, .fa-duotone.fa-level-down-alt::after {content: "\f3be\f3be";}.fad.fa-turn-down-left::after, .fa-duotone.fa-turn-down-left::after {content: "\e331\e331";}.fad.fa-turn-down-right::after, .fa-duotone.fa-turn-down-right::after {content: "\e455\e455";}.fad.fa-turn-up::after, .fa-duotone.fa-turn-up::after {content: "\f3bf\f3bf";}.fad.fa-level-up-alt::after, .fa-duotone.fa-level-up-alt::after {content: "\f3bf\f3bf";}.fad.fa-turntable::after, .fa-duotone.fa-turntable::after {content: "\f8e4\f8e4";}.fad.fa-turtle::after, .fa-duotone.fa-turtle::after {content: "\f726\f726";}.fad.fa-tv::after, .fa-duotone.fa-tv::after {content: "\f26c\f26c";}.fad.fa-television::after, .fa-duotone.fa-television::after {content: "\f26c\f26c";}.fad.fa-tv-alt::after, .fa-duotone.fa-tv-alt::after {content: "\f26c\f26c";}.fad.fa-tv-music::after, .fa-duotone.fa-tv-music::after {content: "\f8e6\f8e6";}.fad.fa-tv-retro::after, .fa-duotone.fa-tv-retro::after {content: "\f401\f401";}.fad.fa-typewriter::after, .fa-duotone.fa-typewriter::after {content: "\f8e7\f8e7";}.fad.fa-u::after, .fa-duotone.fa-u::after {content: "\55\55";}.fad.fa-ufo::after, .fa-duotone.fa-ufo::after {content: "\e047\e047";}.fad.fa-ufo-beam::after, .fa-duotone.fa-ufo-beam::after {content: "\e048\e048";}.fad.fa-umbrella::after, .fa-duotone.fa-umbrella::after {content: "\f0e9\f0e9";}.fad.fa-umbrella-beach::after, .fa-duotone.fa-umbrella-beach::after {content: "\f5ca\f5ca";}.fad.fa-umbrella-simple::after, .fa-duotone.fa-umbrella-simple::after {content: "\e2bc\e2bc";}.fad.fa-umbrella-alt::after, .fa-duotone.fa-umbrella-alt::after {content: "\e2bc\e2bc";}.fad.fa-underline::after, .fa-duotone.fa-underline::after {content: "\f0cd\f0cd";}.fad.fa-unicorn::after, .fa-duotone.fa-unicorn::after {content: "\f727\f727";}.fad.fa-uniform-martial-arts::after, .fa-duotone.fa-uniform-martial-arts::after {content: "\e3d1\e3d1";}.fad.fa-union::after, .fa-duotone.fa-union::after {content: "\f6a2\f6a2";}.fad.fa-universal-access::after, .fa-duotone.fa-universal-access::after {content: "\f29a\f29a";}.fad.fa-unlock::after, .fa-duotone.fa-unlock::after {content: "\f09c\f09c";}.fad.fa-unlock-keyhole::after, .fa-duotone.fa-unlock-keyhole::after {content: "\f13e\f13e";}.fad.fa-unlock-alt::after, .fa-duotone.fa-unlock-alt::after {content: "\f13e\f13e";}.fad.fa-up::after, .fa-duotone.fa-up::after {content: "\f357\f357";}.fad.fa-arrow-alt-up::after, .fa-duotone.fa-arrow-alt-up::after {content: "\f357\f357";}.fad.fa-up-down::after, .fa-duotone.fa-up-down::after {content: "\f338\f338";}.fad.fa-arrows-alt-v::after, .fa-duotone.fa-arrows-alt-v::after {content: "\f338\f338";}.fad.fa-up-down-left-right::after, .fa-duotone.fa-up-down-left-right::after {content: "\f0b2\f0b2";}.fad.fa-arrows-alt::after, .fa-duotone.fa-arrows-alt::after {content: "\f0b2\f0b2";}.fad.fa-up-from-bracket::after, .fa-duotone.fa-up-from-bracket::after {content: "\e590\e590";}.fad.fa-up-from-dotted-line::after, .fa-duotone.fa-up-from-dotted-line::after {content: "\e456\e456";}.fad.fa-up-from-line::after, .fa-duotone.fa-up-from-line::after {content: "\f346\f346";}.fad.fa-arrow-alt-from-bottom::after, .fa-duotone.fa-arrow-alt-from-bottom::after {content: "\f346\f346";}.fad.fa-up-left::after, .fa-duotone.fa-up-left::after {content: "\e2bd\e2bd";}.fad.fa-up-long::after, .fa-duotone.fa-up-long::after {content: "\f30c\f30c";}.fad.fa-long-arrow-alt-up::after, .fa-duotone.fa-long-arrow-alt-up::after {content: "\f30c\f30c";}.fad.fa-up-right::after, .fa-duotone.fa-up-right::after {content: "\e2be\e2be";}.fad.fa-up-right-and-down-left-from-center::after, .fa-duotone.fa-up-right-and-down-left-from-center::after {content: "\f424\f424";}.fad.fa-expand-alt::after, .fa-duotone.fa-expand-alt::after {content: "\f424\f424";}.fad.fa-up-right-from-square::after, .fa-duotone.fa-up-right-from-square::after {content: "\f35d\f35d";}.fad.fa-external-link-alt::after, .fa-duotone.fa-external-link-alt::after {content: "\f35d\f35d";}.fad.fa-up-to-dotted-line::after, .fa-duotone.fa-up-to-dotted-line::after {content: "\e457\e457";}.fad.fa-up-to-line::after, .fa-duotone.fa-up-to-line::after {content: "\f34d\f34d";}.fad.fa-arrow-alt-to-top::after, .fa-duotone.fa-arrow-alt-to-top::after {content: "\f34d\f34d";}.fad.fa-upload::after, .fa-duotone.fa-upload::after {content: "\f093\f093";}.fad.fa-usb-drive::after, .fa-duotone.fa-usb-drive::after {content: "\f8e9\f8e9";}.fad.fa-user::after, .fa-duotone.fa-user::after {content: "\f007\f007";}.fad.fa-user-alien::after, .fa-duotone.fa-user-alien::after {content: "\e04a\e04a";}.fad.fa-user-astronaut::after, .fa-duotone.fa-user-astronaut::after {content: "\f4fb\f4fb";}.fad.fa-user-bounty-hunter::after, .fa-duotone.fa-user-bounty-hunter::after {content: "\e2bf\e2bf";}.fad.fa-user-check::after, .fa-duotone.fa-user-check::after {content: "\f4fc\f4fc";}.fad.fa-user-chef::after, .fa-duotone.fa-user-chef::after {content: "\e3d2\e3d2";}.fad.fa-user-clock::after, .fa-duotone.fa-user-clock::after {content: "\f4fd\f4fd";}.fad.fa-user-cowboy::after, .fa-duotone.fa-user-cowboy::after {content: "\f8ea\f8ea";}.fad.fa-user-crown::after, .fa-duotone.fa-user-crown::after {content: "\f6a4\f6a4";}.fad.fa-user-doctor::after, .fa-duotone.fa-user-doctor::after {content: "\f0f0\f0f0";}.fad.fa-user-md::after, .fa-duotone.fa-user-md::after {content: "\f0f0\f0f0";}.fad.fa-user-doctor-hair::after, .fa-duotone.fa-user-doctor-hair::after {content: "\e458\e458";}.fad.fa-user-doctor-hair-long::after, .fa-duotone.fa-user-doctor-hair-long::after {content: "\e459\e459";}.fad.fa-user-doctor-message::after, .fa-duotone.fa-user-doctor-message::after {content: "\f82e\f82e";}.fad.fa-user-md-chat::after, .fa-duotone.fa-user-md-chat::after {content: "\f82e\f82e";}.fad.fa-user-gear::after, .fa-duotone.fa-user-gear::after {content: "\f4fe\f4fe";}.fad.fa-user-cog::after, .fa-duotone.fa-user-cog::after {content: "\f4fe\f4fe";}.fad.fa-user-graduate::after, .fa-duotone.fa-user-graduate::after {content: "\f501\f501";}.fad.fa-user-group::after, .fa-duotone.fa-user-group::after {content: "\f500\f500";}.fad.fa-user-friends::after, .fa-duotone.fa-user-friends::after {content: "\f500\f500";}.fad.fa-user-group-crown::after, .fa-duotone.fa-user-group-crown::after {content: "\f6a5\f6a5";}.fad.fa-users-crown::after, .fa-duotone.fa-users-crown::after {content: "\f6a5\f6a5";}.fad.fa-user-hair::after, .fa-duotone.fa-user-hair::after {content: "\e45a\e45a";}.fad.fa-user-hair-buns::after, .fa-duotone.fa-user-hair-buns::after {content: "\e3d3\e3d3";}.fad.fa-user-hair-long::after, .fa-duotone.fa-user-hair-long::after {content: "\e45b\e45b";}.fad.fa-user-hair-mullet::after, .fa-duotone.fa-user-hair-mullet::after {content: "\e45c\e45c";}.fad.fa-business-front::after, .fa-duotone.fa-business-front::after {content: "\e45c\e45c";}.fad.fa-party-back::after, .fa-duotone.fa-party-back::after {content: "\e45c\e45c";}.fad.fa-trian-balbot::after, .fa-duotone.fa-trian-balbot::after {content: "\e45c\e45c";}.fad.fa-user-headset::after, .fa-duotone.fa-user-headset::after {content: "\f82d\f82d";}.fad.fa-user-helmet-safety::after, .fa-duotone.fa-user-helmet-safety::after {content: "\f82c\f82c";}.fad.fa-user-construction::after, .fa-duotone.fa-user-construction::after {content: "\f82c\f82c";}.fad.fa-user-hard-hat::after, .fa-duotone.fa-user-hard-hat::after {content: "\f82c\f82c";}.fad.fa-user-injured::after, .fa-duotone.fa-user-injured::after {content: "\f728\f728";}.fad.fa-user-large::after, .fa-duotone.fa-user-large::after {content: "\f406\f406";}.fad.fa-user-alt::after, .fa-duotone.fa-user-alt::after {content: "\f406\f406";}.fad.fa-user-large-slash::after, .fa-duotone.fa-user-large-slash::after {content: "\f4fa\f4fa";}.fad.fa-user-alt-slash::after, .fa-duotone.fa-user-alt-slash::after {content: "\f4fa\f4fa";}.fad.fa-user-lock::after, .fa-duotone.fa-user-lock::after {content: "\f502\f502";}.fad.fa-user-minus::after, .fa-duotone.fa-user-minus::after {content: "\f503\f503";}.fad.fa-user-music::after, .fa-duotone.fa-user-music::after {content: "\f8eb\f8eb";}.fad.fa-user-ninja::after, .fa-duotone.fa-user-ninja::after {content: "\f504\f504";}.fad.fa-user-nurse::after, .fa-duotone.fa-user-nurse::after {content: "\f82f\f82f";}.fad.fa-user-nurse-hair::after, .fa-duotone.fa-user-nurse-hair::after {content: "\e45d\e45d";}.fad.fa-user-nurse-hair-long::after, .fa-duotone.fa-user-nurse-hair-long::after {content: "\e45e\e45e";}.fad.fa-user-pen::after, .fa-duotone.fa-user-pen::after {content: "\f4ff\f4ff";}.fad.fa-user-edit::after, .fa-duotone.fa-user-edit::after {content: "\f4ff\f4ff";}.fad.fa-user-pilot::after, .fa-duotone.fa-user-pilot::after {content: "\e2c0\e2c0";}.fad.fa-user-pilot-tie::after, .fa-duotone.fa-user-pilot-tie::after {content: "\e2c1\e2c1";}.fad.fa-user-plus::after, .fa-duotone.fa-user-plus::after {content: "\f234\f234";}.fad.fa-user-police::after, .fa-duotone.fa-user-police::after {content: "\e333\e333";}.fad.fa-user-police-tie::after, .fa-duotone.fa-user-police-tie::after {content: "\e334\e334";}.fad.fa-user-robot::after, .fa-duotone.fa-user-robot::after {content: "\e04b\e04b";}.fad.fa-user-robot-xmarks::after, .fa-duotone.fa-user-robot-xmarks::after {content: "\e4a7\e4a7";}.fad.fa-user-secret::after, .fa-duotone.fa-user-secret::after {content: "\f21b\f21b";}.fad.fa-user-shakespeare::after, .fa-duotone.fa-user-shakespeare::after {content: "\e2c2\e2c2";}.fad.fa-user-shield::after, .fa-duotone.fa-user-shield::after {content: "\f505\f505";}.fad.fa-user-slash::after, .fa-duotone.fa-user-slash::after {content: "\f506\f506";}.fad.fa-user-tag::after, .fa-duotone.fa-user-tag::after {content: "\f507\f507";}.fad.fa-user-tie::after, .fa-duotone.fa-user-tie::after {content: "\f508\f508";}.fad.fa-user-tie-hair::after, .fa-duotone.fa-user-tie-hair::after {content: "\e45f\e45f";}.fad.fa-user-tie-hair-long::after, .fa-duotone.fa-user-tie-hair-long::after {content: "\e460\e460";}.fad.fa-user-unlock::after, .fa-duotone.fa-user-unlock::after {content: "\e058\e058";}.fad.fa-user-visor::after, .fa-duotone.fa-user-visor::after {content: "\e04c\e04c";}.fad.fa-user-vneck::after, .fa-duotone.fa-user-vneck::after {content: "\e461\e461";}.fad.fa-user-vneck-hair::after, .fa-duotone.fa-user-vneck-hair::after {content: "\e462\e462";}.fad.fa-user-vneck-hair-long::after, .fa-duotone.fa-user-vneck-hair-long::after {content: "\e463\e463";}.fad.fa-user-xmark::after, .fa-duotone.fa-user-xmark::after {content: "\f235\f235";}.fad.fa-user-times::after, .fa-duotone.fa-user-times::after {content: "\f235\f235";}.fad.fa-users::after, .fa-duotone.fa-users::after {content: "\f0c0\f0c0";}.fad.fa-users-between-lines::after, .fa-duotone.fa-users-between-lines::after {content: "\e591\e591";}.fad.fa-users-gear::after, .fa-duotone.fa-users-gear::after {content: "\f509\f509";}.fad.fa-users-cog::after, .fa-duotone.fa-users-cog::after {content: "\f509\f509";}.fad.fa-users-line::after, .fa-duotone.fa-users-line::after {content: "\e592\e592";}.fad.fa-users-medical::after, .fa-duotone.fa-users-medical::after {content: "\f830\f830";}.fad.fa-users-rays::after, .fa-duotone.fa-users-rays::after {content: "\e593\e593";}.fad.fa-users-rectangle::after, .fa-duotone.fa-users-rectangle::after {content: "\e594\e594";}.fad.fa-users-slash::after, .fa-duotone.fa-users-slash::after {content: "\e073\e073";}.fad.fa-users-viewfinder::after, .fa-duotone.fa-users-viewfinder::after {content: "\e595\e595";}.fad.fa-utensils::after, .fa-duotone.fa-utensils::after {content: "\f2e7\f2e7";}.fad.fa-cutlery::after, .fa-duotone.fa-cutlery::after {content: "\f2e7\f2e7";}.fad.fa-utensils-slash::after, .fa-duotone.fa-utensils-slash::after {content: "\e464\e464";}.fad.fa-utility-pole::after, .fa-duotone.fa-utility-pole::after {content: "\e2c3\e2c3";}.fad.fa-utility-pole-double::after, .fa-duotone.fa-utility-pole-double::after {content: "\e2c4\e2c4";}.fad.fa-v::after, .fa-duotone.fa-v::after {content: "\56\56";}.fad.fa-vacuum::after, .fa-duotone.fa-vacuum::after {content: "\e04d\e04d";}.fad.fa-vacuum-robot::after, .fa-duotone.fa-vacuum-robot::after {content: "\e04e\e04e";}.fad.fa-value-absolute::after, .fa-duotone.fa-value-absolute::after {content: "\f6a6\f6a6";}.fad.fa-van-shuttle::after, .fa-duotone.fa-van-shuttle::after {content: "\f5b6\f5b6";}.fad.fa-shuttle-van::after, .fa-duotone.fa-shuttle-van::after {content: "\f5b6\f5b6";}.fad.fa-vault::after, .fa-duotone.fa-vault::after {content: "\e2c5\e2c5";}.fad.fa-vector-circle::after, .fa-duotone.fa-vector-circle::after {content: "\e2c6\e2c6";}.fad.fa-vector-polygon::after, .fa-duotone.fa-vector-polygon::after {content: "\e2c7\e2c7";}.fad.fa-vector-square::after, .fa-duotone.fa-vector-square::after {content: "\f5cb\f5cb";}.fad.fa-vent-damper::after, .fa-duotone.fa-vent-damper::after {content: "\e465\e465";}.fad.fa-venus::after, .fa-duotone.fa-venus::after {content: "\f221\f221";}.fad.fa-venus-double::after, .fa-duotone.fa-venus-double::after {content: "\f226\f226";}.fad.fa-venus-mars::after, .fa-duotone.fa-venus-mars::after {content: "\f228\f228";}.fad.fa-vest::after, .fa-duotone.fa-vest::after {content: "\e085\e085";}.fad.fa-vest-patches::after, .fa-duotone.fa-vest-patches::after {content: "\e086\e086";}.fad.fa-vial::after, .fa-duotone.fa-vial::after {content: "\f492\f492";}.fad.fa-vial-circle-check::after, .fa-duotone.fa-vial-circle-check::after {content: "\e596\e596";}.fad.fa-vial-virus::after, .fa-duotone.fa-vial-virus::after {content: "\e597\e597";}.fad.fa-vials::after, .fa-duotone.fa-vials::after {content: "\f493\f493";}.fad.fa-video::after, .fa-duotone.fa-video::after {content: "\f03d\f03d";}.fad.fa-video-camera::after, .fa-duotone.fa-video-camera::after {content: "\f03d\f03d";}.fad.fa-video-arrow-down-left::after, .fa-duotone.fa-video-arrow-down-left::after {content: "\e2c8\e2c8";}.fad.fa-video-arrow-up-right::after, .fa-duotone.fa-video-arrow-up-right::after {content: "\e2c9\e2c9";}.fad.fa-video-plus::after, .fa-duotone.fa-video-plus::after {content: "\f4e1\f4e1";}.fad.fa-video-slash::after, .fa-duotone.fa-video-slash::after {content: "\f4e2\f4e2";}.fad.fa-vihara::after, .fa-duotone.fa-vihara::after {content: "\f6a7\f6a7";}.fad.fa-violin::after, .fa-duotone.fa-violin::after {content: "\f8ed\f8ed";}.fad.fa-virus::after, .fa-duotone.fa-virus::after {content: "\e074\e074";}.fad.fa-virus-covid::after, .fa-duotone.fa-virus-covid::after {content: "\e4a8\e4a8";}.fad.fa-virus-covid-slash::after, .fa-duotone.fa-virus-covid-slash::after {content: "\e4a9\e4a9";}.fad.fa-virus-slash::after, .fa-duotone.fa-virus-slash::after {content: "\e075\e075";}.fad.fa-viruses::after, .fa-duotone.fa-viruses::after {content: "\e076\e076";}.fad.fa-voicemail::after, .fa-duotone.fa-voicemail::after {content: "\f897\f897";}.fad.fa-volcano::after, .fa-duotone.fa-volcano::after {content: "\f770\f770";}.fad.fa-volleyball::after, .fa-duotone.fa-volleyball::after {content: "\f45f\f45f";}.fad.fa-volleyball-ball::after, .fa-duotone.fa-volleyball-ball::after {content: "\f45f\f45f";}.fad.fa-volume::after, .fa-duotone.fa-volume::after {content: "\f6a8\f6a8";}.fad.fa-volume-medium::after, .fa-duotone.fa-volume-medium::after {content: "\f6a8\f6a8";}.fad.fa-volume-high::after, .fa-duotone.fa-volume-high::after {content: "\f028\f028";}.fad.fa-volume-up::after, .fa-duotone.fa-volume-up::after {content: "\f028\f028";}.fad.fa-volume-low::after, .fa-duotone.fa-volume-low::after {content: "\f027\f027";}.fad.fa-volume-down::after, .fa-duotone.fa-volume-down::after {content: "\f027\f027";}.fad.fa-volume-off::after, .fa-duotone.fa-volume-off::after {content: "\f026\f026";}.fad.fa-volume-slash::after, .fa-duotone.fa-volume-slash::after {content: "\f2e2\f2e2";}.fad.fa-volume-xmark::after, .fa-duotone.fa-volume-xmark::after {content: "\f6a9\f6a9";}.fad.fa-volume-mute::after, .fa-duotone.fa-volume-mute::after {content: "\f6a9\f6a9";}.fad.fa-volume-times::after, .fa-duotone.fa-volume-times::after {content: "\f6a9\f6a9";}.fad.fa-vr-cardboard::after, .fa-duotone.fa-vr-cardboard::after {content: "\f729\f729";}.fad.fa-w::after, .fa-duotone.fa-w::after {content: "\57\57";}.fad.fa-waffle::after, .fa-duotone.fa-waffle::after {content: "\e466\e466";}.fad.fa-wagon-covered::after, .fa-duotone.fa-wagon-covered::after {content: "\f8ee\f8ee";}.fad.fa-walker::after, .fa-duotone.fa-walker::after {content: "\f831\f831";}.fad.fa-walkie-talkie::after, .fa-duotone.fa-walkie-talkie::after {content: "\f8ef\f8ef";}.fad.fa-wallet::after, .fa-duotone.fa-wallet::after {content: "\f555\f555";}.fad.fa-wand::after, .fa-duotone.fa-wand::after {content: "\f72a\f72a";}.fad.fa-wand-magic::after, .fa-duotone.fa-wand-magic::after {content: "\f0d0\f0d0";}.fad.fa-magic::after, .fa-duotone.fa-magic::after {content: "\f0d0\f0d0";}.fad.fa-wand-magic-sparkles::after, .fa-duotone.fa-wand-magic-sparkles::after {content: "\e2ca\e2ca";}.fad.fa-magic-wand-sparkles::after, .fa-duotone.fa-magic-wand-sparkles::after {content: "\e2ca\e2ca";}.fad.fa-wand-sparkles::after, .fa-duotone.fa-wand-sparkles::after {content: "\f72b\f72b";}.fad.fa-warehouse::after, .fa-duotone.fa-warehouse::after {content: "\f494\f494";}.fad.fa-warehouse-full::after, .fa-duotone.fa-warehouse-full::after {content: "\f495\f495";}.fad.fa-warehouse-alt::after, .fa-duotone.fa-warehouse-alt::after {content: "\f495\f495";}.fad.fa-washing-machine::after, .fa-duotone.fa-washing-machine::after {content: "\f898\f898";}.fad.fa-washer::after, .fa-duotone.fa-washer::after {content: "\f898\f898";}.fad.fa-watch::after, .fa-duotone.fa-watch::after {content: "\f2e1\f2e1";}.fad.fa-watch-apple::after, .fa-duotone.fa-watch-apple::after {content: "\e2cb\e2cb";}.fad.fa-watch-calculator::after, .fa-duotone.fa-watch-calculator::after {content: "\f8f0\f8f0";}.fad.fa-watch-fitness::after, .fa-duotone.fa-watch-fitness::after {content: "\f63e\f63e";}.fad.fa-watch-smart::after, .fa-duotone.fa-watch-smart::after {content: "\e2cc\e2cc";}.fad.fa-water::after, .fa-duotone.fa-water::after {content: "\f773\f773";}.fad.fa-water-arrow-down::after, .fa-duotone.fa-water-arrow-down::after {content: "\f774\f774";}.fad.fa-water-lower::after, .fa-duotone.fa-water-lower::after {content: "\f774\f774";}.fad.fa-water-arrow-up::after, .fa-duotone.fa-water-arrow-up::after {content: "\f775\f775";}.fad.fa-water-rise::after, .fa-duotone.fa-water-rise::after {content: "\f775\f775";}.fad.fa-water-ladder::after, .fa-duotone.fa-water-ladder::after {content: "\f5c5\f5c5";}.fad.fa-ladder-water::after, .fa-duotone.fa-ladder-water::after {content: "\f5c5\f5c5";}.fad.fa-swimming-pool::after, .fa-duotone.fa-swimming-pool::after {content: "\f5c5\f5c5";}.fad.fa-watermelon-slice::after, .fa-duotone.fa-watermelon-slice::after {content: "\e337\e337";}.fad.fa-wave-pulse::after, .fa-duotone.fa-wave-pulse::after {content: "\f5f8\f5f8";}.fad.fa-heart-rate::after, .fa-duotone.fa-heart-rate::after {content: "\f5f8\f5f8";}.fad.fa-wave-sine::after, .fa-duotone.fa-wave-sine::after {content: "\f899\f899";}.fad.fa-wave-square::after, .fa-duotone.fa-wave-square::after {content: "\f83e\f83e";}.fad.fa-wave-triangle::after, .fa-duotone.fa-wave-triangle::after {content: "\f89a\f89a";}.fad.fa-waveform::after, .fa-duotone.fa-waveform::after {content: "\f8f1\f8f1";}.fad.fa-waveform-lines::after, .fa-duotone.fa-waveform-lines::after {content: "\f8f2\f8f2";}.fad.fa-waveform-path::after, .fa-duotone.fa-waveform-path::after {content: "\f8f2\f8f2";}.fad.fa-weight-hanging::after, .fa-duotone.fa-weight-hanging::after {content: "\f5cd\f5cd";}.fad.fa-weight-scale::after, .fa-duotone.fa-weight-scale::after {content: "\f496\f496";}.fad.fa-weight::after, .fa-duotone.fa-weight::after {content: "\f496\f496";}.fad.fa-whale::after, .fa-duotone.fa-whale::after {content: "\f72c\f72c";}.fad.fa-wheat::after, .fa-duotone.fa-wheat::after {content: "\f72d\f72d";}.fad.fa-wheat-awn::after, .fa-duotone.fa-wheat-awn::after {content: "\e2cd\e2cd";}.fad.fa-wheat-alt::after, .fa-duotone.fa-wheat-alt::after {content: "\e2cd\e2cd";}.fad.fa-wheat-awn-circle-exclamation::after, .fa-duotone.fa-wheat-awn-circle-exclamation::after {content: "\e598\e598";}.fad.fa-wheat-awn-slash::after, .fa-duotone.fa-wheat-awn-slash::after {content: "\e338\e338";}.fad.fa-wheat-slash::after, .fa-duotone.fa-wheat-slash::after {content: "\e339\e339";}.fad.fa-wheelchair::after, .fa-duotone.fa-wheelchair::after {content: "\f193\f193";}.fad.fa-wheelchair-move::after, .fa-duotone.fa-wheelchair-move::after {content: "\e2ce\e2ce";}.fad.fa-wheelchair-alt::after, .fa-duotone.fa-wheelchair-alt::after {content: "\e2ce\e2ce";}.fad.fa-whiskey-glass::after, .fa-duotone.fa-whiskey-glass::after {content: "\f7a0\f7a0";}.fad.fa-glass-whiskey::after, .fa-duotone.fa-glass-whiskey::after {content: "\f7a0\f7a0";}.fad.fa-whiskey-glass-ice::after, .fa-duotone.fa-whiskey-glass-ice::after {content: "\f7a1\f7a1";}.fad.fa-glass-whiskey-rocks::after, .fa-duotone.fa-glass-whiskey-rocks::after {content: "\f7a1\f7a1";}.fad.fa-whistle::after, .fa-duotone.fa-whistle::after {content: "\f460\f460";}.fad.fa-wifi::after, .fa-duotone.fa-wifi::after {content: "\f1eb\f1eb";}.fad.fa-wifi-3::after, .fa-duotone.fa-wifi-3::after {content: "\f1eb\f1eb";}.fad.fa-wifi-strong::after, .fa-duotone.fa-wifi-strong::after {content: "\f1eb\f1eb";}.fad.fa-wifi-exclamation::after, .fa-duotone.fa-wifi-exclamation::after {content: "\e2cf\e2cf";}.fad.fa-wifi-fair::after, .fa-duotone.fa-wifi-fair::after {content: "\f6ab\f6ab";}.fad.fa-wifi-2::after, .fa-duotone.fa-wifi-2::after {content: "\f6ab\f6ab";}.fad.fa-wifi-slash::after, .fa-duotone.fa-wifi-slash::after {content: "\f6ac\f6ac";}.fad.fa-wifi-weak::after, .fa-duotone.fa-wifi-weak::after {content: "\f6aa\f6aa";}.fad.fa-wifi-1::after, .fa-duotone.fa-wifi-1::after {content: "\f6aa\f6aa";}.fad.fa-wind::after, .fa-duotone.fa-wind::after {content: "\f72e\f72e";}.fad.fa-wind-turbine::after, .fa-duotone.fa-wind-turbine::after {content: "\f89b\f89b";}.fad.fa-wind-warning::after, .fa-duotone.fa-wind-warning::after {content: "\f776\f776";}.fad.fa-wind-circle-exclamation::after, .fa-duotone.fa-wind-circle-exclamation::after {content: "\f776\f776";}.fad.fa-window::after, .fa-duotone.fa-window::after {content: "\f40e\f40e";}.fad.fa-window-flip::after, .fa-duotone.fa-window-flip::after {content: "\f40f\f40f";}.fad.fa-window-alt::after, .fa-duotone.fa-window-alt::after {content: "\f40f\f40f";}.fad.fa-window-frame::after, .fa-duotone.fa-window-frame::after {content: "\e04f\e04f";}.fad.fa-window-frame-open::after, .fa-duotone.fa-window-frame-open::after {content: "\e050\e050";}.fad.fa-window-maximize::after, .fa-duotone.fa-window-maximize::after {content: "\f2d0\f2d0";}.fad.fa-window-minimize::after, .fa-duotone.fa-window-minimize::after {content: "\f2d1\f2d1";}.fad.fa-window-restore::after, .fa-duotone.fa-window-restore::after {content: "\f2d2\f2d2";}.fad.fa-windsock::after, .fa-duotone.fa-windsock::after {content: "\f777\f777";}.fad.fa-wine-bottle::after, .fa-duotone.fa-wine-bottle::after {content: "\f72f\f72f";}.fad.fa-wine-glass::after, .fa-duotone.fa-wine-glass::after {content: "\f4e3\f4e3";}.fad.fa-wine-glass-crack::after, .fa-duotone.fa-wine-glass-crack::after {content: "\f4bb\f4bb";}.fad.fa-fragile::after, .fa-duotone.fa-fragile::after {content: "\f4bb\f4bb";}.fad.fa-wine-glass-empty::after, .fa-duotone.fa-wine-glass-empty::after {content: "\f5ce\f5ce";}.fad.fa-wine-glass-alt::after, .fa-duotone.fa-wine-glass-alt::after {content: "\f5ce\f5ce";}.fad.fa-won-sign::after, .fa-duotone.fa-won-sign::after {content: "\f159\f159";}.fad.fa-krw::after, .fa-duotone.fa-krw::after {content: "\f159\f159";}.fad.fa-won::after, .fa-duotone.fa-won::after {content: "\f159\f159";}.fad.fa-worm::after, .fa-duotone.fa-worm::after {content: "\e599\e599";}.fad.fa-wreath::after, .fa-duotone.fa-wreath::after {content: "\f7e2\f7e2";}.fad.fa-wrench::after, .fa-duotone.fa-wrench::after {content: "\f0ad\f0ad";}.fad.fa-wrench-simple::after, .fa-duotone.fa-wrench-simple::after {content: "\e2d1\e2d1";}.fad.fa-x::after, .fa-duotone.fa-x::after {content: "\58\58";}.fad.fa-x-ray::after, .fa-duotone.fa-x-ray::after {content: "\f497\f497";}.fad.fa-xmark::after, .fa-duotone.fa-xmark::after {content: "\f00d\f00d";}.fad.fa-close::after, .fa-duotone.fa-close::after {content: "\f00d\f00d";}.fad.fa-multiply::after, .fa-duotone.fa-multiply::after {content: "\f00d\f00d";}.fad.fa-remove::after, .fa-duotone.fa-remove::after {content: "\f00d\f00d";}.fad.fa-times::after, .fa-duotone.fa-times::after {content: "\f00d\f00d";}.fad.fa-xmark-large::after, .fa-duotone.fa-xmark-large::after {content: "\e59b\e59b";}.fad.fa-xmark-to-slot::after, .fa-duotone.fa-xmark-to-slot::after {content: "\f771\f771";}.fad.fa-times-to-slot::after, .fa-duotone.fa-times-to-slot::after {content: "\f771\f771";}.fad.fa-vote-nay::after, .fa-duotone.fa-vote-nay::after {content: "\f771\f771";}.fad.fa-xmarks-lines::after, .fa-duotone.fa-xmarks-lines::after {content: "\e59a\e59a";}.fad.fa-y::after, .fa-duotone.fa-y::after {content: "\59\59";}.fad.fa-yen-sign::after, .fa-duotone.fa-yen-sign::after {content: "\f157\f157";}.fad.fa-cny::after, .fa-duotone.fa-cny::after {content: "\f157\f157";}.fad.fa-jpy::after, .fa-duotone.fa-jpy::after {content: "\f157\f157";}.fad.fa-rmb::after, .fa-duotone.fa-rmb::after {content: "\f157\f157";}.fad.fa-yen::after, .fa-duotone.fa-yen::after {content: "\f157\f157";}.fad.fa-yin-yang::after, .fa-duotone.fa-yin-yang::after {content: "\f6ad\f6ad";}.fad.fa-z::after, .fa-duotone.fa-z::after {content: "\5a\5a";}:root, :host {--fa-font-light: normal 300 1em/1 "Font Awesome 6 Pro";}@font-face {font-family: 'Font Awesome 6 Pro';font-style: normal;font-weight: 300;font-display: block;src: url("../webfonts/fa-light-300.woff2") format("woff2"), url("../webfonts/fa-light-300.ttf") format("truetype");}.fal, .fa-light {font-family: 'Font Awesome 6 Pro';font-weight: 300;}:root, :host {--fa-font-regular: normal 400 1em/1 "Font Awesome 6 Pro";}@font-face {font-family: 'Font Awesome 6 Pro';font-style: normal;font-weight: 400;font-display: block;src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype");}.far, .fa-regular {font-family: 'Font Awesome 6 Pro';font-weight: 400;}:root, :host {--fa-font-solid: normal 900 1em/1 "Font Awesome 6 Pro";}@font-face {font-family: 'Font Awesome 6 Pro';font-style: normal;font-weight: 900;font-display: block;src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype");}.fas, .fa-solid {font-family: 'Font Awesome 6 Pro';font-weight: 900;}:root, :host {--fa-font-thin: normal 100 1em/1 "Font Awesome 6 Pro";}@font-face {font-family: 'Font Awesome 6 Pro';font-style: normal;font-weight: 100;font-display: block;src: url("../webfonts/fa-thin-100.woff2") format("woff2"), url("../webfonts/fa-thin-100.ttf") format("truetype");}.fat, .fa-thin {font-family: 'Font Awesome 6 Pro';font-weight: 100;}@font-face {font-family: "Font Awesome 5 Brands";font-display: block;font-weight: 400;src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype");}@font-face {font-family: "Font Awesome 5 Pro";font-display: block;font-weight: 900;src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype");}@font-face {font-family: "Font Awesome 5 Pro";font-display: block;font-weight: 400;src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype");}@font-face {font-family: "Font Awesome 5 Pro";font-display: block;font-weight: 300;src: url("../webfonts/fa-light-300.woff2") format("woff2"), url("../webfonts/fa-light-300.ttf") format("truetype");}@font-face {font-family: "Font Awesome 5 Duotone";font-display: block;font-weight: 900;src: url("../webfonts/fa-duotone-900.woff2") format("woff2"), url("../webfonts/fa-duotone-900.ttf") format("truetype");}@font-face {font-family: "FontAwesome";font-display: block;src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype");}@font-face {font-family: "FontAwesome";font-display: block;src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype");}@font-face {font-family: "FontAwesome";font-display: block;src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype");unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC;}@font-face {font-family: "FontAwesome";font-display: block;src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype");unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F250,U+F252,U+F27A;} diff --git a/docs/static/images/android-chrome-192x192.png b/docs/static/images/android-chrome-192x192.png new file mode 100644 index 00000000..dfd6ed0a Binary files /dev/null and b/docs/static/images/android-chrome-192x192.png differ diff --git a/docs/static/images/android-chrome-512x512.png b/docs/static/images/android-chrome-512x512.png new file mode 100644 index 00000000..290a1b11 Binary files /dev/null and b/docs/static/images/android-chrome-512x512.png differ diff --git a/docs/static/images/apple-touch-icon.png b/docs/static/images/apple-touch-icon.png new file mode 100644 index 00000000..0eefb94e Binary files /dev/null and b/docs/static/images/apple-touch-icon.png differ diff --git a/docs/static/images/favicon-16x16.png b/docs/static/images/favicon-16x16.png new file mode 100644 index 00000000..f7dbde78 Binary files /dev/null and b/docs/static/images/favicon-16x16.png differ diff --git a/docs/static/images/favicon-32x32.png b/docs/static/images/favicon-32x32.png new file mode 100644 index 00000000..1963b089 Binary files /dev/null and b/docs/static/images/favicon-32x32.png differ diff --git a/docs/static/images/favicon.ico b/docs/static/images/favicon.ico new file mode 100644 index 00000000..a37be997 Binary files /dev/null and b/docs/static/images/favicon.ico differ diff --git a/docs/static/images/favicon.png b/docs/static/images/favicon.png new file mode 100644 index 00000000..f02d9416 Binary files /dev/null and b/docs/static/images/favicon.png differ diff --git a/docs/static/images/flasher-usage.png b/docs/static/images/flasher-usage.png new file mode 100644 index 00000000..d1efeac4 Binary files /dev/null and b/docs/static/images/flasher-usage.png differ diff --git a/docs/static/images/logo.png b/docs/static/images/logo.png new file mode 100644 index 00000000..ca5413c1 Binary files /dev/null and b/docs/static/images/logo.png differ diff --git a/docs/static/images/motion-notifications.png b/docs/static/images/motion-notifications.png new file mode 100644 index 00000000..3c986570 Binary files /dev/null and b/docs/static/images/motion-notifications.png differ diff --git a/docs/static/images/mstile-150x150.png b/docs/static/images/mstile-150x150.png new file mode 100644 index 00000000..8fec03ce Binary files /dev/null and b/docs/static/images/mstile-150x150.png differ diff --git a/docs/static/images/php-flasher-logo-bell.png b/docs/static/images/php-flasher-logo-bell.png new file mode 100644 index 00000000..b3f62487 Binary files /dev/null and b/docs/static/images/php-flasher-logo-bell.png differ diff --git a/docs/static/images/php-flasher-logo-bell.svg b/docs/static/images/php-flasher-logo-bell.svg new file mode 100644 index 00000000..00e0512e --- /dev/null +++ b/docs/static/images/php-flasher-logo-bell.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/static/images/php-flasher-logo-dark.png b/docs/static/images/php-flasher-logo-dark.png new file mode 100644 index 00000000..d8e1fe65 Binary files /dev/null and b/docs/static/images/php-flasher-logo-dark.png differ diff --git a/docs/static/images/php-flasher-logo-dark.svg b/docs/static/images/php-flasher-logo-dark.svg new file mode 100644 index 00000000..b5839bc0 --- /dev/null +++ b/docs/static/images/php-flasher-logo-dark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/static/images/php-flasher-logo.png b/docs/static/images/php-flasher-logo.png new file mode 100644 index 00000000..836c8b0a Binary files /dev/null and b/docs/static/images/php-flasher-logo.png differ diff --git a/docs/static/images/php-flasher-logo.svg b/docs/static/images/php-flasher-logo.svg new file mode 100644 index 00000000..47e454d2 --- /dev/null +++ b/docs/static/images/php-flasher-logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/static/images/php-flasher-social-card.jpg b/docs/static/images/php-flasher-social-card.jpg new file mode 100644 index 00000000..8f1dea4b Binary files /dev/null and b/docs/static/images/php-flasher-social-card.jpg differ diff --git a/docs/static/images/php-flasher-social-card.png b/docs/static/images/php-flasher-social-card.png new file mode 100644 index 00000000..0457a470 Binary files /dev/null and b/docs/static/images/php-flasher-social-card.png differ diff --git a/docs/static/images/php-flasher.png b/docs/static/images/php-flasher.png new file mode 100644 index 00000000..b18d2f0e Binary files /dev/null and b/docs/static/images/php-flasher.png differ diff --git a/docs/static/images/render-notifications.png b/docs/static/images/render-notifications.png new file mode 100644 index 00000000..b9587d47 Binary files /dev/null and b/docs/static/images/render-notifications.png differ diff --git a/docs/static/images/safari-pinned-tab.svg b/docs/static/images/safari-pinned-tab.svg new file mode 100644 index 00000000..51917ef4 --- /dev/null +++ b/docs/static/images/safari-pinned-tab.svg @@ -0,0 +1,36 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/docs/static/images/squares.svg b/docs/static/images/squares.svg new file mode 100644 index 00000000..1c93a4c8 --- /dev/null +++ b/docs/static/images/squares.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/docs/static/images/twitter-card.png b/docs/static/images/twitter-card.png new file mode 100644 index 00000000..10841c88 Binary files /dev/null and b/docs/static/images/twitter-card.png differ diff --git a/docs/static/images/twitter.svg b/docs/static/images/twitter.svg new file mode 100644 index 00000000..72698e9d --- /dev/null +++ b/docs/static/images/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/docs/static/images/younes-khoubza.jpeg b/docs/static/images/younes-khoubza.jpeg new file mode 100644 index 00000000..2ad47326 Binary files /dev/null and b/docs/static/images/younes-khoubza.jpeg differ diff --git a/docs/static/sounds/notification.wav b/docs/static/sounds/notification.wav new file mode 100644 index 00000000..cda91f41 Binary files /dev/null and b/docs/static/sounds/notification.wav differ diff --git a/docs/static/webfonts/fa-brands-400.ttf b/docs/static/webfonts/fa-brands-400.ttf new file mode 100644 index 00000000..3e5d9ffb Binary files /dev/null and b/docs/static/webfonts/fa-brands-400.ttf differ diff --git a/docs/static/webfonts/fa-brands-400.woff2 b/docs/static/webfonts/fa-brands-400.woff2 new file mode 100644 index 00000000..64a7ce5f Binary files /dev/null and b/docs/static/webfonts/fa-brands-400.woff2 differ diff --git a/docs/static/webfonts/fa-duotone-900.ttf b/docs/static/webfonts/fa-duotone-900.ttf new file mode 100644 index 00000000..9f4b6402 Binary files /dev/null and b/docs/static/webfonts/fa-duotone-900.ttf differ diff --git a/docs/static/webfonts/fa-duotone-900.woff2 b/docs/static/webfonts/fa-duotone-900.woff2 new file mode 100644 index 00000000..e6f5d5e3 Binary files /dev/null and b/docs/static/webfonts/fa-duotone-900.woff2 differ diff --git a/docs/static/webfonts/fa-light-300.ttf b/docs/static/webfonts/fa-light-300.ttf new file mode 100644 index 00000000..1179b2d5 Binary files /dev/null and b/docs/static/webfonts/fa-light-300.ttf differ diff --git a/docs/static/webfonts/fa-light-300.woff2 b/docs/static/webfonts/fa-light-300.woff2 new file mode 100644 index 00000000..ca29e058 Binary files /dev/null and b/docs/static/webfonts/fa-light-300.woff2 differ diff --git a/docs/static/webfonts/fa-regular-400.ttf b/docs/static/webfonts/fa-regular-400.ttf new file mode 100644 index 00000000..7c102868 Binary files /dev/null and b/docs/static/webfonts/fa-regular-400.ttf differ diff --git a/docs/static/webfonts/fa-regular-400.woff2 b/docs/static/webfonts/fa-regular-400.woff2 new file mode 100644 index 00000000..e1af3761 Binary files /dev/null and b/docs/static/webfonts/fa-regular-400.woff2 differ diff --git a/docs/static/webfonts/fa-solid-900.ttf b/docs/static/webfonts/fa-solid-900.ttf new file mode 100644 index 00000000..77cb15ed Binary files /dev/null and b/docs/static/webfonts/fa-solid-900.ttf differ diff --git a/docs/static/webfonts/fa-solid-900.woff2 b/docs/static/webfonts/fa-solid-900.woff2 new file mode 100644 index 00000000..5b5f605c Binary files /dev/null and b/docs/static/webfonts/fa-solid-900.woff2 differ diff --git a/docs/static/webfonts/fa-thin-100.ttf b/docs/static/webfonts/fa-thin-100.ttf new file mode 100644 index 00000000..d17e2e13 Binary files /dev/null and b/docs/static/webfonts/fa-thin-100.ttf differ diff --git a/docs/static/webfonts/fa-thin-100.woff2 b/docs/static/webfonts/fa-thin-100.woff2 new file mode 100644 index 00000000..0e6ecc58 Binary files /dev/null and b/docs/static/webfonts/fa-thin-100.woff2 differ diff --git a/docs/static/webfonts/fa-v4compatibility.ttf b/docs/static/webfonts/fa-v4compatibility.ttf new file mode 100644 index 00000000..9ab9091d Binary files /dev/null and b/docs/static/webfonts/fa-v4compatibility.ttf differ diff --git a/docs/static/webfonts/fa-v4compatibility.woff2 b/docs/static/webfonts/fa-v4compatibility.woff2 new file mode 100644 index 00000000..747d39cb Binary files /dev/null and b/docs/static/webfonts/fa-v4compatibility.woff2 differ diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js new file mode 100644 index 00000000..d166359f --- /dev/null +++ b/docs/tailwind.config.js @@ -0,0 +1,7 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './_site/**/*.html', + './_site/**/*.js', + ], +} diff --git a/docs/webpack.config.js b/docs/webpack.config.js new file mode 100644 index 00000000..75067d30 --- /dev/null +++ b/docs/webpack.config.js @@ -0,0 +1,35 @@ +const process = require('node:process') +const Encore = require('@symfony/webpack-encore') + +if (!Encore.isRuntimeEnvironmentConfigured()) { + Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev') +} + +Encore + .setOutputPath('dist/') + .setPublicPath('/dist') + + // Clean up the output directory before building + .cleanupOutputBeforeBuild() + + .disableSingleRuntimeChunk() + + .enableSourceMaps(!Encore.isProduction()) + .enableVersioning(Encore.isProduction()) + + // Enable notifications on build completion/errors + .enableBuildNotifications() + + // enables the Symfony UX Stimulus bridge (used in assets/js/stimulus.js) + .enableStimulusBridge('./assets/controllers.json') + + // Enable scss and postcss support for styling + .enablePostCssLoader() + + .configureManifestPlugin((options) => { + options.fileName = '../_data/manifest.json' + }) + + .addEntry('main', './assets/js/main.js') + +module.exports = Encore.getWebpackConfig() diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..75c128e4 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,32 @@ +import antfu from '@antfu/eslint-config' + +export default antfu( + { + stylistic: { + indent: 4, + }, + + typescript: true, + ignores: [ + '.github', + 'dist', + 'node_modules', + ], + }, + { + rules: { + 'style/brace-style': ['error', '1tbs'], + 'style/arrow-parens': ['error', 'always'], + 'curly': ['error', 'all'], + 'antfu/consistent-list-newline': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + 'ts/consistent-type-definitions': 'off', + }, + }, + { + files: ['package.json'], + rules: { + 'style/eol-last': 'off', + }, + }, +) diff --git a/extension.neon b/extension.neon new file mode 100644 index 00000000..843ad3af --- /dev/null +++ b/extension.neon @@ -0,0 +1,3 @@ +includes: + - src/Prime/extension.neon + - src/Laravel/extension.neon diff --git a/grumphp.yml b/grumphp.yml deleted file mode 100644 index c5a71a70..00000000 --- a/grumphp.yml +++ /dev/null @@ -1,41 +0,0 @@ -grumphp: - ascii: ~ - tasks: - # composer: ~ - # composer_normalize: ~ - # composer_script: - # script: check-syntax - # phpcsfixer: ~ - # jsonlint: ~ - # yamllint: ~ - # phpstan: ~ - # phpunit: ~ - # git_branch_name: - # blacklist: - # - main - git_commit_message: - allow_empty_message: false - enforce_capitalized_subject: false - max_subject_width: 93 - type_scope_conventions: - types: - - build - - ci - - chore - - docs - - feat - - fix - - perf - - refactor - - revert - - style - - test - scopes: - - core - - flasher - - toastr - - noty - - notyf - - pnotify - - sweetalert - - notify diff --git a/monorepo-builder.php b/monorepo-builder.php index 73985e9c..549a7d0a 100644 --- a/monorepo-builder.php +++ b/monorepo-builder.php @@ -1,25 +1,11 @@ - */ +declare(strict_types=1); use Symplify\MonorepoBuilder\Config\MBConfig; return static function (MBConfig $config) { - $config->packageDirectories(array( + $config->packageDirectories([ __DIR__.'/src', - )); - - $config->packageAliasFormat('2.x-dev'); - - $config->workers(array( - // 'Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker', - // 'Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker', - // 'Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker', - // 'Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker', - // 'Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker', - // 'Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker', - )); + ]); }; diff --git a/package-lock.json b/package-lock.json index da7d5823..dd9a9063 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,283 +1,2028 @@ { - "name": "php-flasher", + "name": "@flasher/php-flasher", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { + "name": "@flasher/php-flasher", + "version": "2.0.0", + "license": "MIT", + "workspaces": [ + "src/Prime/Resources", + "src/Noty/Prime/Resources", + "src/Notyf/Prime/Resources", + "src/SweetAlert/Prime/Resources", + "src/Toastr/Prime/Resources" + ], "devDependencies": { - "commitizen": "^4.3.0", - "cz-conventional-changelog": "^3.3.0" + "@antfu/eslint-config": "2.12.2", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.24.4", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-eslint": "^9.0.5", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", + "@types/node": "^20.12.6", + "@typescript-eslint/eslint-plugin": "7.5.0", + "@typescript-eslint/parser": "^7.6.0", + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cross-env": "7.0.3", + "cssnano": "^6.1.2", + "eslint": "^8.57.0", + "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-babel": "5.3.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "postcss-discard-comments": "^6.0.2", + "punycode": "2.3.1", + "rollup": "^4.14.1", + "rollup-plugin-cleanup": "^3.2.1", + "rollup-plugin-clear": "^2.0.7", + "rollup-plugin-copy": "3.5.0", + "rollup-plugin-filesize": "^10.0.0", + "rollup-plugin-postcss": "^4.0.2", + "sass": "^1.74.1", + "ts-node": "^10.9.2", + "tslib": "^2.6.2", + "typescript": "^5.4.4" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/eslint-config": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-2.12.2.tgz", + "integrity": "sha512-PfxkKKyFaXGyn9Z4OmuEUgrwM0oOAOjoP50SLNJ7EEE044O4WrblLre2HGROoc/y+Ljdu0E1ZEnBmR9d2UmhYA==", + "dev": true, + "dependencies": { + "@antfu/install-pkg": "^0.3.2", + "@clack/prompts": "^0.7.0", + "@stylistic/eslint-plugin": "^1.7.0", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@typescript-eslint/parser": "^7.5.0", + "eslint-config-flat-gitignore": "^0.1.5", + "eslint-flat-config-utils": "^0.2.1", + "eslint-merge-processors": "^0.1.0", + "eslint-plugin-antfu": "^2.1.2", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-import-x": "^0.5.0", + "eslint-plugin-jsdoc": "^48.2.3", + "eslint-plugin-jsonc": "^2.15.0", + "eslint-plugin-markdown": "^4.0.1", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-perfectionist": "^2.8.0", + "eslint-plugin-toml": "^0.11.0", + "eslint-plugin-unicorn": "^52.0.0", + "eslint-plugin-unused-imports": "^3.1.0", + "eslint-plugin-vitest": "^0.4.1", + "eslint-plugin-vue": "^9.24.0", + "eslint-plugin-yml": "^1.14.0", + "eslint-processor-vue-blocks": "^0.1.1", + "globals": "^15.0.0", + "jsonc-eslint-parser": "^2.4.0", + "local-pkg": "^0.5.0", + "parse-gitignore": "^2.0.0", + "picocolors": "^1.0.0", + "toml-eslint-parser": "^0.9.3", + "vue-eslint-parser": "^9.4.2", + "yaml-eslint-parser": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "eslint-config": "bin/index.js" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@unocss/eslint-plugin": ">=0.50.0", + "astro-eslint-parser": "^0.16.3", + "eslint": ">=8.40.0", + "eslint-plugin-astro": "^0.31.4", + "eslint-plugin-format": ">=0.1.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.4", + "eslint-plugin-svelte": ">=2.35.1", + "prettier-plugin-astro": "^0.13.0", + "prettier-plugin-slidev": "^1.0.5", + "svelte-eslint-parser": "^0.33.1" + }, + "peerDependenciesMeta": { + "@unocss/eslint-plugin": { + "optional": true + }, + "astro-eslint-parser": { + "optional": true + }, + "eslint-plugin-astro": { + "optional": true + }, + "eslint-plugin-format": { + "optional": true + }, + "eslint-plugin-react": { + "optional": true + }, + "eslint-plugin-react-hooks": { + "optional": true + }, + "eslint-plugin-react-refresh": { + "optional": true + }, + "eslint-plugin-svelte": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-slidev": { + "optional": true + }, + "svelte-eslint-parser": { + "optional": true + } + } + }, + "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-unused-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz", + "integrity": "sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==", + "dev": true, + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "6 - 7", + "eslint": "8" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, + "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-vue": { + "version": "9.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.24.0.tgz", + "integrity": "sha512-9SkJMvF8NGMT9aQCwFc5rj8Wo1XWSMSHk36i7ZwdI614BU7sIOR28ZjuFPKp8YGymZN12BSEbiSwa7qikp+PBw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.0", + "vue-eslint-parser": "^9.4.2", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/eslint-plugin-vue/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@antfu/eslint-config/node_modules/eslint-processor-vue-blocks": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-processor-vue-blocks/-/eslint-processor-vue-blocks-0.1.1.tgz", + "integrity": "sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/compiler-sfc": "^3.3.0", + "eslint": "^8.50.0" + } + }, + "node_modules/@antfu/eslint-config/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@antfu/eslint-config/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@antfu/eslint-config/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@antfu/eslint-config/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@antfu/install-pkg": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.3.2.tgz", + "integrity": "sha512-FFYqME8+UHlPnRlX/vn+8cTD4Wo/nG/lzRxpABs3XANBmdJdNImVz3QvjNAE/W3PSCNbG387FOz8o5WelnWOlg==", + "dev": true, + "dependencies": { + "execa": "^8.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dev": true, - "optional": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/compat-data": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", + "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", + "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.4", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.4", + "@babel/parser": "^7.24.4", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", + "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz", + "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "optional": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", + "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dev": true, - "optional": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@commitlint/config-validator": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.0.tgz", - "integrity": "sha512-Sa/+8KNpDXz4zT4bVbz2fpFjvgkPO6u2V2fP4TKgt6FjmOw2z3eEX859vtfeaTav/ukBw0/0jr+5ZTZp9zCBhA==", + "node_modules/@babel/parser": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "dev": true, - "optional": true, - "dependencies": { - "@commitlint/types": "^17.4.0", - "ajv": "^8.11.0" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=v14" + "node": ">=6.0.0" } }, - "node_modules/@commitlint/execute-rule": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", - "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz", + "integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==", "dev": true, - "optional": true, - "engines": { - "node": ">=v14" - } - }, - "node_modules/@commitlint/load": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.4.2.tgz", - "integrity": "sha512-Si++F85rJ9t4hw6JcOw1i2h0fdpdFQt0YKwjuK4bk9KhFjyFkRxvR3SB2dPaMs+EwWlDrDBGL+ygip1QD6gmPw==", - "dev": true, - "optional": true, "dependencies": { - "@commitlint/config-validator": "^17.4.0", - "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.4.0", - "@commitlint/types": "^17.4.0", - "@types/node": "*", - "chalk": "^4.1.0", - "cosmiconfig": "^8.0.0", - "cosmiconfig-typescript-loader": "^4.0.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0", - "resolve-from": "^5.0.0", - "ts-node": "^10.8.1", - "typescript": "^4.6.4" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { - "node": ">=v14" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@commitlint/load/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", "dev": true, - "optional": true, "dependencies": { - "color-convert": "^2.0.1" + "@babel/helper-plugin-utils": "^7.24.0" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", + "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz", + "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", + "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.4", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz", + "integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.4", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.1", + "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.1", + "@babel/plugin-transform-async-generator-functions": "^7.24.3", + "@babel/plugin-transform-async-to-generator": "^7.24.1", + "@babel/plugin-transform-block-scoped-functions": "^7.24.1", + "@babel/plugin-transform-block-scoping": "^7.24.4", + "@babel/plugin-transform-class-properties": "^7.24.1", + "@babel/plugin-transform-class-static-block": "^7.24.4", + "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-computed-properties": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-dotall-regex": "^7.24.1", + "@babel/plugin-transform-duplicate-keys": "^7.24.1", + "@babel/plugin-transform-dynamic-import": "^7.24.1", + "@babel/plugin-transform-exponentiation-operator": "^7.24.1", + "@babel/plugin-transform-export-namespace-from": "^7.24.1", + "@babel/plugin-transform-for-of": "^7.24.1", + "@babel/plugin-transform-function-name": "^7.24.1", + "@babel/plugin-transform-json-strings": "^7.24.1", + "@babel/plugin-transform-literals": "^7.24.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", + "@babel/plugin-transform-member-expression-literals": "^7.24.1", + "@babel/plugin-transform-modules-amd": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-modules-systemjs": "^7.24.1", + "@babel/plugin-transform-modules-umd": "^7.24.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.24.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", + "@babel/plugin-transform-numeric-separator": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-super": "^7.24.1", + "@babel/plugin-transform-optional-catch-binding": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.1", + "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-private-methods": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-property-literals": "^7.24.1", + "@babel/plugin-transform-regenerator": "^7.24.1", + "@babel/plugin-transform-reserved-words": "^7.24.1", + "@babel/plugin-transform-shorthand-properties": "^7.24.1", + "@babel/plugin-transform-spread": "^7.24.1", + "@babel/plugin-transform-sticky-regex": "^7.24.1", + "@babel/plugin-transform-template-literals": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-unicode-escapes": "^7.24.1", + "@babel/plugin-transform-unicode-property-regex": "^7.24.1", + "@babel/plugin-transform-unicode-regex": "^7.24.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@clack/core": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz", + "integrity": "sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.7.0.tgz", + "integrity": "sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==", + "bundleDependencies": [ + "is-unicode-supported" + ], + "dev": true, + "dependencies": { + "@clack/core": "^0.3.3", + "is-unicode-supported": "*", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts/node_modules/is-unicode-supported": { + "version": "1.3.0", + "extraneous": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@commitlint/load/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@commitlint/load/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@commitlint/load/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "node_modules/@commitlint/load/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@commitlint/load/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@commitlint/resolve-extends": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.0.tgz", - "integrity": "sha512-3JsmwkrCzoK8sO22AzLBvNEvC1Pmdn/65RKXzEtQMy6oYMl0Snrq97a5bQQEFETF0VsvbtUuKttLqqgn99OXRQ==", - "dev": true, - "optional": true, - "dependencies": { - "@commitlint/config-validator": "^17.4.0", - "@commitlint/types": "^17.4.0", - "import-fresh": "^3.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" - }, - "engines": { - "node": ">=v14" - } - }, - "node_modules/@commitlint/types": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.0.tgz", - "integrity": "sha512-2NjAnq5IcxY9kXtUeO2Ac0aPpvkuOmwbH/BxIm36XXK5LtWFObWJWjXOA+kcaABMrthjWu6la+FUpyYFMHRvbA==", - "dev": true, - "optional": true, - "dependencies": { - "chalk": "^4.1.0" - }, - "engines": { - "node": ">=v14" - } - }, - "node_modules/@commitlint/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@commitlint/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@commitlint/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@commitlint/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "node_modules/@commitlint/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@commitlint/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@cspotcode/source-map-support": { @@ -285,7 +2030,6 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "optional": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -293,75 +2037,2349 @@ "node": ">=12" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true, - "optional": true - }, - "node_modules/@jridgewell/trace-mapping": { + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "optional": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "node_modules/@es-joy/jsdoccomment": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz", + "integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==", "dev": true, - "optional": true + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@flasher/flasher": { + "resolved": "src/Prime/Resources", + "link": true + }, + "node_modules/@flasher/flasher-noty": { + "resolved": "src/Noty/Prime/Resources", + "link": true + }, + "node_modules/@flasher/flasher-notyf": { + "resolved": "src/Notyf/Prime/Resources", + "link": true + }, + "node_modules/@flasher/flasher-sweetalert": { + "resolved": "src/SweetAlert/Prime/Resources", + "link": true + }, + "node_modules/@flasher/flasher-toastr": { + "resolved": "src/Toastr/Prime/Resources", + "link": true + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/fs/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@npmcli/git": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@npmcli/git/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", + "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", + "dev": true, + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", + "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", + "dev": true, + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", + "integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@rollup/pluginutils": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "25.0.7", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", + "integrity": "sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "commondir": "^1.0.1", + "estree-walker": "^2.0.2", + "glob": "^8.0.3", + "is-reference": "1.2.1", + "magic-string": "^0.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.68.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-eslint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-eslint/-/plugin-eslint-9.0.5.tgz", + "integrity": "sha512-C4nh0sSeJuxVW5u5tDX+dCMjKcNfHm4hS+zeUVh1si7gttnhgGbrmPkUxIX7iZgYABwdEh/ewyMbZB+WXjSJdA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "eslint": "^8.24.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-typescript": { + "version": "11.1.6", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", + "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", + "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", + "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", + "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", + "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", + "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", + "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", + "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", + "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "cpu": [ + "ppc64le" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", + "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", + "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", + "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", + "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", + "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", + "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", + "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sigstore/bundle": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz", + "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", + "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz", + "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "make-fetch-happen": "^11.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/@sigstore/sign/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@sigstore/tuf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz", + "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.0", + "tuf-js": "^1.1.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.7.0.tgz", + "integrity": "sha512-ThMUjGIi/jeWYNvOdjZkoLw1EOVs0tEuKXDgWvTn8uWaEz55HuPlajKxjKLpv19C+qRDbKczJfzUODfCdME53A==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@stylistic/eslint-plugin-jsx": "1.7.0", + "@stylistic/eslint-plugin-plus": "1.7.0", + "@stylistic/eslint-plugin-ts": "1.7.0", + "@types/eslint": "^8.56.2" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.7.0.tgz", + "integrity": "sha512-PN6On/+or63FGnhhMKSQfYcWutRlzOiYlVdLM6yN7lquoBTqUJHYnl4TA4MHwiAt46X5gRxDr1+xPZ1lOLcL+Q==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.2", + "acorn": "^8.11.3", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-jsx": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.7.0.tgz", + "integrity": "sha512-BACdBwXakQvjYIST5N2WWhRbvhRsIxa/F59BiZol+0IH4FSmDXhie7v/yaxDIIA9CbfElzOmIA5nWNYTVXcnwQ==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "^1.7.0", + "@types/eslint": "^8.56.2", + "estraverse": "^5.3.0", + "picomatch": "^4.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-jsx/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@stylistic/eslint-plugin-plus": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.7.0.tgz", + "integrity": "sha512-AabDw8sXsc70Ydx3qnbeTlRHZnIwY6UKEenBPURPhY3bfYWX+/pDpZH40HkOu94v8D0DUrocPkeeEUxl4e0JDg==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@stylistic/eslint-plugin-plus/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.7.0.tgz", + "integrity": "sha512-QsHv98mmW1xaucVYQTyLDgEpybPJ/6jPPxVBrIchntWWwj74xCWKUiw79hu+TpYj/Pbhd9rkqJYLNq3pQGYuyA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.7.0", + "@types/eslint": "^8.56.2", + "@typescript-eslint/utils": "^6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@stylistic/eslint-plugin-ts/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@swc/core": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.11.tgz", + "integrity": "sha512-WKEakMZxkVwRdgMN4AMJ9K5nysY8g8npgQPczmjBeNK5In7QEAZAJwnyccrWwJZU0XjVeHn2uj+XbOKdDW17rg==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "@swc/counter": "^0.1.2", + "@swc/types": "^0.1.5" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.4.11", + "@swc/core-darwin-x64": "1.4.11", + "@swc/core-linux-arm-gnueabihf": "1.4.11", + "@swc/core-linux-arm64-gnu": "1.4.11", + "@swc/core-linux-arm64-musl": "1.4.11", + "@swc/core-linux-x64-gnu": "1.4.11", + "@swc/core-linux-x64-musl": "1.4.11", + "@swc/core-win32-arm64-msvc": "1.4.11", + "@swc/core-win32-ia32-msvc": "1.4.11", + "@swc/core-win32-x64-msvc": "1.4.11" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.11.tgz", + "integrity": "sha512-C1j1Qp/IHSelVWdEnT7f0iONWxQz6FAqzjCF2iaL+0vFg4V5f2nlgrueY8vj5pNNzSGhrAlxsMxEIp4dj1MXkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.11.tgz", + "integrity": "sha512-0TTy3Ni8ncgaMCchSQ7FK8ZXQLlamy0FXmGWbR58c+pVZWYZltYPTmheJUvVcR0H2+gPAymRKyfC0iLszDALjg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.11.tgz", + "integrity": "sha512-XJLB71uw0rog4DjYAPxFGAuGCBQpgJDlPZZK6MTmZOvI/1t0+DelJ24IjHIxk500YYM26Yv47xPabqFPD7I2zQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.11.tgz", + "integrity": "sha512-vYQwzJvm/iu052d5Iw27UFALIN5xSrGkPZXxLNMHPySVko2QMNNBv35HLatkEQHbQ3X+VKSW9J9SkdtAvAVRAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.11.tgz", + "integrity": "sha512-eV+KduiRYUFjPsvbZuJ9aknQH9Tj0U2/G9oIZSzLx/18WsYi+upzHbgxmIIHJ2VJgfd7nN40RI/hMtxNsUzR/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.11.tgz", + "integrity": "sha512-WA1iGXZ2HpqM1OR9VCQZJ8sQ1KP2or9O4bO8vWZo6HZJIeoQSo7aa9waaCLRpkZvkng1ct/TF/l6ymqSNFXIzQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.11.tgz", + "integrity": "sha512-UkVJToKf0owwQYRnGvjHAeYVDfeimCEcx0VQSbJoN7Iy0ckRZi7YPlmWJU31xtKvikE2bQWCOVe0qbSDqqcWXA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.11.tgz", + "integrity": "sha512-35khwkyly7lF5NDSyvIrukBMzxPorgc5iTSDfVO/LvnmN5+fm4lTlrDr4tUfTdOhv3Emy7CsKlsNAeFRJ+Pm+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.11.tgz", + "integrity": "sha512-Wx8/6f0ufgQF2pbVPsJ2dAmFLwIOW+xBE5fxnb7VnEbGkTgP1qMDWiiAtD9rtvDSuODG3i1AEmAak/2HAc6i6A==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.11.tgz", + "integrity": "sha512-0xRFW6K9UZQH2NVC/0pVB0GJXS45lY24f+6XaPBF1YnMHd8A8GoHl7ugyM5yNUTe2AKhSgk5fJV00EJt/XBtdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@swc/types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.6.tgz", + "integrity": "sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "optional": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "optional": true + "dev": true }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@tufjs/canonical-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", + "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", "dev": true, - "optional": true + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.7", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.7.tgz", + "integrity": "sha512-SjDvI/x3zsZnOkYZ3lCt9lOZWZLB2jIlNKz+LBgCtDurK0JZcwucxYHn1w2BJkD34dgX9Tjnak0txtq4WTggEA==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/jquery": { + "version": "3.5.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.29.tgz", + "integrity": "sha512-oXQQC9X9MOPRrMhPHHOsXqeQDnWeCDT3PelUIg/Oy8FAbzSZtFHRjc7IpbfFVmpLtJ+UOoywpRsuO5Jxjybyeg==", + "dev": true, + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true }, "node_modules/@types/node": { - "version": "18.11.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "version": "20.12.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", + "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", "dev": true, - "optional": true + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", + "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "dev": true + }, + "node_modules/@types/toastr": { + "version": "2.1.43", + "resolved": "https://registry.npmjs.org/@types/toastr/-/toastr-2.1.43.tgz", + "integrity": "sha512-sLC2fr2OXeE1iyhUixpQ64wQ2tA26awmLidn4tXTLBz4yP/VhtYUKHpmiIyDtztKkHjucdiTLH8F5uRRyhNi2Q==", + "dev": true, + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz", + "integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/type-utils": "7.5.0", + "@typescript-eslint/utils": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz", + "integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/utils": "7.5.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz", + "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz", + "integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.6.0", + "@typescript-eslint/types": "7.6.0", + "@typescript-eslint/typescript-estree": "7.6.0", + "@typescript-eslint/visitor-keys": "7.6.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz", + "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.6.0", + "@typescript-eslint/visitor-keys": "7.6.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz", + "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz", + "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.6.0", + "@typescript-eslint/visitor-keys": "7.6.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz", + "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.6.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz", + "integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz", + "integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz", + "integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz", + "integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.5.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.21", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "dev": true, + "peer": true, + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "dev": true, + "peer": true, + "dependencies": { + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "dev": true, + "peer": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "optional": true, "bin": { "acorn": "bin/acorn" }, @@ -369,26 +4387,70 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, - "optional": true, "engines": { "node": ">=0.4.0" } }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dev": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "optional": true, "dependencies": { "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { @@ -396,19 +4458,13 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dev": true, "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "string-width": "^4.1.0" } }, "node_modules/ansi-regex": { @@ -432,27 +4488,271 @@ "node": ">=4" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "optional": true + "dev": true }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "optional": true + "dev": true }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", + "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001599", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.1", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", + "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/balanced-match": { @@ -461,45 +4761,135 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", "dev": true, "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -514,37 +4904,190 @@ "node": ">=8" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "node_modules/brotli-size": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-4.0.0.tgz", + "integrity": "sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==", + "dev": true, + "dependencies": { + "duplexer": "0.1.1" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, { "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/builtins/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/cacache": { + "version": "17.1.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", + "integrity": "sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^7.0.3", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/callsites": { @@ -552,11 +5095,54 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "optional": true, "engines": { "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001600", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", + "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -571,28 +5157,139 @@ "node": ">=4" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "dependencies": { - "restore-cursor": "^3.1.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "engines": { "node": ">=8" } }, - "node_modules/cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true, "engines": { "node": ">=6" @@ -601,22 +5298,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">= 10" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" + "node": ">=12" } }, "node_modules/color-convert": { @@ -634,171 +5327,1179 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/commitizen": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.0.tgz", - "integrity": "sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==", + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, - "dependencies": { - "cachedir": "2.3.0", - "cz-conventional-changelog": "3.3.0", - "dedent": "0.7.0", - "detect-indent": "6.1.0", - "find-node-modules": "^2.1.2", - "find-root": "1.1.0", - "fs-extra": "9.1.0", - "glob": "7.2.3", - "inquirer": "8.2.5", - "is-utf8": "^0.2.1", - "lodash": "4.17.21", - "minimist": "1.2.7", - "strip-bom": "4.0.0", - "strip-json-comments": "3.1.1" - }, "bin": { - "commitizen": "bin/commitizen", - "cz": "bin/git-cz", - "git-cz": "bin/git-cz" - }, - "engines": { - "node": ">= 12" + "color-support": "bin.js" } }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true + }, + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/conventional-commit-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", - "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", - "dev": true - }, - "node_modules/cosmiconfig": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", - "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "node_modules/concat-with-sourcemaps": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", + "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", "dev": true, - "optional": true, "dependencies": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" + "source-map": "^0.6.1" } }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz", - "integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==", + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/core-js-compat": { + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "dev": true, - "optional": true, - "engines": { - "node": ">=12", - "npm": ">=6" + "dependencies": { + "browserslist": "^4.23.0" }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=7", - "ts-node": ">=10", - "typescript": ">=3" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true - }, - "node_modules/cz-conventional-changelog": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", - "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "commitizen": "^4.0.3", - "conventional-commit-types": "^3.0.0", - "lodash.map": "^4.5.1", - "longest": "^2.0.1", - "word-wrap": "^1.0.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@commitlint/load": ">6.1.1" - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, "dependencies": { - "clone": "^1.0.2" + "cross-spawn": "^7.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" } }, - "node_modules/detect-file": { + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "optional": true, "engines": { "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha512-sxNZ+ljy+RA1maXoUReeqBBpBC6RLKmg5ewzV+x+mSETmWNoKdZN6vcQjpFROemza23hGFskJtFNoUWUaQ+R4Q==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.719", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.719.tgz", + "integrity": "sha512-FbWy2Q2YgdFzkFUW/W5jBjE9dj+804+98E4Pup78JBPnbdb3pv6IneY2JCPKdeKLh3AOKHQeYf+KwLr7mxGh6Q==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "optional": true, "dependencies": { "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", + "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", + "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-compat-utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-compat-utils/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-compat-utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-config-airbnb-typescript": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", + "integrity": "sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + } + }, + "node_modules/eslint-config-airbnb-typescript/node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-flat-gitignore": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/eslint-config-flat-gitignore/-/eslint-config-flat-gitignore-0.1.5.tgz", + "integrity": "sha512-hEZLwuZjDBGDERA49c2q7vxc8sCGv8EdBp6PQYzGOMcHIgrfG9YOM6s/4jx24zhD+wnK9AI8mgN5RxSss5nClQ==", + "dev": true, + "dependencies": { + "find-up": "^7.0.0", + "parse-gitignore": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/eslint-config-flat-gitignore/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-flat-config-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/eslint-flat-config-utils/-/eslint-flat-config-utils-0.2.1.tgz", + "integrity": "sha512-SKnSr4YdPD7xxynNpaad/IlJYfeDmtWvZ0UEmHEA0+eTOcZFPt1075KO87LIWN30jXGCREG2qcCqdAnRoCiAWQ==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.7", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-merge-processors": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/eslint-merge-processors/-/eslint-merge-processors-0.1.0.tgz", + "integrity": "sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-antfu": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-2.1.2.tgz", + "integrity": "sha512-s7ZTOM3uq0iqpp6gF0UEotnvup7f2PHBUftCytLZX0+6C9j9KadKZQh6bVVngAyFgsmeD9+gcBopOYLClb2oDg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/eslint-plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz", + "integrity": "sha512-VsQEr6NH3dj664+EyxJwO4FCYm/00JhYb3Sk3ft8o+fpKuIfQ9TaW6uVUfvwMXHcf/lsnRIoyFPsLMyiWCSL/g==", + "dev": true, + "dependencies": { + "eslint-rule-composer": "^0.3.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": ">=4.0.0" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz", + "integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.6.0", + "eslint-compat-utils": "^0.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-eslint-comments": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", + "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + }, + "engines": { + "node": ">=6.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", @@ -807,46 +6508,300 @@ "node": ">=0.8.0" } }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "homedir-polyfill": "^1.0.1" + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import-x": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-0.5.0.tgz", + "integrity": "sha512-C7R8Z4IzxmsoOPMtSzwuOBW5FH6iRlxHR6iTks+MzVlrk3r3TUxokkWTx3ypdj9nGOEP+CG/5e6ebZzHbxgbbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^7.4.0", + "debug": "^4.3.4", + "doctrine": "^3.0.0", + "eslint-import-resolver-node": "^0.3.9", + "get-tsconfig": "^4.7.3", + "is-glob": "^4.0.3", + "minimatch": "^9.0.3", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "eslint": "^8.56.0 || ^9.0.0-0" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/utils": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz", + "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=4" + "node": "*" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "optional": true - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "node_modules/eslint-plugin-jsdoc": { + "version": "48.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.3.tgz", + "integrity": "sha512-r9DMAmFs66VNvNqRLLjHejdnJtILrt3xGi+Qx0op0oRfFGVpOR1Hb3BC++MacseHx93d8SKYPhyrC9BS7Os2QA==", "dev": true, "dependencies": { - "escape-string-regexp": "^1.0.5" + "@es-joy/jsdoccomment": "~0.42.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "is-builtin-module": "^3.2.1", + "semver": "^7.6.0", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-plugin-jsonc": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.15.0.tgz", + "integrity": "sha512-wAphMVgTQPAKAYV8d/QEkEYDg8uer9nMQ85N17IUiJcAWLxJs83/Exe59dEH9yKUpvpLf46H+wR7/U7lZ3/NpQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "eslint-compat-utils": "^0.5.0", + "espree": "^9.6.1", + "graphemer": "^1.4.0", + "jsonc-eslint-parser": "^2.0.4", + "natural-compare": "^1.4.0", + "synckit": "^0.6.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-markdown": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-4.0.1.tgz", + "integrity": "sha512-5/MnGvYU0i8MbHH5cg8S+Vl3DL+bqRNYshk1xUO86DilNBaxtTkhH+5FD0/yO03AmlI6+lfNFdk2yOw72EPzpA==", + "dev": true, + "dependencies": { + "mdast-util-from-markdown": "^0.8.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-n": { + "version": "16.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz", + "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "builtins": "^5.0.1", + "eslint-plugin-es-x": "^7.5.0", + "get-tsconfig": "^4.7.0", + "globals": "^13.24.0", + "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", + "is-core-module": "^2.12.1", + "minimatch": "^3.1.2", + "resolve": "^1.22.2", + "semver": "^7.5.3" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" @@ -855,6 +6810,824 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-plugin-n/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-n/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-plugin-no-only-tests": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz", + "integrity": "sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==", + "dev": true, + "engines": { + "node": ">=5.0.0" + } + }, + "node_modules/eslint-plugin-perfectionist": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.8.0.tgz", + "integrity": "sha512-XBjQ4ctU1rOzQ4bFJoUowe8XdsIIz42JqNrouFlae1TO78HjoyYBaRP8+gAHDDQCSdHY10pbChyzlJeBA6D51w==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^6.13.0", + "minimatch": "^9.0.3", + "natural-compare-lite": "^1.4.0" + }, + "peerDependencies": { + "astro-eslint-parser": "^0.16.0", + "eslint": ">=8.0.0", + "svelte": ">=3.0.0", + "svelte-eslint-parser": "^0.33.0", + "vue-eslint-parser": ">=9.0.0" + }, + "peerDependenciesMeta": { + "astro-eslint-parser": { + "optional": true + }, + "svelte": { + "optional": true + }, + "svelte-eslint-parser": { + "optional": true + }, + "vue-eslint-parser": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-perfectionist/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-prettier/node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/eslint-plugin-toml": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.11.0.tgz", + "integrity": "sha512-sau+YvPU4fWTjB+qtBt3n8WS87aoDCs+BVbSUAemGaIsRNbvR9uEk+Tt892iLHTGvp/DPWYoCX4/8DoyAbB+sQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-compat-utils": "^0.5.0", + "lodash": "^4.17.19", + "toml-eslint-parser": "^0.9.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "52.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-52.0.0.tgz", + "integrity": "sha512-1Yzm7/m+0R4djH0tjDjfVei/ju2w3AzUGjG6q8JnuNIL5xIwsflyCooW5sfBvQp2pMYQFSWWCFONsjCax1EHng==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "@eslint-community/eslint-utils": "^4.4.0", + "@eslint/eslintrc": "^2.1.4", + "ci-info": "^4.0.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.34.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.5.4", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=8.56.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-plugin-vitest": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.4.1.tgz", + "integrity": "sha512-+PnZ2u/BS+f5FiuHXz4zKsHPcMKHie+K+1Uvu/x91ovkCMEOJqEI8E9Tw1Wzx2QRz4MHOBHYf1ypO8N1K0aNAA==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^7.4.0" + }, + "engines": { + "node": "^18.0.0 || >= 20.0.0" + }, + "peerDependencies": { + "eslint": ">=8.0.0", + "vitest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vitest/node_modules/@typescript-eslint/utils": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz", + "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/eslint-plugin-vitest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-vitest/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-vitest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/eslint-plugin-yml": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz", + "integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.2", + "eslint-compat-utils": "^0.5.0", + "lodash": "^4.17.21", + "natural-compare": "^1.4.0", + "yaml-eslint-parser": "^1.2.1" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-rule-composer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filesize": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz", + "integrity": "sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -867,50 +7640,113 @@ "node": ">=8" } }, - "node_modules/find-node-modules": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", - "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "findup-sync": "^4.0.0", - "merge": "^2.1.1" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true - }, - "node_modules/findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/fs.realpath": { @@ -919,75 +7755,312 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/generic-names": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-4.0.0.tgz", + "integrity": "sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==", + "dev": true, + "dependencies": { + "loader-utils": "^3.2.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "optional": true, "dependencies": { - "ini": "^1.3.4" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "node_modules/globals": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.0.0.tgz", + "integrity": "sha512-m/C/yR4mjO6pXDTm9/R/SpYTAIyaUB4EOzcaaMEl7mds7Mshct9GfejiJNQGjHHbdMPey13Kpu4TMbYi9ex1pw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" + "define-properties": "^1.1.3" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gzip-size/node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -997,56 +8070,207 @@ "node": ">=4" } }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "parse-passwd": "^1.0.0" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "dependencies": { + "ms": "^2.0.0" } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==", + "dev": true + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz", + "integrity": "sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/immutable": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", + "dev": true + }, + "node_modules/import-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz", + "integrity": "sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==", + "dev": true, + "dependencies": { + "import-from": "^3.0.0" + }, + "engines": { + "node": ">=8" + } }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "optional": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1058,16 +8282,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/import-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", "dev": true, - "optional": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, + "node_modules/import-from/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1084,114 +8343,197 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/inquirer": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", - "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": ">=12.0.0" + "node": ">= 0.4" } }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" }, "engines": { - "node": ">=8" + "node": ">= 12" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "optional": true + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/is-extglob": { "version": "2.1.1", @@ -1223,13 +8565,38 @@ "node": ">=0.10.0" } }, - "node_modules/is-interactive": { + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-number": { @@ -1241,52 +8608,218 @@ "node": ">=0.12.0" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "peer": true + }, + "node_modules/js-cleanup": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", + "integrity": "sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==", + "dev": true, + "dependencies": { + "magic-string": "^0.25.7", + "perf-regexes": "^1.0.1", + "skip-regex": "^1.0.2" + }, + "engines": { + "node": "^10.14.2 || >=12.0.0" + } + }, + "node_modules/js-cleanup/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "optional": true + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "optional": true, "dependencies": { "argparse": "^2.0.1" }, @@ -1294,87 +8827,216 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "optional": true + "dev": true }, "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "optional": true + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", + "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "optional": true - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, - "optional": true + "engines": { + "node": ">= 12.13.0" + } }, - "node_modules/lodash.map": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "optional": true - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true, - "optional": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true, - "optional": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", "dev": true, "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" }, "engines": { "node": ">=10" @@ -1383,98 +9045,308 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "yallist": "^3.0.2" } }, - "node_modules/longest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", - "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" } }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "optional": true - }, - "node_modules/merge": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", - "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", "dev": true }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-fetch-happen/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -1489,15 +9361,411 @@ } }, "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mlly": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", + "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", @@ -1509,20 +9777,538 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "node_modules/node-gyp/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/noty": { + "version": "3.2.0-beta-deprecated", + "resolved": "https://registry.npmjs.org/noty/-/noty-3.2.0-beta-deprecated.tgz", + "integrity": "sha512-ntRbHuQ9SnnnVFZm/oq5L1DBCaHQUvsU24AwZH3PGjAWx2YqR/IhOadMk11vmJovYiQo00oqTj6Hp+D6PGtmLA==", + "deprecated": "no longer supported", + "peer": true + }, + "node_modules/notyf": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/notyf/-/notyf-3.10.0.tgz", + "integrity": "sha512-Mtnp+0qiZxgrH+TzVlzhWyZceHdAZ/UWK0/ju9U0HQeDpap1mZ8cC7H5wSI5mwgni6yeAjaxsTw0sbMK+aSuHw==", + "peer": true + }, + "node_modules/npm-bundled": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz", + "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-install-checks/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-install-checks/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm-package-arg/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-arg/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-arg/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-packlist": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz", + "integrity": "sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-pick-manifest/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-pick-manifest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dev": true, + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm-registry-fetch/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/once": { "version": "1.4.0", @@ -1534,35 +10320,53 @@ } }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" @@ -1571,7 +10375,1727 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/ansi-styles": { + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pacote": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", + "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", + "dev": true, + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-gitignore": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-gitignore/-/parse-gitignore-2.0.0.tgz", + "integrity": "sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/perf-regexes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", + "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", + "dev": true, + "engines": { + "node": ">=6.14" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "dev": true, + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.3.1.tgz", + "integrity": "sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==", + "dev": true, + "dependencies": { + "generic-names": "^4.0.0", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", + "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", + "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "dev": true, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "dev": true, + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "peer": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise.series": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/promise.series/-/promise.series-0.2.0.tgz", + "integrity": "sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-package-json": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", + "dev": true, + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/glob": { + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/read-package-json/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/read-package-json/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/read-package-json/node_modules/normalize-package-data": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/read-package-json/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/read-package-json/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/regexpu-core/node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/rollup": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", + "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.14.1", + "@rollup/rollup-android-arm64": "4.14.1", + "@rollup/rollup-darwin-arm64": "4.14.1", + "@rollup/rollup-darwin-x64": "4.14.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", + "@rollup/rollup-linux-arm64-gnu": "4.14.1", + "@rollup/rollup-linux-arm64-musl": "4.14.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", + "@rollup/rollup-linux-riscv64-gnu": "4.14.1", + "@rollup/rollup-linux-s390x-gnu": "4.14.1", + "@rollup/rollup-linux-x64-gnu": "4.14.1", + "@rollup/rollup-linux-x64-musl": "4.14.1", + "@rollup/rollup-win32-arm64-msvc": "4.14.1", + "@rollup/rollup-win32-ia32-msvc": "4.14.1", + "@rollup/rollup-win32-x64-msvc": "4.14.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-cleanup": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.2.1.tgz", + "integrity": "sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==", + "dev": true, + "dependencies": { + "js-cleanup": "^1.2.0", + "rollup-pluginutils": "^2.8.2" + }, + "engines": { + "node": "^10.14.2 || >=12.0.0" + }, + "peerDependencies": { + "rollup": ">=2.0" + } + }, + "node_modules/rollup-plugin-clear": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/rollup-plugin-clear/-/rollup-plugin-clear-2.0.7.tgz", + "integrity": "sha512-Hg8NC3JcJBO1ofgyQC0IACpyKn/yhHPGZ3C7R3ubNGWUXy9JXHQrewk4J4hVcZznw6SOKayLsaNae596Rwt8Vg==", + "dev": true, + "dependencies": { + "rimraf": "^2.6.2" + } + }, + "node_modules/rollup-plugin-clear/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rollup-plugin-clear/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup-plugin-clear/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/rollup-plugin-clear/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup-plugin-copy": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz", + "integrity": "sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==", + "dev": true, + "dependencies": { + "@types/fs-extra": "^8.0.1", + "colorette": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "10.0.1", + "is-plain-object": "^3.0.0" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/rollup-plugin-copy/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rollup-plugin-copy/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup-plugin-copy/node_modules/globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-copy/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/rollup-plugin-filesize": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-filesize/-/rollup-plugin-filesize-10.0.0.tgz", + "integrity": "sha512-JAYYhzCcmGjmCzo3LEHSDE3RAPHKIeBdpqRhiyZSv5o/3wFhktUOzYAWg/uUKyEu5dEaVaql6UOmaqHx1qKrZA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.8", + "boxen": "^5.0.0", + "brotli-size": "4.0.0", + "colors": "1.4.0", + "filesize": "^6.1.0", + "gzip-size": "^6.0.0", + "pacote": "^15.1.1", + "terser": "^5.6.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/rollup-plugin-postcss": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-postcss/-/rollup-plugin-postcss-4.0.2.tgz", + "integrity": "sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "concat-with-sourcemaps": "^1.1.0", + "cssnano": "^5.0.1", + "import-cwd": "^3.0.0", + "p-queue": "^6.6.2", + "pify": "^5.0.0", + "postcss-load-config": "^3.0.0", + "postcss-modules": "^4.0.0", + "promise.series": "^0.2.0", + "resolve": "^1.19.0", + "rollup-pluginutils": "^2.8.2", + "safe-identifier": "^0.4.2", + "style-inject": "^0.3.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "8.x" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -1586,7 +12110,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ora/node_modules/chalk": { + "node_modules/rollup-plugin-postcss/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -1602,7 +12126,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ora/node_modules/color-convert": { + "node_modules/rollup-plugin-postcss/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -1614,13 +12138,194 @@ "node": ">=7.0.0" } }, - "node_modules/ora/node_modules/color-name": { + "node_modules/rollup-plugin-postcss/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/ora/node_modules/has-flag": { + "node_modules/rollup-plugin-postcss/node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -1629,7 +12334,443 @@ "node": ">=8" } }, - "node_modules/ora/node_modules/supports-color": { + "node_modules/rollup-plugin-postcss/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dev": true, + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dev": true, + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dev": true, + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/rollup-plugin-postcss/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", @@ -1641,186 +12782,81 @@ "node": ">=8" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "node_modules/rollup-plugin-postcss/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "optional": true, "dependencies": { - "callsites": "^3.0.0" + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" }, "engines": { - "node": ">=6" + "node": ">=10.13.0" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, - "optional": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "estree-walker": "^0.6.1" + } + }, + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" }, "engines": { - "node": ">=8" + "node": ">=0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-global": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", - "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", - "dev": true, - "optional": true, - "dependencies": { - "global-dirs": "^0.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safe-buffer": { @@ -1843,16 +12879,417 @@ } ] }, + "node_modules/safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", + "dev": true + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "node_modules/sass": { + "version": "1.74.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.74.1.tgz", + "integrity": "sha512-w0Z9p/rWZWelb88ISOLyvqTWGmtmu2QJICqDBGyNnfG4OUnPX9BBjjYIXUpXCMOOg5MQWNpqzt876la1fsTvUA==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz", + "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "@sigstore/sign": "^1.0.0", + "@sigstore/tuf": "^1.0.3", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/sigstore/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/sigstore/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/skip-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", + "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", + "dev": true, + "engines": { + "node": ">=4.2" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/smob": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", + "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", + "dev": true + }, + "node_modules/socks": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", + "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", + "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", "dev": true }, "node_modules/string_decoder": { @@ -1864,6 +13301,12 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==", + "dev": true + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1878,6 +13321,70 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1890,11 +13397,48 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, "engines": { "node": ">=8" } @@ -1911,6 +13455,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-inject": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz", + "integrity": "sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==", + "dev": true + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1923,22 +13489,158 @@ "node": ">=4" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/svgo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", + "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", "dev": true, "dependencies": { - "os-tmpdir": "~1.0.2" + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" }, "engines": { - "node": ">=0.6.0" + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/sweetalert2": { + "version": "11.10.7", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", + "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==", + "peer": true, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, + "node_modules/synckit": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.6.2.tgz", + "integrity": "sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/terser": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.30.0.tgz", + "integrity": "sha512-Y/SblUl5kEyEFzhMAQdsxVHh+utAxd4IuRNJzKywY/4uzSogh3G219jqbDDxYu4MXO9CzY3tSEqmZvW6AoEDJw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/to-regex-range": { @@ -1953,12 +13655,47 @@ "node": ">=8.0" } }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "node_modules/toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA==", + "peer": true, + "dependencies": { + "jquery": ">=1.12.0" + } + }, + "node_modules/toml-eslint-parser": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.9.3.tgz", + "integrity": "sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "optional": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -1997,45 +13734,371 @@ } } }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/tuf-js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", + "dev": true, + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" + } + }, + "node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", "dev": true, - "optional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "engines": { - "node": ">= 10.0.0" + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, "node_modules/uri-js": { @@ -2043,7 +14106,6 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "optional": true, "dependencies": { "punycode": "^2.1.0" } @@ -2058,37 +14120,166 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "optional": true + "dev": true }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "dependencies": { - "defaults": "^1.0.3" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vue-eslint-parser": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", + "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/vue-eslint-parser/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { - "which": "bin/which" + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/wrap-ansi": { @@ -2108,6 +14299,57 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2147,15 +14389,162 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-eslint-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz", + "integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.0.0", + "lodash": "^4.17.21", + "yaml": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/yaml-eslint-parser/node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "optional": true, "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "src/Noty/Prime/Resources": { + "name": "@flasher/flasher-noty", + "version": "2.0.0", + "license": "MIT", + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "noty": "^3.2.0-beta-deprecated" + } + }, + "src/Notyf/Prime/Resources": { + "name": "@flasher/flasher-notyf", + "version": "2.0.0", + "license": "MIT", + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "notyf": "^3.10.0" + } + }, + "src/Prime/Resources": { + "name": "@flasher/flasher", + "version": "2.0.0", + "license": "MIT", + "devDependencies": { + "csstype": "^3.1.3" + } + }, + "src/SweetAlert/Prime/Resources": { + "name": "@flasher/flasher-sweetalert", + "version": "2.0.0", + "license": "MIT", + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "sweetalert2": "^11.6.13" + } + }, + "src/Toastr/Prime/Resources": { + "name": "@flasher/flasher-toastr", + "version": "2.0.0", + "license": "MIT", + "devDependencies": { + "@types/toastr": "^2.1.43" + }, + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "toastr": "^2.1.4" + } } } } diff --git a/package.json b/package.json index 5792cf99..5ff9da50 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,57 @@ { - "devDependencies": { - "commitizen": "^4.3.0", - "cz-conventional-changelog": "^3.3.0" - }, + "name": "@flasher/php-flasher", + "type": "module", + "version": "2.0.0", + "license": "MIT", + "workspaces": [ + "src/Prime/Resources", + "src/Noty/Prime/Resources", + "src/Notyf/Prime/Resources", + "src/SweetAlert/Prime/Resources", + "src/Toastr/Prime/Resources" + ], "scripts": { - "commit": "cz" + "dev": "rollup -c", + "watch": "rollup -c -w", + "build": "cross-env NODE_ENV=production rollup -c", + "link": "npm link --workspaces", + "ncu": "ncu -u && npm run ncu --workspaces" + }, + "devDependencies": { + "@antfu/eslint-config": "2.12.2", + "@babel/core": "^7.24.4", + "@babel/preset-env": "^7.24.4", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-eslint": "^9.0.5", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^11.1.6", + "@types/node": "^20.12.6", + "@typescript-eslint/eslint-plugin": "7.5.0", + "@typescript-eslint/parser": "^7.6.0", + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cross-env": "7.0.3", + "cssnano": "^6.1.2", + "eslint": "^8.57.0", + "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-babel": "5.3.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.1.3", + "postcss-discard-comments": "^6.0.2", + "punycode": "2.3.1", + "rollup": "^4.14.1", + "rollup-plugin-cleanup": "^3.2.1", + "rollup-plugin-clear": "^2.0.7", + "rollup-plugin-copy": "3.5.0", + "rollup-plugin-filesize": "^10.0.0", + "rollup-plugin-postcss": "^4.0.2", + "sass": "^1.74.1", + "ts-node": "^10.9.2", + "tslib": "^2.6.2", + "typescript": "^5.4.4" } } diff --git a/packs/laravel-pack/.github/FUNDING.yml b/packs/laravel-pack/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/packs/laravel-pack/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/packs/laravel-pack/.github/workflows/auto_closer.yaml b/packs/laravel-pack/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/packs/laravel-pack/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/packs/laravel-pack/LICENSE b/packs/laravel-pack/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/packs/laravel-pack/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/packs/laravel-pack/README.md b/packs/laravel-pack/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/packs/laravel-pack/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/packs/laravel-pack/composer.json b/packs/laravel-pack/composer.json deleted file mode 100644 index f567b035..00000000 --- a/packs/laravel-pack/composer.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "php-flasher/laravel-pack", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "flasher-pack", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "require": { - "php-flasher/flasher-cli-laravel": "*", - "php-flasher/flasher-noty-laravel": "*", - "php-flasher/flasher-notyf-laravel": "*", - "php-flasher/flasher-pnotify-laravel": "*", - "php-flasher/flasher-sweetalert-laravel": "*", - "php-flasher/flasher-toastr-laravel": "*" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/packs/php-pack/.github/workflows/auto_closer.yaml b/packs/php-pack/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/packs/php-pack/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/packs/php-pack/LICENSE b/packs/php-pack/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/packs/php-pack/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/packs/php-pack/README.md b/packs/php-pack/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/packs/php-pack/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/packs/php-pack/composer.json b/packs/php-pack/composer.json deleted file mode 100644 index ee57e090..00000000 --- a/packs/php-pack/composer.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "php-flasher/php-pack", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "flasher-pack", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "require": { - "php-flasher/flasher-cli": "*", - "php-flasher/flasher-noty": "*", - "php-flasher/flasher-notyf": "*", - "php-flasher/flasher-pnotify": "*", - "php-flasher/flasher-sweetalert": "*", - "php-flasher/flasher-toastr": "*" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/packs/symfony-pack/.github/FUNDING.yml b/packs/symfony-pack/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/packs/symfony-pack/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/packs/symfony-pack/.github/workflows/auto_closer.yaml b/packs/symfony-pack/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/packs/symfony-pack/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/packs/symfony-pack/LICENSE b/packs/symfony-pack/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/packs/symfony-pack/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/packs/symfony-pack/README.md b/packs/symfony-pack/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/packs/symfony-pack/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/packs/symfony-pack/composer.json b/packs/symfony-pack/composer.json deleted file mode 100644 index 6c7e81e2..00000000 --- a/packs/symfony-pack/composer.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "php-flasher/symfony-pack", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "flasher-pack", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "require": { - "php-flasher/flasher-cli-symfony": "*", - "php-flasher/flasher-noty-symfony": "*", - "php-flasher/flasher-notyf-symfony": "*", - "php-flasher/flasher-pnotify-symfony": "*", - "php-flasher/flasher-sweetalert-symfony": "*", - "php-flasher/flasher-toastr-symfony": "*" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/phpstan.neon b/phpstan.neon deleted file mode 100644 index 0f5583c1..00000000 --- a/phpstan.neon +++ /dev/null @@ -1,9 +0,0 @@ -parameters: - level: 9 - paths: - - src - excludePaths: - - src/Symfony/Bridge/ - - src/Laravel/Middleware/HttpKernelFlasherMiddleware.php - - src/Laravel/Middleware/HttpKernelSessionMiddleware.php - - src/*/Symfony/Flasher*SymfonyBundle.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 00000000..c21df306 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,15 @@ +includes: + - extension.neon + - vendor/phpstan/phpstan-symfony/extension.neon + - vendor/phpstan/phpstan-symfony/rules.neon + - vendor/larastan/larastan/extension.neon + - vendor/phpstan/phpstan-mockery/extension.neon + +parameters: + level: 9 + + paths: + - src/ + - tests/ + + tmpDir: .cache/phpstan diff --git a/phpstorm/Laravel/.phpstorm.meta.php b/phpstorm/Laravel/.phpstorm.meta.php index fd2ce861..56e7904f 100644 --- a/phpstorm/Laravel/.phpstorm.meta.php +++ b/phpstorm/Laravel/.phpstorm.meta.php @@ -6,4 +6,8 @@ override(\Illuminate\Foundation\Application::make(0), map([ 'config' => \Illuminate\Contracts\Config\Repository::class, 'session' => \Illuminate\Session\SessionManager::class, 'view' => \Illuminate\View\Factory::class, + 'translator' => \Illuminate\Translation\Translator::class, + 'livewire' => \Livewire\LivewireManager::class, ])); + +expectedArguments(\Illuminate\Contracts\Config\Repository::get(), 0, 'flasher'); diff --git a/phpunit-laravel.xml b/phpunit-laravel.xml deleted file mode 100644 index b1501643..00000000 --- a/phpunit-laravel.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - tests/Prime - tests/Laravel - - - - - - src - - - diff --git a/phpunit-symfony.xml b/phpunit-symfony.xml deleted file mode 100644 index ca06a285..00000000 --- a/phpunit-symfony.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - tests/Prime - tests/Symfony - - - - - - src - - - diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index a01dbaa7..00000000 --- a/phpunit.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - tests - - - - - - src - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..e010477c --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + tests/Prime + tests/Noty/Prime + tests/Notyf/Prime + tests/SweetAlert/Prime + tests/Toastr/Prime + + + + tests/Laravel + tests/Noty/Laravel + tests/Notyf/Laravel + tests/SweetAlert/Laravel + tests/Toastr/Laravel + + + + tests/Symfony + tests/Noty/Symfony + tests/Notyf/Symfony + tests/SweetAlert/Symfony + tests/Toastr/Symfony + + + + + + + + src + + + diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..8465c664 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,8 @@ +prefer-workspace-packages: true + +packages: + - src/Prime/Resources + - src/Noty/Prime/Resources + - src/Notyf/Prime/Resources + - src/SweetAlert/Prime/Resources + - src/Toastr/Prime/Resources diff --git a/psalm.xml b/psalm.xml deleted file mode 100644 index 95224c95..00000000 --- a/psalm.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/rector.php b/rector.php new file mode 100644 index 00000000..6f006bac --- /dev/null +++ b/rector.php @@ -0,0 +1,27 @@ +withPaths([ + __DIR__.'/src/', + __DIR__.'/tests/', + __DIR__.'/bin/', + ]) + ->withRootFiles() + ->withSets([ + SetList::PHP_82, + PHPUnitSetList::PHPUNIT_100, + PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES, + PHPUnitSetList::PHPUNIT_CODE_QUALITY, + ]) + ->withSkip([ + AddSeeTestAnnotationRector::class, + StringClassNameToClassConstantRector::class, + ]); diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..ed69c9bc --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,123 @@ +import process from 'node:process' +import { defineConfig } from 'rollup' +import clear from 'rollup-plugin-clear' +import resolve from '@rollup/plugin-node-resolve' +import cleanup from 'rollup-plugin-cleanup' +import typescript from '@rollup/plugin-typescript' +import babel from '@rollup/plugin-babel' +import terser from '@rollup/plugin-terser' +import filesize from 'rollup-plugin-filesize' +import copy from 'rollup-plugin-copy' +import postcss from 'rollup-plugin-postcss' +import cssnano from 'cssnano' +import autoprefixer from 'autoprefixer' +import discardComments from 'postcss-discard-comments' + +const isProduction = process.env.NODE_ENV === 'production' + +const modules = [ + { name: 'flasher', path: 'src/Prime/Resources' }, + { name: 'noty', path: 'src/Noty/Prime/Resources', globals: { noty: 'Noty' }, assets: ['noty/lib/noty.min.js', 'noty/lib/noty.css', 'noty/lib/themes/mint.css'] }, + { name: 'notyf', path: 'src/Notyf/Prime/Resources' }, + { name: 'sweetalert', path: 'src/SweetAlert/Prime/Resources', globals: { sweetalert2: 'Swal' }, assets: ['sweetalert2/dist/sweetalert2.min.js', 'sweetalert2/dist/sweetalert2.min.css'] }, + { name: 'toastr', path: 'src/Toastr/Prime/Resources', globals: { toastr: 'toastr' }, assets: ['jquery/dist/jquery.min.js', 'toastr/build/toastr.min.js', 'toastr/build/toastr.min.css'] }, +] + +const postcssPlugins = [ + cssnano(), + discardComments({ removeAll: true }), + autoprefixer({ overrideBrowserslist: ['> 0%'] }), +] + +function commonPlugins(path) { + return [ + resolve(), + typescript({ compilerOptions: { outDir: `${path}/dist` }, include: [`${path}/assets/**/**`] }), + // babel({ babelHelpers: 'bundled' }), + ] +} + +function createConfig(module) { + module = { ...module, globals: createGlobals(module) } + + return defineConfig({ + input: `${module.path}/assets/index.ts`, + external: Object.keys(module.globals), + plugins: createPlugins(module), + output: createOutput(module), + }) +} + +function createGlobals(module) { + const globals = module.globals || {} + + if (module.name !== 'flasher') { + globals['@flasher/flasher'] = 'flasher' + } + + return globals +} + +function createPlugins({ name, path, assets }) { + const filename = name === 'flasher' ? 'flasher.min.css' : `flasher-${name}.min.css` + + const copyAssets = assets + ? [copy({ targets: assets.map((asset) => ({ + src: asset.startsWith('node_modules') ? asset : `node_modules/${asset}`, + dest: `${path}/public` })) })] + : [] + + return [ + ...(isProduction ? [clear({ targets: [`${path}/dist`, `${path}/public`] })] : []), + postcss({ extract: filename, plugins: isProduction ? postcssPlugins : [] }), + ...commonPlugins(path), + ...(isProduction ? [cleanup({ comments: 'none' })] : []), + ...copyAssets, + ] +} + +function createOutput({ name, path, globals }) { + const filename = name === 'flasher' ? 'flasher' : `flasher-${name}` + const distPath = `${path}/dist` + const publicPath = `${path}/public` + + const output = { + name, + globals, + assetFileNames: '[name][extname]', + } + + const plugins = [ + ...(isProduction ? [terser({ format: { comments: false } })] : []), + copy({ targets: [{ src: [`${distPath}/*.min.js`, `${distPath}/*.min.css`], dest: publicPath }], hook: 'writeBundle' }), + ...(isProduction ? [terser({ format: { comments: false } })] : []), + ...(isProduction ? [filesize()] : []), + ] + + return [ + { format: 'umd', file: `${distPath}/${filename}.min.js`, plugins, ...output }, + { format: 'umd', file: `${distPath}/${filename}.js`, ...output }, + { format: 'es', file: `${distPath}/${filename}.esm.js`, ...output }, + // { format: 'cjs', file: `${distPath}/${filename}.cjs.js`, ...output }, + // { format: 'iife', file: `${distPath}/${filename}.iife.js`, ...output }, + ] +} + +function createPrimePlugin() { + const path = 'src/Prime/Resources' + const filename = `${path}/dist/plugin` + + return defineConfig({ + input: `${path}/assets/plugin.ts`, + plugins: [resolve(), typescript({ compilerOptions: { outDir: `${path}/dist` }, include: [`${path}/assets/**/**`] })], + output: [ + { format: 'es', file: `${filename}.js` }, + // { format: 'cjs', file: `${filename}.cjs.js` }, + ], + }) +} + +export default [ + createPrimePlugin(), + ...modules.map(createConfig), +] diff --git a/src/Cli/Laravel/.github/FUNDING.yml b/src/Cli/Laravel/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/src/Cli/Laravel/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Cli/Laravel/.github/workflows/auto_closer.yaml b/src/Cli/Laravel/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/src/Cli/Laravel/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/src/Cli/Laravel/FlasherCliServiceProvider.php b/src/Cli/Laravel/FlasherCliServiceProvider.php deleted file mode 100644 index f3f0e8a2..00000000 --- a/src/Cli/Laravel/FlasherCliServiceProvider.php +++ /dev/null @@ -1,106 +0,0 @@ - - */ - -namespace Flasher\Cli\Laravel; - -use Flasher\Cli\Prime\CliFactory; -use Flasher\Cli\Prime\EventListener\RenderListener; -use Flasher\Cli\Prime\Notify; -use Flasher\Cli\Prime\Presenter\CliPresenter; -use Flasher\Prime\EventDispatcher\EventDispatcherInterface; -use Flasher\Prime\FlasherInterface; -use Flasher\Prime\Response\ResponseManagerInterface; -use Illuminate\Container\Container; -use Illuminate\Support\ServiceProvider; - -final class FlasherCliServiceProvider extends ServiceProvider -{ - /** - * @return void - */ - public function boot() - { - $this->processConfiguration(); - $this->registerRenderListener(); - $this->registerPresenter(); - } - - /** - * {@inheritdoc} - */ - public function register() - { - $this->registerNotifierFactory(); - $this->registerNotifier(); - } - - /** - * @return void - */ - private function processConfiguration() - { - $name = 'flasher_cli'; - $config = $this->app->make('config'); - - $config->set($name, $config->get($name, array())); // @phpstan-ignore-line - } - - /** - * @return void - */ - private function registerNotifierFactory() - { - $this->app->singleton('flasher.cli', function (Container $app) { - return new CliFactory($app->make('flasher.storage_manager')); // @phpstan-ignore-line - }); - - $this->app->alias('flasher.cli', 'Flasher\Cli\Prime\CliFactory'); - } - - /** - * @return void - */ - private function registerNotifier() - { - $this->app->singleton('flasher.notify', function (Container $app) { - /** @phpstan-ignore-next-line */ - $title = $app->make('config')->get('flasher_cli.title', null); - $icons = $app->make('config')->get('flasher_cli.icons', array()); // @phpstan-ignore-line - - return new Notify($title, $icons); - }); - - $this->app->alias('flasher.notify', 'Flasher\Cli\Prime\Notify'); - $this->app->alias('flasher.notify', 'Flasher\Cli\Prime\NotifyInterface'); - } - - /** - * @return void - */ - private function registerRenderListener() - { - /** @var FlasherInterface $flasher */ - $flasher = $this->app->make('flasher'); - $this->app->extend('flasher.event_dispatcher', function (EventDispatcherInterface $dispatcher) use ($flasher) { - $dispatcher->addSubscriber(new RenderListener($flasher)); - - return $dispatcher; - }); - } - - /** - * @return void - */ - private function registerPresenter() - { - $this->app->extend('flasher.response_manager', function (ResponseManagerInterface $manager, Container $app) { - $manager->addPresenter(CliPresenter::NAME, new CliPresenter($app->make('flasher.notify'))); // @phpstan-ignore-line - - return $manager; - }); - } -} diff --git a/src/Cli/Laravel/LICENSE b/src/Cli/Laravel/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/src/Cli/Laravel/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/src/Cli/Laravel/README.md b/src/Cli/Laravel/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/src/Cli/Laravel/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/src/Cli/Laravel/composer.json b/src/Cli/Laravel/composer.json deleted file mode 100644 index 342603c4..00000000 --- a/src/Cli/Laravel/composer.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "php-flasher/flasher-cli-laravel", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "library", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-cli": "^1.15.14", - "php-flasher/flasher-laravel": "^1.15.14" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "autoload": { - "psr-4": { - "Flasher\\Cli\\Laravel\\": "" - } - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - }, - "extra": { - "laravel": { - "providers": [ - "Flasher\\Cli\\Laravel\\FlasherCliServiceProvider" - ] - } - } -} diff --git a/src/Cli/Prime/.github/FUNDING.yml b/src/Cli/Prime/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/src/Cli/Prime/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Cli/Prime/.github/workflows/auto_closer.yaml b/src/Cli/Prime/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/src/Cli/Prime/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/src/Cli/Prime/.phpstorm.meta.php b/src/Cli/Prime/.phpstorm.meta.php deleted file mode 100644 index ef331a8a..00000000 --- a/src/Cli/Prime/.phpstorm.meta.php +++ /dev/null @@ -1,11 +0,0 @@ - \Flasher\Cli\Prime\CliFactory::class -])); - -override(\Flasher\Prime\FlasherInterface::using(), map([ - 'cli' => \Flasher\Cli\Prime\CliFactory::class -])); diff --git a/src/Cli/Prime/CliBuilder.php b/src/Cli/Prime/CliBuilder.php deleted file mode 100644 index 347e5e2b..00000000 --- a/src/Cli/Prime/CliBuilder.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime; - -use Flasher\Prime\Notification\NotificationBuilder; - -final class CliBuilder extends NotificationBuilder -{ - /** - * @param string $title - * - * @return static - */ - public function title($title) - { - /** @var Notification $notification */ - $notification = $this->envelope->getNotification(); - $notification->setTitle($title); - - return $this; - } - - /** - * @param string $icon - * - * @return static - */ - public function icon($icon) - { - /** @var Notification $notification */ - $notification = $this->envelope->getNotification(); - $notification->setIcon($icon); - - return $this; - } -} diff --git a/src/Cli/Prime/CliFactory.php b/src/Cli/Prime/CliFactory.php deleted file mode 100644 index 443c40e7..00000000 --- a/src/Cli/Prime/CliFactory.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime; - -use Flasher\Prime\Factory\NotificationFactory; - -final class CliFactory extends NotificationFactory -{ - public function createNotificationBuilder() - { - return new CliBuilder($this->getStorageManager(), new Notification(), 'cli'); - } -} diff --git a/src/Cli/Prime/EventListener/RenderListener.php b/src/Cli/Prime/EventListener/RenderListener.php deleted file mode 100644 index 6d4648a2..00000000 --- a/src/Cli/Prime/EventListener/RenderListener.php +++ /dev/null @@ -1,46 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\EventListener; - -use Flasher\Cli\Prime\Presenter\CliPresenter; -use Flasher\Prime\EventDispatcher\Event\PostPersistEvent; -use Flasher\Prime\EventDispatcher\EventListener\EventSubscriberInterface; -use Flasher\Prime\FlasherInterface; - -final class RenderListener implements EventSubscriberInterface -{ - /** - * @var FlasherInterface - */ - private $flasher; - - public function __construct(FlasherInterface $flasher) - { - $this->flasher = $flasher; - } - - /** - * @return void - */ - public function __invoke(PostPersistEvent $event) - { - if ('cli' !== \PHP_SAPI) { - return; - } - - $this->flasher->render(array(), CliPresenter::NAME); - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() - { - return 'Flasher\Prime\EventDispatcher\Event\PostPersistEvent'; - } -} diff --git a/src/Cli/Prime/LICENSE b/src/Cli/Prime/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/src/Cli/Prime/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/src/Cli/Prime/Notification.php b/src/Cli/Prime/Notification.php deleted file mode 100644 index 404f38d4..00000000 --- a/src/Cli/Prime/Notification.php +++ /dev/null @@ -1,228 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime; - -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\Notification as BaseNotification; -use Flasher\Prime\Notification\NotificationInterface; - -final class Notification extends BaseNotification -{ - /** - * @var string|null - */ - private $title; - - /** - * @var string|null - */ - private $icon; - - /** - * @param string|null $message - * @param string|null $title - * @param string|null $icon - * @param string $type - * @param array $options - */ - public function __construct($message = null, $title = null, $icon = null, $type = self::INFO, array $options = array()) - { - $this->message = $message; - $this->title = $title; - $this->icon = $icon; - $this->type = $type; - $this->options = $options; - } - - /** - * @param Notification|string $notification - * - * @return static - */ - public static function wrap($notification) - { - if ($notification instanceof Notification) { - return $notification; - } - - return self::create($notification); - } - - /** - * @param string $message - * @param string|null $title - * @param string|null $icon - * @param string $type - * @param array $options - * - * @return static - */ - public static function create($message, $title = null, $icon = null, $type = self::INFO, array $options = array()) - { - return new self($message, $title, $icon, $type, $options); - } - - /** - * @param string $message - * @param string|null $title - * @param string|null $icon - * @param array $options - * - * @return static - */ - public static function error($message, $title = null, $icon = null, array $options = array()) - { - return self::create($message, $title, $icon, NotificationInterface::ERROR, $options); - } - - /** - * @param string $message - * @param string|null $title - * @param string|null $icon - * @param array $options - * - * @return static - */ - public static function info($message, $title = null, $icon = null, array $options = array()) - { - return self::create($message, $title, $icon, NotificationInterface::INFO, $options); - } - - /** - * @param string $message - * @param string|null $title - * @param string|null $icon - * @param array $options - * - * @return static - */ - public static function success($message, $title = null, $icon = null, array $options = array()) - { - return self::create($message, $title, $icon, NotificationInterface::SUCCESS, $options); - } - - /** - * @param string $message - * @param string|null $title - * @param string|null $icon - * @param array $options - * - * @return static - */ - public static function warning($message, $title = null, $icon = null, array $options = array()) - { - return self::create($message, $title, $icon, NotificationInterface::WARNING, $options); - } - - /** - * {@inheritdoc} - */ - public function getMessage() - { - $message = parent::getMessage(); - - if (\is_string($message)) { - $message = addslashes($message); - } - - return $message; - } - - /** - * {@inheritdoc} - */ - public function getOption($name, $default = null) - { - $option = parent::getOption($name, $default); - - if (\is_string($option)) { - $option = addslashes($option); - } - - return $option; - } - - /** - * @return string|null - */ - public function getTitle() - { - $title = $this->title; - - if (\is_string($title)) { - $title = addslashes($title); - } - - return $title; - } - - /** - * @param string|null $title - * - * @return static - */ - public function setTitle($title) - { - $this->title = $title; - - return $this; - } - - /** - * @return string|null - */ - public function getIcon() - { - return $this->icon; - } - - /** - * @param string|null $icon - * - * @return static - */ - public function setIcon($icon) - { - $this->icon = $icon; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - return array_merge(parent::toArray(), array( - 'title' => $this->getTitle(), - 'icon' => $this->getIcon(), - )); - } - - /** - * @return static - */ - public static function fromEnvelope(Envelope $envelope) - { - $self = new self(); - - $self->setType($envelope->getType()); - $self->setMessage($envelope->getMessage()); - $self->setOptions($envelope->getOptions()); - - $notification = $envelope->getNotification(); - if (!$notification instanceof self) { - return $self; - } - - $self->setTitle($notification->getTitle()); - $self->setIcon($notification->getIcon()); - - return $self; - } -} diff --git a/src/Cli/Prime/Notifier/AppleScriptBaseNotifier.php b/src/Cli/Prime/Notifier/AppleScriptBaseNotifier.php deleted file mode 100644 index 6411dccc..00000000 --- a/src/Cli/Prime/Notifier/AppleScriptBaseNotifier.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; - -final class AppleScriptBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addArgument(sprintf('display notification "%s"', $notification->getMessage())) - ->addArgument(sprintf('with title "%s"', $notification->getTitle())); - - /** @var string $subtitle */ - $subtitle = $notification->getOption('subtitle'); - if ($subtitle) { - $cmd->addArgument(sprintf('subtitle "%s"', $subtitle)); - } - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - if (!$this->getProgram()) { - return false; - } - - return OS::isMacOS() && version_compare(OS::getMacOSVersion(), '10.9.0', '>='); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'osascript'; - } -} diff --git a/src/Cli/Prime/Notifier/BaseNotifier.php b/src/Cli/Prime/Notifier/BaseNotifier.php deleted file mode 100644 index 53eddf96..00000000 --- a/src/Cli/Prime/Notifier/BaseNotifier.php +++ /dev/null @@ -1,111 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\NotifyInterface; -use Flasher\Cli\Prime\System\Path; -use Flasher\Cli\Prime\System\Program; -use Flasher\Prime\Notification\NotificationInterface; - -abstract class BaseNotifier implements NotifyInterface -{ - /** - * {@inheritdoc} - */ - public function isSupported() - { - return true; - } - - /** - * {@inheritdoc} - */ - public function getPriority() - { - return 0; - } - - /** - * @return string|null - */ - public function getBinary() - { - return null; - } - - /** - * @return string|string[] - */ - public function getBinaryPaths() - { - return array(); - } - - /** - * @return string|null - */ - public function getProgram() - { - if (Program::exist($this->getBinary())) { - return $this->getBinary(); - } - - foreach ((array) $this->getBinaryPaths() as $path) { - $path = Path::realpath($path); - - if (file_exists($path)) { - return $path; - } - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function success($message, $title = null, $options = array()) - { - $this->type(NotificationInterface::SUCCESS, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function info($message, $title = null, $options = array()) - { - $this->type(NotificationInterface::INFO, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function error($message, $title = null, $options = array()) - { - $this->type(NotificationInterface::ERROR, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function warning($message, $title = null, $options = array()) - { - $this->type(NotificationInterface::WARNING, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function type($type, $message, $title = null, $options = array()) - { - $notification = new Notification($message, $title, null, $type, $options); - - $this->send($notification); - } -} diff --git a/src/Cli/Prime/Notifier/GrowlNotifyBaseNotifier.php b/src/Cli/Prime/Notifier/GrowlNotifyBaseNotifier.php deleted file mode 100644 index 4a0434ef..00000000 --- a/src/Cli/Prime/Notifier/GrowlNotifyBaseNotifier.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; - -final class GrowlNotifyBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('--message', $notification->getMessage()) - ->addOption('--title', $notification->getTitle()) - ->addOption('--image', $notification->getIcon()); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return OS::isMacOS() && $this->getProgram(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'growlnotify'; - } -} diff --git a/src/Cli/Prime/Notifier/KDialogBaseNotifier.php b/src/Cli/Prime/Notifier/KDialogBaseNotifier.php deleted file mode 100644 index b5e9ba65..00000000 --- a/src/Cli/Prime/Notifier/KDialogBaseNotifier.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; - -final class KDialogBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('--passivepopup', $notification->getMessage()) - ->addOption('--title', $notification->getTitle()) - ->addArgument(5); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return OS::isUnix() && $this->getProgram(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'kdialog'; - } -} diff --git a/src/Cli/Prime/Notifier/NotifuBaseNotifier.php b/src/Cli/Prime/Notifier/NotifuBaseNotifier.php deleted file mode 100644 index 17087deb..00000000 --- a/src/Cli/Prime/Notifier/NotifuBaseNotifier.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; -use Flasher\Cli\Prime\System\Path; - -final class NotifuBaseNotifier extends BaseNotifier -{ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('/m', $notification->getMessage()) - ->addOption('/p', $notification->getTitle()) - ->addOption('/i', $notification->getIcon()); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return OS::isWindowsSeven() && $this->getProgram(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'notifu'; - } - - /** - * {@inheritdoc} - */ - public function getBinaryPaths() - { - return Path::realpath(__DIR__.'/../Resources/bin/notifu/notifu.exe'); - } -} diff --git a/src/Cli/Prime/Notifier/NotifySendBaseNotifier.php b/src/Cli/Prime/Notifier/NotifySendBaseNotifier.php deleted file mode 100644 index 9fbd24f4..00000000 --- a/src/Cli/Prime/Notifier/NotifySendBaseNotifier.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; - -final class NotifySendBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('--urgency', 'normal') - ->addOption('--app-name', 'notify') - ->addOption('--icon', $notification->getIcon()) - ->addOption('--expire-time', 1) - ->addArgument($notification->getTitle()) - ->addArgument($notification->getMessage()); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return OS::isUnix() && $this->getProgram(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'notify-send'; - } -} diff --git a/src/Cli/Prime/Notifier/NullBaseNotifier.php b/src/Cli/Prime/Notifier/NullBaseNotifier.php deleted file mode 100644 index ea93cbfe..00000000 --- a/src/Cli/Prime/Notifier/NullBaseNotifier.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -final class NullBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return false; - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return ''; - } -} diff --git a/src/Cli/Prime/Notifier/SnoreToastBaseNotifier.php b/src/Cli/Prime/Notifier/SnoreToastBaseNotifier.php deleted file mode 100644 index cce0d642..00000000 --- a/src/Cli/Prime/Notifier/SnoreToastBaseNotifier.php +++ /dev/null @@ -1,61 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; -use Flasher\Cli\Prime\System\Path; - -final class SnoreToastBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('-m', $notification->getMessage()) - ->addOption('-t', $notification->getTitle()) - ->addOption('-p', $notification->getIcon()); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - if (!$this->getProgram()) { - return false; - } - - return OS::isWindowsEightOrHigher() || OS::isWindowsSubsystemForLinux(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'snoretoast'; - } - - /** - * {@inheritdoc} - */ - public function getBinaryPaths() - { - return Path::realpath(__DIR__.'/../Resources/bin/snoreToast/snoretoast-x86.exe'); - } -} diff --git a/src/Cli/Prime/Notifier/TerminalNotifierBaseNotifier.php b/src/Cli/Prime/Notifier/TerminalNotifierBaseNotifier.php deleted file mode 100644 index 93224eca..00000000 --- a/src/Cli/Prime/Notifier/TerminalNotifierBaseNotifier.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; - -final class TerminalNotifierBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('-message', $notification->getMessage()) - ->addOption('-title', $notification->getTitle()); - - if (version_compare(OS::getMacOSVersion(), '10.9.0', '>=')) { - $cmd->addOption('-appIcon', $notification->getIcon()); - } - - /** @var string|null $url */ - $url = $notification->getOption('url'); - if ($url) { - $cmd->addOption('-open', $url); - } - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return OS::isMacOS() && $this->getProgram(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'terminal-notifier'; - } -} diff --git a/src/Cli/Prime/Notifier/ToasterBaseNotifier.php b/src/Cli/Prime/Notifier/ToasterBaseNotifier.php deleted file mode 100644 index f9f6f2c8..00000000 --- a/src/Cli/Prime/Notifier/ToasterBaseNotifier.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; -use Flasher\Cli\Prime\System\Path; - -final class ToasterBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addOption('-t', $notification->getTitle()) - ->addOption('-m', $notification->getMessage()) - ->addOption('-p', $notification->getIcon()) - ->addArgument('-w'); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - if (!$this->getProgram()) { - return false; - } - - return OS::isWindowsEightOrHigher() || OS::isWindowsSubsystemForLinux(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'toast'; - } - - /** - * {@inheritdoc} - */ - public function getBinaryPaths() - { - return Path::realpath(__DIR__.'/../Resources/bin/toaster/toast.exe'); - } -} diff --git a/src/Cli/Prime/Notifier/ZenityBaseNotifier.php b/src/Cli/Prime/Notifier/ZenityBaseNotifier.php deleted file mode 100644 index ca0f2de1..00000000 --- a/src/Cli/Prime/Notifier/ZenityBaseNotifier.php +++ /dev/null @@ -1,48 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Notifier; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\System\Command; -use Flasher\Cli\Prime\System\OS; - -final class ZenityBaseNotifier extends BaseNotifier -{ - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = Notification::wrap($notification); - - $cmd = new Command($this->getProgram()); - - $cmd - ->addArgument('--notification') - ->addOption('--text', $notification->getTitle().'\n\n'.$notification->getMessage()) - ->addOption('--window-icon', $notification->getIcon()); - - $cmd->run(); - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - return OS::isUnix() && $this->getProgram(); - } - - /** - * {@inheritdoc} - */ - public function getBinary() - { - return 'zenity'; - } -} diff --git a/src/Cli/Prime/Notify.php b/src/Cli/Prime/Notify.php deleted file mode 100644 index 491599ab..00000000 --- a/src/Cli/Prime/Notify.php +++ /dev/null @@ -1,231 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime; - -use Flasher\Cli\Prime\Notifier\BaseNotifier; -use Flasher\Cli\Prime\System\Path; -use Flasher\Prime\Notification\NotificationInterface; - -final class Notify extends BaseNotifier -{ - /** - * @var NotifyInterface|null - */ - private $notifier; - - /** - * @var NotifyInterface[] - */ - private $notifiers = array(); - - /** - * @var NotifyInterface[] - */ - private $sorted = array(); - - /** - * @var bool|null - */ - private $isSupported; - - /** - * @var string|null - */ - private $title; - - /** - * @var array{success?: string, error?: string, info?: string, warning?: string} - */ - private $icons = array(); - - /** - * @param string|null $title - * @param array{success?: string, error?: string, info?: string, warning?: string}|string $icons - */ - public function __construct($title = 'PHPFlasher', $icons = array()) - { - $this->title = $title; - $this->icons = $this->configureIcons($icons); - - $this->addNotifier(new Notifier\NotifySendBaseNotifier()); - $this->addNotifier(new Notifier\AppleScriptBaseNotifier()); - $this->addNotifier(new Notifier\GrowlNotifyBaseNotifier()); - $this->addNotifier(new Notifier\KDialogBaseNotifier()); - $this->addNotifier(new Notifier\NotifuBaseNotifier()); - $this->addNotifier(new Notifier\SnoreToastBaseNotifier()); - $this->addNotifier(new Notifier\TerminalNotifierBaseNotifier()); - $this->addNotifier(new Notifier\ToasterBaseNotifier()); - $this->addNotifier(new Notifier\ZenityBaseNotifier()); - } - - /** - * @param string|null $title - * @param array{success?: string, error?: string, info?: string, warning?: string}|string $icons - * - * @return static - */ - public static function create($title = null, $icons = array()) - { - return new self($title, $icons); - } - - /** - * {@inheritdoc} - */ - public function send($notification) - { - $notification = $this->configureNotification($notification); - - $notifier = $this->createNotifier(); - $notifier->send($notification); - } - - /** - * @return void - */ - public function addNotifier(NotifyInterface $notifier) - { - $this->notifiers[] = $notifier; - $this->reset(); - } - - /** - * {@inheritdoc} - */ - public function getPriority() - { - return 0; - } - - /** - * {@inheritdoc} - */ - public function isSupported() - { - if (null !== $this->isSupported) { - return $this->isSupported; - } - - if ($this->notifier instanceof NotifyInterface) { - return true; - } - - foreach ($this->getNotifiers() as $notifier) { - if ($notifier->isSupported()) { - return $this->isSupported = true; - } - } - - return false; - } - - /** - * @return void - */ - private function reset() - { - $this->notifier = null; - $this->sorted = array(); - $this->isSupported = null; - } - - /** - * @return NotifyInterface[] - */ - private function getNotifiers() - { - if (array() !== $this->sorted) { - return $this->sorted; - } - - $this->sorted = $this->notifiers; - - usort($this->sorted, static function (NotifyInterface $a, NotifyInterface $b) { - $priorityA = $a->getPriority(); - $priorityB = $b->getPriority(); - - if ($priorityA === $priorityB) { - return 0; - } - - return $priorityA < $priorityB ? 1 : -1; - }); - - return $this->sorted; - } - - /** - * @return NotifyInterface - */ - private function createNotifier() - { - if ($this->notifier instanceof NotifyInterface) { - return $this->notifier; - } - - foreach ($this->getNotifiers() as $notifier) { - if ($notifier->isSupported()) { - return $this->notifier = $notifier; - } - } - - return new Notifier\NullBaseNotifier(); - } - - /** - * @param array{success?: string, error?: string, info?: string, warning?: string}|string $icons - * - * @return array<'default'|'error'|'info'|'success'|'warning', string> - */ - private function configureIcons($icons = array()) - { - $icons = $icons ?: array(); - - if (!\is_array($icons)) { - $icons = array( - NotificationInterface::SUCCESS => $icons, - NotificationInterface::ERROR => $icons, - NotificationInterface::INFO => $icons, - NotificationInterface::WARNING => $icons, - 'default' => $icons, - ); - } - - return array_merge(array( - NotificationInterface::SUCCESS => Path::realpath(__DIR__.'/Resources/icons/success.png'), - NotificationInterface::ERROR => Path::realpath(__DIR__.'/Resources/icons/error.png'), - NotificationInterface::INFO => Path::realpath(__DIR__.'/Resources/icons/info.png'), - NotificationInterface::WARNING => Path::realpath(__DIR__.'/Resources/icons/warning.png'), - 'default' => Path::realpath(__DIR__.'/Resources/icons/info.png'), - ), $icons); - } - - /** - * @param Notification|string $notification - * - * @return Notification - */ - private function configureNotification($notification) - { - $notification = Notification::wrap($notification); - - if (null === $notification->getTitle()) { - $notification->setTitle($this->title); - } - - if (null === $notification->getIcon() && isset($this->icons[$notification->getType()])) { - $notification->setIcon($this->icons[$notification->getType()]); - } - - if (null === $notification->getIcon()) { - $notification->setIcon($this->icons['default']); // @phpstan-ignore-line - } - - return $notification; - } -} diff --git a/src/Cli/Prime/NotifyInterface.php b/src/Cli/Prime/NotifyInterface.php deleted file mode 100644 index 994e0cbe..00000000 --- a/src/Cli/Prime/NotifyInterface.php +++ /dev/null @@ -1,74 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime; - -interface NotifyInterface -{ - /** - * @param Notification|string $notification - * - * @return void - */ - public function send($notification); - - /** - * @return int - */ - public function getPriority(); - - /** - * @return bool - */ - public function isSupported(); - - /** - * @param string $type - * @param string $message - * @param string|null $title - * @param array $options - * - * @return void - */ - public function type($type, $message, $title = null, $options = array()); - - /** - * @param string $message - * @param string|null $title - * @param array $options - * - * @return void - */ - public function warning($message, $title = null, $options = array()); - - /** - * @param string $message - * @param string|null $title - * @param array $options - * - * @return void - */ - public function info($message, $title = null, $options = array()); - - /** - * @param string $message - * @param string|null $title - * @param array $options - * - * @return void - */ - public function error($message, $title = null, $options = array()); - - /** - * @param string $message - * @param string|null $title - * @param array $options - * - * @return void - */ - public function success($message, $title = null, $options = array()); -} diff --git a/src/Cli/Prime/Presenter/CliPresenter.php b/src/Cli/Prime/Presenter/CliPresenter.php deleted file mode 100644 index 5e064d59..00000000 --- a/src/Cli/Prime/Presenter/CliPresenter.php +++ /dev/null @@ -1,44 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\Presenter; - -use Flasher\Cli\Prime\Notification; -use Flasher\Cli\Prime\Notify; -use Flasher\Cli\Prime\NotifyInterface; -use Flasher\Prime\Response\Presenter\PresenterInterface; -use Flasher\Prime\Response\Response; - -final class CliPresenter implements PresenterInterface -{ - const NAME = 'cli'; - - /** - * @var NotifyInterface - */ - private $notifier; - - public function __construct(NotifyInterface $notifier = null) - { - $this->notifier = $notifier ?: new Notify(); - } - - /** - * {@inheritdoc} - */ - public function render(Response $response) - { - if ('cli' !== \PHP_SAPI || array() === $response->getEnvelopes()) { - return; - } - - foreach ($response->getEnvelopes() as $envelope) { - $notification = Notification::fromEnvelope($envelope); - $this->notifier->send($notification); - } - } -} diff --git a/src/Cli/Prime/README.md b/src/Cli/Prime/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/src/Cli/Prime/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/src/Cli/Prime/Resources/bin/notifu/README.md b/src/Cli/Prime/Resources/bin/notifu/README.md deleted file mode 100644 index 88e4e422..00000000 --- a/src/Cli/Prime/Resources/bin/notifu/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Notifu - -This binary come from the [Notifu](http://www.paralint.com/projects/notifu) -project. All credits for this Windows tool goes to their original authors. - -Only the required file was extracted here. If you want to fully test it, please -have a look at [this url](http://www.paralint.com/projects/notifu) instead. diff --git a/src/Cli/Prime/Resources/bin/snoreToast/LICENSE b/src/Cli/Prime/Resources/bin/snoreToast/LICENSE deleted file mode 100644 index f579bb74..00000000 --- a/src/Cli/Prime/Resources/bin/snoreToast/LICENSE +++ /dev/null @@ -1,166 +0,0 @@ -// Retrieved from https://github.com/KDE/snoretoast/blob/master/COPYING.LGPL-3 version 0.7.0 - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. \ No newline at end of file diff --git a/src/Cli/Prime/Resources/bin/snoreToast/README.md b/src/Cli/Prime/Resources/bin/snoreToast/README.md deleted file mode 100644 index 64eebf57..00000000 --- a/src/Cli/Prime/Resources/bin/snoreToast/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# SnoreToast - -These toaster binary files come from the [KDE/snoretoast](https://github.com/KDE/snoretoast) -project. All credits for this Windows 8* application goes to [KDE project](https://github.com/KDE). - -Only the required files were extracted here. If you want to fully test it, -please have a look at the github project instead. diff --git a/src/Cli/Prime/Resources/bin/toaster/README.md b/src/Cli/Prime/Resources/bin/toaster/README.md deleted file mode 100644 index 1ccca586..00000000 --- a/src/Cli/Prime/Resources/bin/toaster/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Toaster - -These toaster binary files come from the [nels-o/toaster](https://github.com/nels-o/toaster) -project. All credits for this Windows 8 application goes to [nels-o](https://github.com/nels-o). - -Only the required files were extracted here. If you want to fully test it, -please have a look at the github project instead. diff --git a/src/Cli/Prime/Resources/bin/toaster/toast.exe b/src/Cli/Prime/Resources/bin/toaster/toast.exe deleted file mode 100644 index e69de29b..00000000 diff --git a/src/Cli/Prime/Resources/icons/error.png b/src/Cli/Prime/Resources/icons/error.png deleted file mode 100644 index 06b4c269..00000000 Binary files a/src/Cli/Prime/Resources/icons/error.png and /dev/null differ diff --git a/src/Cli/Prime/Resources/icons/info.png b/src/Cli/Prime/Resources/icons/info.png deleted file mode 100644 index 60d03393..00000000 Binary files a/src/Cli/Prime/Resources/icons/info.png and /dev/null differ diff --git a/src/Cli/Prime/Resources/icons/success.png b/src/Cli/Prime/Resources/icons/success.png deleted file mode 100644 index 7109c421..00000000 Binary files a/src/Cli/Prime/Resources/icons/success.png and /dev/null differ diff --git a/src/Cli/Prime/Resources/icons/warning.png b/src/Cli/Prime/Resources/icons/warning.png deleted file mode 100644 index 94a312d7..00000000 Binary files a/src/Cli/Prime/Resources/icons/warning.png and /dev/null differ diff --git a/src/Cli/Prime/System/Command.php b/src/Cli/Prime/System/Command.php deleted file mode 100644 index 8fe7e472..00000000 --- a/src/Cli/Prime/System/Command.php +++ /dev/null @@ -1,100 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\System; - -final class Command -{ - /** - * @var string|null - */ - private $command; - - /** - * @var array - */ - private $options = array(); - - /** - * @var array - */ - private $arguments = array(); - - /** - * @param string|null $command - */ - public function __construct($command) - { - $this->command = null !== $command ? escapeshellcmd((string) $command) : null; - } - - /** - * @param string $name - * @param int|string|null $value - * - * @return static - */ - public function addOption($name, $value = null) - { - $this->options[$name] = null !== $value ? escapeshellarg((string) $value) : null; - - return $this; - } - - /** - * @param int|string|null $argument - * - * @return static - */ - public function addArgument($argument) - { - $this->arguments[] = null !== $argument ? escapeshellarg((string) $argument) : $argument; - - return $this; - } - - /** - * @return void - */ - public function run() - { - $command = $this->command.' '.$this->formatOptions().' '.$this->formatArguments(); - - if (OS::isWindows()) { - pclose(popen('start /B '.$command, 'r')); // @phpstan-ignore-line - - return; - } - - exec($command); - } - - /** - * @return string - */ - private function formatArguments() - { - return implode(' ', $this->arguments); - } - - /** - * @return string - */ - private function formatOptions() - { - $line = ''; - - foreach ($this->options as $name => $value) { - $line .= $name; - if ($value) { - $line .= ' '.$value.' '; - } - } - - return $line; - } -} diff --git a/src/Cli/Prime/System/OS.php b/src/Cli/Prime/System/OS.php deleted file mode 100644 index b200d2e0..00000000 --- a/src/Cli/Prime/System/OS.php +++ /dev/null @@ -1,94 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\System; - -final class OS -{ - /** - * @return string - */ - public static function getName() - { - return php_uname('s'); - } - - /** - * @return string - */ - public static function getRelease() - { - return php_uname('r'); - } - - /** - * @return bool - */ - public static function isUnix() - { - return \in_array(self::getName(), array( - 'Linux', - 'FreeBSD', - 'NetBSD', - 'OpenBSD', - 'SunOS', - 'DragonFly', - ), true); - } - - /** - * @return bool - */ - public static function isWindows() - { - return 'WIN' === strtoupper(substr(self::getName(), 0, 3)); - } - - /** - * @return bool - */ - public static function isWindowsSeven() - { - return self::isWindows() && '6.1' === self::getRelease(); - } - - /** - * @return bool - */ - public static function isWindowsEightOrHigher() - { - return self::isWindows() && version_compare(self::getRelease(), '6.2', '>='); - } - - /** - * @return bool - */ - public static function isWindowsSubsystemForLinux() - { - return self::isUnix() && false !== mb_strpos(strtolower(self::getName()), 'microsoft'); - } - - /** - * @return bool - */ - public static function isMacOS() - { - return false !== strpos(self::getName(), 'Darwin'); - } - - /** - * @return string - */ - public static function getMacOSVersion() - { - exec('sw_vers -productVersion', $output); - - $output = (array) $output; - - return trim(reset($output)); - } -} diff --git a/src/Cli/Prime/System/Path.php b/src/Cli/Prime/System/Path.php deleted file mode 100644 index ca1c5db4..00000000 --- a/src/Cli/Prime/System/Path.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\System; - -final class Path -{ - /** - * @param string $path - * - * @return string - */ - public static function realpath($path) - { - return (string) realpath(str_replace(array('/', '\\'), \DIRECTORY_SEPARATOR, $path)); - } -} diff --git a/src/Cli/Prime/System/Program.php b/src/Cli/Prime/System/Program.php deleted file mode 100644 index 4bf58011..00000000 --- a/src/Cli/Prime/System/Program.php +++ /dev/null @@ -1,33 +0,0 @@ - - */ - -namespace Flasher\Cli\Prime\System; - -final class Program -{ - /** - * @param string|null $program - * - * @return bool - */ - public static function exist($program) - { - if (null === $program) { - return false; - } - - if (OS::isWindows()) { - $output = shell_exec("where {$program} 2>null"); - - return !empty($output); - } - - $output = shell_exec("command -v {$program}"); - - return !empty($output); - } -} diff --git a/src/Cli/Prime/composer.json b/src/Cli/Prime/composer.json deleted file mode 100644 index 4d711a16..00000000 --- a/src/Cli/Prime/composer.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "php-flasher/flasher-cli", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "library", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "ext-mbstring": "*", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "autoload": { - "psr-4": { - "Flasher\\Cli\\Prime\\": "" - }, - "files": [ - "helpers.php" - ] - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/src/Cli/Prime/helpers.php b/src/Cli/Prime/helpers.php deleted file mode 100644 index b8cc48c5..00000000 --- a/src/Cli/Prime/helpers.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -use Flasher\Prime\Container\FlasherContainer; - -if (!function_exists('notify')) { - /** - * @param Flasher\Cli\Prime\Notification|string|null $notification - * - * @return Flasher\Cli\Prime\Notify - */ - function notify($notification = null) - { - /** @var Flasher\Cli\Prime\Notify $notifier */ - $notifier = FlasherContainer::create('flasher.notify'); - - if (null === $notification || 0 === func_num_args()) { - return $notifier; - } - - $notifier->send($notification); - - return $notifier; - } -} diff --git a/src/Cli/Symfony/.github/FUNDING.yml b/src/Cli/Symfony/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/src/Cli/Symfony/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Cli/Symfony/.github/workflows/auto_closer.yaml b/src/Cli/Symfony/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/src/Cli/Symfony/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/src/Cli/Symfony/DependencyInjection/Compiler/NotifierCompilerPass.php b/src/Cli/Symfony/DependencyInjection/Compiler/NotifierCompilerPass.php deleted file mode 100644 index 8ff2e9fe..00000000 --- a/src/Cli/Symfony/DependencyInjection/Compiler/NotifierCompilerPass.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - -namespace Flasher\Cli\Symfony\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; - -final class NotifierCompilerPass implements CompilerPassInterface -{ - /** - * @return void - */ - public function process(ContainerBuilder $container) - { - if (!$container->has('flasher.cli_notifier')) { - return; - } - - $notifier = $container->findDefinition('flasher.cli_notifier'); - - foreach ($container->findTaggedServiceIds('flasher.cli_notifier') as $id => $tags) { - $notifier->addMethodCall('addNotifier', array(new Reference($id))); - } - } -} diff --git a/src/Cli/Symfony/DependencyInjection/Configuration.php b/src/Cli/Symfony/DependencyInjection/Configuration.php deleted file mode 100644 index 91e2fbec..00000000 --- a/src/Cli/Symfony/DependencyInjection/Configuration.php +++ /dev/null @@ -1,42 +0,0 @@ - - */ - -namespace Flasher\Cli\Symfony\DependencyInjection; - -use Flasher\Symfony\Bridge\DependencyInjection\FlasherConfiguration; -use Symfony\Component\Config\Definition\Builder\TreeBuilder; - -final class Configuration extends FlasherConfiguration -{ - /** - * @return TreeBuilder - */ - public function getFlasherConfigTreeBuilder() - { - $name = 'flasher_cli'; - - $treeBuilder = new TreeBuilder($name); - - $rootNode = method_exists($treeBuilder, 'getRootNode') - ? $treeBuilder->getRootNode() - : $treeBuilder->root($name); // @phpstan-ignore-line - - $rootNode - ->children() - ->scalarNode('title') - ->defaultValue('PHPFlasher') - ->end() - ->arrayNode('icons') - ->prototype('variable')->end() - ->defaultValue(array()) - ->end() - ->end() - ; - - return $treeBuilder; - } -} diff --git a/src/Cli/Symfony/DependencyInjection/FlasherCliExtension.php b/src/Cli/Symfony/DependencyInjection/FlasherCliExtension.php deleted file mode 100644 index 361a915d..00000000 --- a/src/Cli/Symfony/DependencyInjection/FlasherCliExtension.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ - -namespace Flasher\Cli\Symfony\DependencyInjection; - -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; - -final class FlasherCliExtension extends Extension -{ - /** - * @param array> $configs - * - * @return void - */ - public function load(array $configs, ContainerBuilder $container) - { - $configs = $this->processConfiguration(new Configuration(), $configs); - - $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('services.php'); - - $this->configureNotifier($configs, $container); - } - - /** - * @param array> $configs - * - * @return void - */ - private function configureNotifier(array $configs, ContainerBuilder $container) - { - $notifier = $container->getDefinition('flasher.notify'); - $notifier->replaceArgument(0, $configs['title']); // @phpstan-ignore-line - $notifier->replaceArgument(1, $configs['icons']); // @phpstan-ignore-line - } -} diff --git a/src/Cli/Symfony/FlasherCliSymfonyBundle.php b/src/Cli/Symfony/FlasherCliSymfonyBundle.php deleted file mode 100644 index 7ee4de2c..00000000 --- a/src/Cli/Symfony/FlasherCliSymfonyBundle.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Flasher\Cli\Symfony; - -use Flasher\Cli\Symfony\DependencyInjection\Compiler\NotifierCompilerPass; -use Flasher\Cli\Symfony\DependencyInjection\FlasherCliExtension; -use Flasher\Symfony\Bridge\FlasherBundle; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -class FlasherCliSymfonyBundle extends FlasherBundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - protected function flasherBuild(ContainerBuilder $container) - { - $container->addCompilerPass(new NotifierCompilerPass()); - } - - protected function getFlasherContainerExtension() - { - return new FlasherCliExtension(); - } -} diff --git a/src/Cli/Symfony/LICENSE b/src/Cli/Symfony/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/src/Cli/Symfony/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/src/Cli/Symfony/README.md b/src/Cli/Symfony/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/src/Cli/Symfony/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/src/Cli/Symfony/Resources/config/services.php b/src/Cli/Symfony/Resources/config/services.php deleted file mode 100644 index 9ce841a2..00000000 --- a/src/Cli/Symfony/Resources/config/services.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - -use Flasher\Cli\Prime\Presenter\CliPresenter; -use Flasher\Symfony\Bridge\Bridge; -use Symfony\Component\DependencyInjection\ChildDefinition; -use Symfony\Component\DependencyInjection\DefinitionDecorator; -use Symfony\Component\DependencyInjection\Reference; - -if (!isset($container)) { - return; -} - -/** @var ChildDefinition $definition */ -$definition = class_exists('Symfony\Component\DependencyInjection\ChildDefinition') - ? new ChildDefinition('flasher.notification_factory') - : new DefinitionDecorator('flasher.notification_factory'); // @phpstan-ignore-line - -$definition - ->setClass('Flasher\Cli\Prime\CliFactory') - ->setPublic(true) - ->addTag('flasher.factory', array('alias' => 'cli')); - -$container->setDefinition('flasher.cli', $definition); - -$container->register('flasher.notify', 'Flasher\Cli\Prime\Notify') - ->setPublic(true) - ->addArgument(null) - ->addArgument(array()); - -$container - ->register('flasher.cli.presenter', 'Flasher\Cli\Prime\Presenter\CliPresenter') - ->addArgument(new Reference('flasher.notify')) - ->addTag('flasher.presenter', array('alias' => CliPresenter::NAME)); - -$container - ->register('flasher.cli.render_listener', 'Flasher\Cli\Prime\EventListener\RenderListener') - ->addArgument(new Reference('flasher')) - ->addTag('flasher.event_subscriber', array('priority' => -256)); - -if (Bridge::canLoadAliases()) { - $container->setAlias('Flasher\Cli\Prime\CliFactory', 'flasher.cli'); - $container->setAlias('Flasher\Cli\Prime\Notify', 'flasher.notify'); - $container->setAlias('Flasher\Cli\Prime\NotifyInterface', 'flasher.notify'); -} diff --git a/src/Cli/Symfony/composer.json b/src/Cli/Symfony/composer.json deleted file mode 100644 index e3a21df7..00000000 --- a/src/Cli/Symfony/composer.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "php-flasher/flasher-cli-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "symfony-bundle", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-cli": "^1.15.14", - "php-flasher/flasher-symfony": "^1.15.14" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "autoload": { - "psr-4": { - "Flasher\\Cli\\Symfony\\": "" - } - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/src/Laravel/.github/FUNDING.yml b/src/Laravel/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Laravel/.github/FUNDING.yml +++ b/src/Laravel/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Laravel/.github/workflows/auto_closer.yaml b/src/Laravel/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Laravel/.github/workflows/auto_closer.yaml +++ b/src/Laravel/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Laravel/.phpstorm.meta.php b/src/Laravel/.phpstorm.meta.php index 7633e5db..e9e6bd1c 100644 --- a/src/Laravel/.phpstorm.meta.php +++ b/src/Laravel/.phpstorm.meta.php @@ -6,130 +6,108 @@ override(new \Illuminate\Contracts\Container\Container, map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\Illuminate\Container\Container::makeWith(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\Illuminate\Contracts\Container\Container::get(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\Illuminate\Contracts\Container\Container::make(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\Illuminate\Contracts\Container\Container::makeWith(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\App::get(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\App::make(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\App::makeWith(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\app(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\resolve(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); override(\Psr\Container\ContainerInterface::get(0), map([ '' => '@', 'Flasher\Prime\FlasherInterface' => \Flasher\Prime\Flasher::class, 'flasher' => \Flasher\Prime\Flasher::class, - 'flasher.noty' => \Flasher\Noty\Prime\NotyFactory::class, - 'flasher.notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, - 'flasher.pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class, - 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class, - 'flasher.template' => \Flasher\Prime\Factory\FlasherFactory::class, - 'flasher.toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, + 'flasher.noty' => \Flasher\Noty\Prime\Noty::class, + 'flasher.notyf' => \Flasher\Notyf\Prime\Notyf::class, + 'flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlert::class, + 'flasher.toastr' => \Flasher\Toastr\Prime\Toastr::class, ])); diff --git a/src/Laravel/Bridge/Command/FlasherCommand.php b/src/Laravel/Bridge/Command/FlasherCommand.php deleted file mode 100644 index 9c0a71e0..00000000 --- a/src/Laravel/Bridge/Command/FlasherCommand.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ - -namespace Flasher\Laravel\Bridge\Command; - -use Flasher\Laravel\Support\Laravel; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -$class = Laravel::isVersion('11.0', '>=') - ? 'Flasher\Laravel\Bridge\Typed\Command\FlasherCommand' - : 'Flasher\Laravel\Bridge\Legacy\Command\FlasherCommand'; - -class_alias($class, 'Flasher\Laravel\Bridge\Command\FlasherCommand'); - -if (false) { /** @phpstan-ignore-line */ - abstract class FlasherCommand - { - /** - * @return int - */ - abstract protected function flasherExecute(InputInterface $input, OutputInterface $output); - } -} diff --git a/src/Laravel/Bridge/Legacy/Command/FlasherCommand.php b/src/Laravel/Bridge/Legacy/Command/FlasherCommand.php deleted file mode 100644 index 2e4868d7..00000000 --- a/src/Laravel/Bridge/Legacy/Command/FlasherCommand.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -namespace Flasher\Laravel\Bridge\Legacy\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -abstract class FlasherCommand extends Command -{ - protected function execute(InputInterface $input, OutputInterface $output) - { - return $this->flasherExecute($input, $output); - } - - /** - * @return int - */ - abstract protected function flasherExecute(InputInterface $input, OutputInterface $output); -} diff --git a/src/Laravel/Bridge/Typed/Command/FlasherCommand.php b/src/Laravel/Bridge/Typed/Command/FlasherCommand.php deleted file mode 100644 index 14b7be38..00000000 --- a/src/Laravel/Bridge/Typed/Command/FlasherCommand.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -namespace Flasher\Laravel\Bridge\Typed\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -abstract class FlasherCommand extends Command -{ - protected function execute(InputInterface $input, OutputInterface $output): int - { - return $this->flasherExecute($input, $output); - } - - /** - * @return int - */ - abstract protected function flasherExecute(InputInterface $input, OutputInterface $output); -} diff --git a/src/Laravel/Command/InstallCommand.php b/src/Laravel/Command/InstallCommand.php index 3d4d1917..e573116b 100644 --- a/src/Laravel/Command/InstallCommand.php +++ b/src/Laravel/Command/InstallCommand.php @@ -1,38 +1,40 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Command; -use Flasher\Laravel\Support\ServiceProvider as FlasherServiceProvider; +use Flasher\Laravel\Support\PluginServiceProvider; +use Flasher\Prime\Asset\AssetManagerInterface; use Flasher\Prime\Plugin\PluginInterface; -use Flasher\Laravel\Bridge\Command\FlasherCommand; +use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Facades\App; -use Illuminate\Support\ServiceProvider; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Finder\Finder; -class InstallCommand extends FlasherCommand +final class InstallCommand extends Command { - /** - * @return void - */ - protected function configure() + protected $description = 'Installs all PHPFlasher resources to the public and config directories.'; + + public function __construct(private readonly AssetManagerInterface $assetManager) + { + parent::__construct(); + } + + protected function configure(): void { $this ->setName('flasher:install') ->setDescription('Installs all PHPFlasher resources to the public and config directories.') - ->setHelp('The command copies PHPFlasher assets to public/vendor/flasher/ directory and config files to the config/ directory without overwriting any existing config files.'); + ->setHelp('The command copies PHPFlasher assets to public/vendor/flasher/ directory and config files to the config/ directory without overwriting any existing config files.') + ->addOption('config', 'c', InputOption::VALUE_NONE, 'Publish all config files to the config/packages/ directory.') + ->addOption('symlink', 's', InputOption::VALUE_NONE, 'Symlink PHPFlasher assets instead of copying them.'); } - /** - * @return int - */ - protected function flasherExecute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln(''); $output->writeln(' @@ -49,27 +51,49 @@ class InstallCommand extends FlasherCommand $output->writeln(' INFO Copying PHPFlasher resources...'); $output->writeln(''); - $publicDir = App::publicPath().'/vendor/flasher/'; - $exitCode = 0; + $useSymlinks = (bool) $input->getOption('symlink'); + if ($useSymlinks) { + $output->writeln('Using symlinks to publish assets.'); + } else { + $output->writeln('Copying assets to the public directory.'); + } - foreach (ServiceProvider::publishableProviders() as $provider) { - if (!is_a($provider, 'Flasher\Laravel\Support\ServiceProvider', true)) { + $publishConfig = (bool) $input->getOption('config'); + if ($publishConfig) { + $output->writeln('Publishing configuration files.'); + } + + $publicDir = App::publicPath('/vendor/flasher/'); + + $filesystem = new Filesystem(); + $filesystem->deleteDirectory($publicDir); + $filesystem->makeDirectory($publicDir, recursive: true); + + $files = []; + + $exitCode = self::SUCCESS; + + foreach (array_keys(App::getLoadedProviders()) as $provider) { + if (!is_a($provider, PluginServiceProvider::class, true)) { continue; } - /** @var FlasherServiceProvider $provider */ + /** @var PluginServiceProvider $provider */ $provider = App::getProvider($provider); $plugin = $provider->createPlugin(); $configFile = $provider->getConfigurationFile(); try { - $this->publishAssets($plugin, $publicDir); - $this->publishConfig($plugin, $configFile); + $files[] = $this->publishAssets($plugin, $publicDir, $useSymlinks); + + if ($publishConfig) { + $this->publishConfig($plugin, $configFile); + } $status = sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */); $output->writeln(sprintf(' %s %s', $status, $plugin->getAlias())); } catch (\Exception $e) { - $exitCode = 1; + $exitCode = self::FAILURE; $status = sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */); $output->writeln(sprintf(' %s %s %s', $status, $plugin->getAlias(), $e->getMessage())); } @@ -77,41 +101,62 @@ class InstallCommand extends FlasherCommand $output->writeln(''); - if (0 === $exitCode) { - $output->writeln(' SUCCESS PHPFlasher resources have been successfully installed.'); + if (self::SUCCESS === $exitCode) { + $message = 'PHPFlasher resources have been successfully installed.'; + if ($publishConfig) { + $message .= ' Configuration files have been published.'; + } + if ($useSymlinks) { + $message .= ' Assets were symlinked.'; + } + $output->writeln(" SUCCESS $message"); } else { $output->writeln(' ERROR An error occurred during the installation of PHPFlasher resources.'); } + $this->assetManager->createManifest(array_merge([], ...$files)); + $output->writeln(''); return $exitCode; } /** - * @param string $publicDir - * - * @return void + * @return string[] */ - private function publishAssets(PluginInterface $plugin, $publicDir) + private function publishAssets(PluginInterface $plugin, string $publicDir, bool $useSymlinks): array { $originDir = $plugin->getAssetsDir(); if (!is_dir($originDir)) { - return; + return []; } $filesystem = new Filesystem(); - $filesystem->ensureDirectoryExists($originDir, 0777); - $filesystem->copyDirectory($originDir, $publicDir); + $finder = new Finder(); + $finder->files()->in($originDir); + + $files = []; + + foreach ($finder as $file) { + $relativePath = trim(str_replace($originDir, '', $file->getRealPath()), \DIRECTORY_SEPARATOR); + $targetPath = $publicDir.$relativePath; + + $filesystem->makeDirectory(\dirname($targetPath), recursive: true, force: true); + + if ($useSymlinks) { + $filesystem->link($file->getRealPath(), $targetPath); + } else { + $filesystem->copy($file->getRealPath(), $targetPath); + } + + $files[] = $targetPath; + } + + return $files; } - /** - * @param string $configFile - * - * @return void - */ - private function publishConfig(PluginInterface $plugin, $configFile) + private function publishConfig(PluginInterface $plugin, string $configFile): void { if (!file_exists($configFile)) { return; diff --git a/src/Laravel/Component/FlasherComponent.php b/src/Laravel/Component/FlasherComponent.php index d503defe..f9cb9e11 100644 --- a/src/Laravel/Component/FlasherComponent.php +++ b/src/Laravel/Component/FlasherComponent.php @@ -1,23 +1,25 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Component; use Illuminate\View\Component; -class FlasherComponent extends Component +final class FlasherComponent extends Component { - /** - * {@inheritdoc} - */ + public function __construct(public string $criteria = '', public string $context = '') + { + } + public function render() { - @trigger_error('Since php-flasher/flasher-laravel v1.6.0: Using flasher blade component is deprecated and will be removed in v2.0. PHPFlasher will render notification automatically', \E_USER_DEPRECATED); + /** @var array $criteria */ + $criteria = json_decode($this->criteria, true, 512, \JSON_THROW_ON_ERROR) ?: []; - return ''; + /** @var array $context */ + $context = json_decode($this->context, true, 512, \JSON_THROW_ON_ERROR) ?: []; + + return app('flasher')->render('html', $criteria, $context); } } diff --git a/src/Laravel/Container/LaravelContainer.php b/src/Laravel/Container/LaravelContainer.php deleted file mode 100644 index 76779698..00000000 --- a/src/Laravel/Container/LaravelContainer.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ - -namespace Flasher\Laravel\Container; - -use Flasher\Prime\Container\ContainerInterface; - -final class LaravelContainer implements ContainerInterface -{ - /** - * {@inheritDoc} - */ - public function get($id) - { - return app()->make($id); - } -} diff --git a/src/Laravel/EventListener/LivewireListener.php b/src/Laravel/EventListener/LivewireListener.php new file mode 100644 index 00000000..40b9f549 --- /dev/null +++ b/src/Laravel/EventListener/LivewireListener.php @@ -0,0 +1,75 @@ +shouldSkip($context)) { + return; + } + + /** @var array{envelopes: Envelope[]} $data */ + $data = $this->flasher->render('array', [], $this->createContext()); + + if (\count($data['envelopes']) > 0) { + $this->dispatchNotifications($component, $context, $data); + } + } + + /** + * @param array{envelopes: Envelope[]} $data + */ + private function dispatchNotifications(Component $component, ComponentContext $context, array $data): void + { + $data['context']['livewire'] = [ + 'id' => $component->getId(), + 'name' => $component->getName(), + ]; + + $dispatches = $context->effects['dispatches'] ?? []; + $dispatches[] = ['name' => 'flasher:render', 'params' => $data]; + + $context->addEffect('dispatches', $dispatches); + } + + private function shouldSkip(ComponentContext $context): bool + { + return !$this->livewire->isLivewireRequest() || $context->mounting || isset($context->effects['redirect']); + } + + /** + * @return array + */ + private function createContext(): array + { + /** @var LaravelRequest $request */ + $request = ($this->request)(); + $nonces = $this->cspHandler->getNonces(new Request($request)); + + return [ + 'csp_script_nonce' => $nonces['csp_script_nonce'] ?? null, + 'csp_style_nonce' => $nonces['csp_style_nonce'] ?? null, + ]; + } +} diff --git a/src/Laravel/EventListener/OctaneListener.php b/src/Laravel/EventListener/OctaneListener.php new file mode 100644 index 00000000..273138d8 --- /dev/null +++ b/src/Laravel/EventListener/OctaneListener.php @@ -0,0 +1,18 @@ +sandbox->make('flasher.notification_logger_listener'); + $listener->reset(); + } +} diff --git a/src/Laravel/Facade/Flasher.php b/src/Laravel/Facade/Flasher.php index 8aa18344..581ca2b6 100644 --- a/src/Laravel/Facade/Flasher.php +++ b/src/Laravel/Facade/Flasher.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Facade; @@ -38,9 +35,9 @@ use Illuminate\Support\Facades\Facade; * @method static NotificationBuilder handler(string $handler) * @method static Envelope getEnvelope() */ -class Flasher extends Facade +final class Flasher extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'flasher'; } diff --git a/src/Laravel/FlasherServiceProvider.php b/src/Laravel/FlasherServiceProvider.php index 347e432d..bc324595 100644 --- a/src/Laravel/FlasherServiceProvider.php +++ b/src/Laravel/FlasherServiceProvider.php @@ -1,408 +1,300 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel; -use Flasher\Laravel\Container\LaravelContainer; +use Flasher\Laravel\Command\InstallCommand; +use Flasher\Laravel\Component\FlasherComponent; +use Flasher\Laravel\EventListener\LivewireListener; +use Flasher\Laravel\EventListener\OctaneListener; use Flasher\Laravel\Middleware\FlasherMiddleware; -use Flasher\Laravel\Middleware\HttpKernelFlasherMiddleware; -use Flasher\Laravel\Middleware\HttpKernelSessionMiddleware; use Flasher\Laravel\Middleware\SessionMiddleware; use Flasher\Laravel\Storage\SessionBag; -use Flasher\Laravel\Support\Laravel; -use Flasher\Laravel\Support\ServiceProvider; +use Flasher\Laravel\Support\PluginServiceProvider; use Flasher\Laravel\Template\BladeTemplateEngine; use Flasher\Laravel\Translation\Translator; -use Flasher\Prime\Config\Config; -use Flasher\Prime\Config\ConfigInterface; +use Flasher\Prime\Asset\AssetManager; use Flasher\Prime\Container\FlasherContainer; use Flasher\Prime\EventDispatcher\EventDispatcher; -use Flasher\Prime\EventDispatcher\EventListener\PresetListener; +use Flasher\Prime\EventDispatcher\EventListener\ApplyPresetListener; +use Flasher\Prime\EventDispatcher\EventListener\NotificationLoggerListener; use Flasher\Prime\EventDispatcher\EventListener\TranslationListener; +use Flasher\Prime\Factory\NotificationFactoryLocator; use Flasher\Prime\Flasher; use Flasher\Prime\FlasherInterface; +use Flasher\Prime\Http\Csp\ContentSecurityPolicyHandler; +use Flasher\Prime\Http\Csp\NonceGenerator; use Flasher\Prime\Http\RequestExtension; use Flasher\Prime\Http\ResponseExtension; -use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Plugin\FlasherPlugin; use Flasher\Prime\Response\Resource\ResourceManager; use Flasher\Prime\Response\ResponseManager; -use Flasher\Prime\Storage\StorageBag; +use Flasher\Prime\Storage\Filter\FilterFactory; +use Flasher\Prime\Storage\Storage; use Flasher\Prime\Storage\StorageManager; -use Illuminate\Contracts\Config\Repository; +use Illuminate\Container\Container; +use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Foundation\Application; -use Illuminate\Foundation\Http\Kernel; -use Illuminate\Routing\Router; -use Illuminate\Support\Facades\Blade; -use Livewire\Component; +use Illuminate\Foundation\Console\AboutCommand; +use Illuminate\Foundation\Http\Kernel as HttpKernel; +use Illuminate\View\Compilers\BladeCompiler; +use Laravel\Octane\Events\RequestReceived; use Livewire\LivewireManager; -use Livewire\Mechanisms\HandleComponents\ComponentContext; -use Livewire\Response; -/** - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -final class FlasherServiceProvider extends ServiceProvider +final class FlasherServiceProvider extends PluginServiceProvider { - /** - * {@inheritdoc} - */ - public function afterBoot() + public function register(): void { - FlasherContainer::init(new LaravelContainer()); + $this->plugin = $this->createPlugin(); - $this->registerCommands(); - $this->registerBladeDirective(); - $this->registerBladeComponent(); - $this->registerLivewire(); - $this->registerTranslations(); - $this->registerMiddlewares(); + $this->registerConfiguration(); + $this->registerFlasher(); + $this->registerFactoryLocator(); + $this->registerResponseManager(); + $this->registerTemplateEngine(); + $this->registerResourceManager(); + $this->registerStorageManager(); + $this->registerEventDispatcher(); + $this->registerCspHandler(); + $this->registerAssetManager(); } - /** - * @{@inheritdoc} - */ - public function createPlugin() + public function boot(): void + { + FlasherContainer::from(static fn () => Container::getInstance()); + + $this->registerCommands(); + $this->loadTranslationsFrom(__DIR__.'/Translation/lang', 'flasher'); + $this->registerMiddlewares(); + $this->callAfterResolving('blade.compiler', $this->registerBladeDirectives(...)); + $this->registerLivewire(); + } + + public function createPlugin(): FlasherPlugin { return new FlasherPlugin(); } - /** - * {@inheritdoc} - */ - protected function afterRegister() + private function registerFlasher(): void { - $this->registerConfig(); - $this->registerFlasher(); - $this->registerResourceManager(); - $this->registerResponseManager(); - $this->registerStorageManager(); - $this->registerEventDispatcher(); - } - - /** - * @return void - */ - private function registerCommands() - { - if (!in_array(\PHP_SAPI, array('cli', 'phpdbg'))) { - return; - } - - $this->commands(array( - 'Flasher\Laravel\Command\InstallCommand', // flasher:install - )); - } - - /** - * @return void - */ - private function registerConfig() - { - $this->app->singleton('flasher.config', function (Application $app) { - /** @var Repository $config */ + $this->app->singleton('flasher', static function (Application $app) { $config = $app->make('config'); - return new Config($config->get('flasher', array())); // @phpstan-ignore-line - }); - } - - /** - * @return void - */ - private function registerFlasher() - { - $this->app->singleton('flasher', function (Application $app) { - $config = $app->make('flasher.config'); + $default = $config->get('flasher.default'); + $factoryLocator = $app->make('flasher.factory_locator'); $responseManager = $app->make('flasher.response_manager'); $storageManager = $app->make('flasher.storage_manager'); - return new Flasher($config->get('default'), $responseManager, $storageManager); // @phpstan-ignore-line + return new Flasher($default, $factoryLocator, $responseManager, $storageManager); }); - $this->app->alias('flasher', 'Flasher\Prime\Flasher'); - $this->app->bind('Flasher\Prime\FlasherInterface', 'flasher'); + + $this->app->alias('flasher', Flasher::class); + $this->app->bind(FlasherInterface::class, 'flasher'); } - /** - * @return void - */ - private function registerResourceManager() + private function registerFactoryLocator(): void { - $this->app->singleton('flasher.resource_manager', function (Application $app) { - $config = $app->make('flasher.config'); - $view = $app->make('view'); - - return new ResourceManager($config, new BladeTemplateEngine($view)); // @phpstan-ignore-line + $this->app->singleton('flasher.factory_locator', static function () { + return new NotificationFactoryLocator(); }); } - /** - * @return void - */ - private function registerResponseManager() + private function registerResponseManager(): void { - $this->app->singleton('flasher.response_manager', function (Application $app) { + $this->app->singleton('flasher.response_manager', static function (Application $app) { $resourceManager = $app->make('flasher.resource_manager'); $storageManager = $app->make('flasher.storage_manager'); $eventDispatcher = $app->make('flasher.event_dispatcher'); - return new ResponseManager($resourceManager, $storageManager, $eventDispatcher); // @phpstan-ignore-line + return new ResponseManager($resourceManager, $storageManager, $eventDispatcher); }); } - /** - * @return void - */ - private function registerStorageManager() + private function registerTemplateEngine(): void { - $this->app->singleton('flasher.storage_manager', function (Application $app) { - $config = $app->make('flasher.config'); + $this->app->singleton('flasher.template_engine', static function (Application $app) { + $viewFactory = $app->make('view'); + + return new BladeTemplateEngine($viewFactory); + }); + } + + private function registerResourceManager(): void + { + $this->app->singleton('flasher.resource_manager', static function (Application $app) { + $config = $app->make('config'); + + $templateEngine = $app->make('flasher.template_engine'); + $assetManager = $app->make('flasher.asset_manager'); + $mainScript = $config->get('flasher.main_script'); + $resources = $config->get('flasher.plugins'); + + return new ResourceManager($templateEngine, $assetManager, $mainScript, $resources); + }); + } + + private function registerStorageManager(): void + { + $this->app->singleton('flasher.storage_manager', static function (Application $app) { + $config = $app->make('config'); + + $storageBag = new Storage(new SessionBag($app->make('session'))); $eventDispatcher = $app->make('flasher.event_dispatcher'); - $session = $app->make('session'); + $filterFactory = new FilterFactory(); + $criteria = $config->get('flasher.filter'); - /** @phpstan-ignore-next-line */ - $storageBag = new StorageBag(new SessionBag($session)); - - $criteria = $config->get('filter_criteria', array()); // @phpstan-ignore-line - - return new StorageManager($storageBag, $eventDispatcher, $criteria); // @phpstan-ignore-line + return new StorageManager($storageBag, $eventDispatcher, $filterFactory, $criteria); }); } - /** - * @return void - */ - private function registerEventDispatcher() + private function registerEventDispatcher(): void { - $this->app->singleton('flasher.event_dispatcher', function (Application $app) { + $this->app->singleton('flasher.notification_logger_listener', fn () => new NotificationLoggerListener()); + + $this->app->singleton('flasher.event_dispatcher', static function (Application $app) { + $config = $app->make('config'); + $eventDispatcher = new EventDispatcher(); - $config = $app->make('flasher.config'); - /** @phpstan-ignore-next-line */ - $translator = new Translator($app->make('translator')); + $translatorListener = new TranslationListener(new Translator($app->make('translator'))); + $eventDispatcher->addListener($translatorListener); - /** @phpstan-ignore-next-line */ - $autoTranslate = $config->get('auto_translate', true); + $presetListener = new ApplyPresetListener($config->get('flasher.presets')); + $eventDispatcher->addListener($presetListener); - $translatorListener = new TranslationListener($translator, $autoTranslate); - $eventDispatcher->addSubscriber($translatorListener); - - $presetListener = new PresetListener($config->get('presets', array())); // @phpstan-ignore-line - $eventDispatcher->addSubscriber($presetListener); + $eventDispatcher->addListener($app->make('flasher.notification_logger_listener')); return $eventDispatcher; }); - } - /** - * @return void - */ - private function registerTranslations() - { - /** @var \Illuminate\Translation\Translator $translator */ - $translator = $this->app->make('translator'); - $translator->addNamespace('flasher', __DIR__.'/Translation/lang'); - } - - /** - * @return void - */ - private function registerLivewire() - { - if (!$this->app->bound('livewire')) { - return; - } - - $livewire = $this->app->make('livewire'); - if (!$livewire instanceof LivewireManager) { - return; - } - - // Livewire v3 - if (method_exists($livewire, 'componentHook')) { - $livewire->listen('dehydrate', function (Component $component, ComponentContext $context) { - if ($context->mounting || isset($context->effects['redirect'])) { - return; - } - - /** @var FlasherInterface $flasher */ - $flasher = app('flasher'); - - /** @var array{envelopes: Envelope[]} $data */ - $data = $flasher->render(array(), 'array'); - - if (\count($data['envelopes']) > 0) { - $data['context']['livewire'] = array( - 'id' => $component->getId(), - 'name' => $component->getName(), - ); - - $dispatches = isset($context->effects['dispatches']) ? $context->effects['dispatches'] : []; - $dispatches[] = array('name' => 'flasher:render', 'params' => $data); - - $context->addEffect('dispatches', $dispatches); - } - }); - - return; - } - - $livewire->listen('component.dehydrate.subsequent', function (Component $component, Response $response) { - if (isset($response->effects['redirect'])) { - return; - } - - /** @var FlasherInterface $flasher */ - $flasher = app('flasher'); - - /** @var array{envelopes: Envelope[]} $data */ - $data = $flasher->render(array(), 'array'); - - if (\count($data['envelopes']) > 0) { - $data['context']['livewire'] = array( - 'id' => $component->id, - 'name' => $response->fingerprint['name'], - ); - - $response->effects['dispatches'][] = array( - 'event' => 'flasher:render', - 'data' => $data, - ); - } + $this->callAfterResolving(Dispatcher::class, function (Dispatcher $dispatcher) { + $dispatcher->listen(RequestReceived::class, OctaneListener::class); }); } - /** - * @return void - */ - private function registerBladeDirective() + private function registerCommands(): void { - Blade::extend(function ($view) { - $pattern = '/(?app->runningInConsole()) { return; } - Blade::component('flasher', 'Flasher\Laravel\Component\FlasherComponent'); + $this->registerAboutCommand(); + + $this->app->singleton(InstallCommand::class, static function (Application $app) { + $assetManager = $app->make('flasher.asset_manager'); + + return new InstallCommand($assetManager); + }); + + $this->commands(InstallCommand::class); } - /** - * @return void - */ - private function registerMiddlewares() + private function registerAboutCommand(): void + { + if (!class_exists(AboutCommand::class)) { + return; + } + + $pluginServiceProviders = array_filter(array_keys($this->app->getLoadedProviders()), function ($provider) { + return is_a($provider, PluginServiceProvider::class, true); + }); + + $factories = array_map(function ($providerClass) { + /** @var PluginServiceProvider $provider */ + $provider = $this->app->getProvider($providerClass); + $plugin = $provider->createPlugin(); + + return $plugin->getAlias(); + }, $pluginServiceProviders); + + AboutCommand::add('PHPFlasher', [ + 'Version' => Flasher::VERSION, + 'Factories' => implode(' / ', array_map(fn ($factory) => sprintf('%s', $factory), $factories)), + ]); + } + + private function registerMiddlewares(): void { $this->registerSessionMiddleware(); $this->registerFlasherMiddleware(); } - /** - * @return void - */ - private function registerFlasherMiddleware() + private function registerFlasherMiddleware(): void { - /** @var ConfigInterface $config */ - $config = $this->app->make('flasher.config'); - - if (!$config->get('auto_render', true)) { - return; - } - - $this->app->singleton('Flasher\Laravel\Middleware\FlasherMiddleware', function (Application $app) { - /** @var FlasherInterface $flasher */ + $this->app->singleton(FlasherMiddleware::class, static function (Application $app) { $flasher = $app->make('flasher'); + $cspHandler = $app->make('flasher.csp_handler'); - return new FlasherMiddleware(new ResponseExtension($flasher)); + return new FlasherMiddleware(new ResponseExtension($flasher, $cspHandler)); }); - $this->appendMiddlewareToWebGroup('Flasher\Laravel\Middleware\FlasherMiddleware'); - - if (method_exists($this->app, 'middleware')) { - $this->app->middleware(new HttpKernelFlasherMiddleware($this->app)); // @phpstan-ignore-line - } + $this->pushMiddlewareToGroup(FlasherMiddleware::class); } - /** - * @return void - */ - private function registerSessionMiddleware() + private function registerCspHandler(): void { - /** @var ConfigInterface $config */ - $config = $this->app->make('flasher.config'); + $this->app->singleton('flasher.csp_handler', static function () { + return new ContentSecurityPolicyHandler(new NonceGenerator()); + }); + } - if (!$config->get('flash_bag.enabled', true)) { - return; - } + private function registerAssetManager(): void + { + $this->app->singleton('flasher.asset_manager', static function () { + $publicDir = public_path('/'); + $manifestPath = public_path('vendor'.\DIRECTORY_SEPARATOR.'flasher'.\DIRECTORY_SEPARATOR.'manifest.json'); + + return new AssetManager($publicDir, $manifestPath); + }); + } + + private function registerSessionMiddleware(): void + { + $this->app->singleton(SessionMiddleware::class, static function (Application $app) { + $config = $app->make('config'); - $this->app->singleton('Flasher\Laravel\Middleware\SessionMiddleware', function (Application $app) { - /** @var ConfigInterface $config */ - $config = $app->make('flasher.config'); - $mapping = $config->get('flash_bag.mapping', array()); $flasher = $app->make('flasher'); + $mapping = $config->get('flasher.flash_bag', []); - return new SessionMiddleware(new RequestExtension($flasher, $mapping)); // @phpstan-ignore-line + return new SessionMiddleware(new RequestExtension($flasher, $mapping)); }); - $this->appendMiddlewareToWebGroup('Flasher\Laravel\Middleware\SessionMiddleware'); - - if (method_exists($this->app, 'middleware')) { - $this->app->middleware(new HttpKernelSessionMiddleware($this->app)); // @phpstan-ignore-line - } + $this->pushMiddlewareToGroup(SessionMiddleware::class); } - /** - * @param string $middleware - * - * @return void - */ - private function appendMiddlewareToWebGroup($middleware) + private function pushMiddlewareToGroup(string $middleware): void { - if (!$this->app->bound($middleware)) { - return; - } - - /** @var Router $router */ - $router = $this->app->make('router'); - if (method_exists($router, 'pushMiddlewareToGroup')) { - $router->pushMiddlewareToGroup('web', $middleware); - - return; - } - - if (!$this->app->bound('Illuminate\Contracts\Http\Kernel')) { - return; - } - - /** @var Kernel $kernel */ - $kernel = $this->app->make('Illuminate\Contracts\Http\Kernel'); - - if (method_exists($kernel, 'appendMiddlewareToGroup')) { + $this->callAfterResolving(HttpKernel::class, function (HttpKernel $kernel) use ($middleware) { $kernel->appendMiddlewareToGroup('web', $middleware); + }); + } + private function registerBladeDirectives(BladeCompiler $blade): void + { + $blade->directive('flasher_render', function (string $expression = '') { + if (!empty($expression) && str_starts_with($expression, '(') && str_ends_with($expression, ')')) { + $expression = substr($expression, 1, -1); + } + + return "render('html', $expression); ?>"; + }); + + $blade->component(FlasherComponent::class, 'flasher'); + } + + private function registerLivewire(): void + { + if (class_exists(LivewireManager::class) && !$this->app->bound('livewire')) { return; } - if (method_exists($kernel, 'pushMiddleware')) { - $kernel->pushMiddleware($middleware); - } + $this->callAfterResolving('livewire', function (LivewireManager $livewire, Application $app) { + $flasher = $app->make('flasher'); + $cspHandler = $app->make('flasher.csp_handler'); + $request = fn () => $app->make('request'); + + $livewire->listen('dehydrate', new LivewireListener($livewire, $flasher, $cspHandler, $request)); + }); } } diff --git a/src/Laravel/Http/Request.php b/src/Laravel/Http/Request.php index 6ab0c6cf..5c86804d 100644 --- a/src/Laravel/Http/Request.php +++ b/src/Laravel/Http/Request.php @@ -1,78 +1,88 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Http; use Flasher\Prime\Http\RequestInterface; +use Illuminate\Contracts\Session\Session; use Illuminate\Http\Request as LaravelRequest; -final class Request implements RequestInterface +final readonly class Request implements RequestInterface { - /** - * @var LaravelRequest - */ - private $request; - - public function __construct(LaravelRequest $request) + public function __construct(private LaravelRequest $request) { - $this->request = $request; } - /** - * {@inheritDoc} - */ - public function isXmlHttpRequest() + public function isXmlHttpRequest(): bool { return $this->request->ajax(); } - /** - * {@inheritDoc} - */ - public function isHtmlRequestFormat() + public function isHtmlRequestFormat(): bool { - return 'html' === $this->request->getRequestFormat(); + return $this->request->acceptsHtml(); } - /** - * {@inheritDoc} - */ - public function hasSession() + public function hasSession(): bool { return $this->request->hasSession(); } - /** - * {@inheritDoc} - */ - public function hasType($type) + public function isSessionStarted(): bool { - $session = $this->request->session(); + $session = $this->getSession(); - return $session->has($type); + return $session?->isStarted() ?: false; } - /** - * {@inheritDoc} - */ - public function getType($type) + public function hasType(string $type): bool { - $session = $this->request->session(); + if (!$this->hasSession() || !$this->isSessionStarted()) { + return false; + } - return $session->get($type); // @phpstan-ignore-line + $session = $this->getSession(); + + return $session?->has($type) ?: false; } - /** - * {@inheritDoc} - */ - public function forgetType($type) + public function getType(string $type): string|array { - $session = $this->request->session(); + $session = $this->getSession(); - $session->forget($type); + $type = $session?->get($type); + + if (!\is_string($type) && !\is_array($type)) { + return []; + } + + return $type; + } + + public function forgetType(string $type): void + { + $session = $this->getSession(); + + $session?->forget($type); + } + + private function getSession(): ?Session + { + try { + return $this->request->session(); + } catch (\RuntimeException) { + return null; + } + } + + public function hasHeader(string $key): bool + { + return $this->request->headers->has($key); + } + + public function getHeader(string $key): ?string + { + return $this->request->headers->get($key); } } diff --git a/src/Laravel/Http/Response.php b/src/Laravel/Http/Response.php index 20ea091f..68a8bff0 100644 --- a/src/Laravel/Http/Response.php +++ b/src/Laravel/Http/Response.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Http; @@ -11,72 +8,58 @@ use Flasher\Prime\Http\ResponseInterface; use Illuminate\Http\JsonResponse as LaravelJsonResponse; use Illuminate\Http\Response as LaravelResponse; -final class Response implements ResponseInterface +final readonly class Response implements ResponseInterface { - /** - * @var LaravelJsonResponse|LaravelResponse - */ - private $response; - - /** - * @param LaravelJsonResponse|LaravelResponse $response - */ - public function __construct($response) + public function __construct(private LaravelJsonResponse|LaravelResponse $response) { - $this->response = $response; } - /** - * {@inheritDoc} - */ - public function isRedirection() + public function isRedirection(): bool { return $this->response->isRedirection(); } - /** - * {@inheritDoc} - */ - public function isJson() + public function isJson(): bool { return $this->response instanceof LaravelJsonResponse; } - /** - * {@inheritDoc} - */ - public function isHtml() + public function isHtml(): bool { $contentType = $this->response->headers->get('Content-Type'); - return false !== stripos($contentType, 'html'); // @phpstan-ignore-line + if (!\is_string($contentType)) { + return false; + } + + return false !== stripos($contentType, 'html'); } - /** - * {@inheritDoc} - */ - public function isAttachment() + public function isAttachment(): bool { $contentDisposition = $this->response->headers->get('Content-Disposition', ''); - return false !== stripos($contentDisposition, 'attachment;'); // @phpstan-ignore-line + if (!\is_string($contentDisposition)) { + return false; + } + + return false !== stripos($contentDisposition, 'attachment;'); } - /** - * {@inheritDoc} - */ - public function getContent() + public function isSuccessful(): bool { - return $this->response->getContent(); // @phpstan-ignore-line + return $this->response->isSuccessful(); } - /** - * {@inheritDoc} - */ - public function setContent($content) + public function getContent(): string + { + return $this->response->getContent() ?: ''; + } + + public function setContent(string $content): void { $original = null; - if ($this->response instanceof \Illuminate\Http\Response && $this->response->getOriginalContent()) { + if ($this->response instanceof LaravelResponse && $this->response->getOriginalContent()) { $original = $this->response->getOriginalContent(); } @@ -87,4 +70,24 @@ final class Response implements ResponseInterface $this->response->original = $original; } } + + public function hasHeader(string $key): bool + { + return $this->response->headers->has($key); + } + + public function getHeader(string $key): ?string + { + return $this->response->headers->get($key); + } + + public function setHeader(string $key, array|string|null $values): void + { + $this->response->headers->set($key, $values); + } + + public function removeHeader(string $key): void + { + $this->response->headers->remove($key); + } } diff --git a/src/Laravel/LICENSE b/src/Laravel/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Laravel/LICENSE +++ b/src/Laravel/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Laravel/Middleware/FlasherMiddleware.php b/src/Laravel/Middleware/FlasherMiddleware.php index 38c7184c..dc5fcdf5 100644 --- a/src/Laravel/Middleware/FlasherMiddleware.php +++ b/src/Laravel/Middleware/FlasherMiddleware.php @@ -1,39 +1,29 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Middleware; use Flasher\Laravel\Http\Request; use Flasher\Laravel\Http\Response; -use Flasher\Prime\Http\ResponseExtension; +use Flasher\Prime\Http\ResponseExtensionInterface; +use Illuminate\Http\JsonResponse as LaravelJsonResponse; use Illuminate\Http\Request as LaravelRequest; use Illuminate\Http\Response as LaravelResponse; -final class FlasherMiddleware +final readonly class FlasherMiddleware { - /** - * @var ResponseExtension - */ - private $responseExtension; - - public function __construct(ResponseExtension $responseExtension) + public function __construct(private ResponseExtensionInterface $responseExtension) { - $this->responseExtension = $responseExtension; } - /** - * @return LaravelResponse - */ - public function handle(LaravelRequest $request, \Closure $next) + public function handle(LaravelRequest $request, \Closure $next): mixed { - /** @var LaravelResponse $response */ $response = $next($request); - $this->responseExtension->render(new Request($request), new Response($response)); + if ($response instanceof LaravelJsonResponse || $response instanceof LaravelResponse) { + $this->responseExtension->render(new Request($request), new Response($response)); + } return $response; } diff --git a/src/Laravel/Middleware/HttpKernelFlasherMiddleware.php b/src/Laravel/Middleware/HttpKernelFlasherMiddleware.php deleted file mode 100644 index 5fb8e63c..00000000 --- a/src/Laravel/Middleware/HttpKernelFlasherMiddleware.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace Flasher\Laravel\Middleware; - -use Illuminate\Http\Request; -use Symfony\Component\HttpFoundation\Request as SymfonyRequest; -use Symfony\Component\HttpKernel\HttpKernelInterface; - -final class HttpKernelFlasherMiddleware implements HttpKernelInterface -{ - /** - * @var \Symfony\Component\HttpKernel\HttpKernelInterface - */ - private $app; - - public function __construct(HttpKernelInterface $app) - { - $this->app = $app; - } - - public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) - { - $response = $this->app->handle($request, $type, $catch); - - $request = Request::createFromBase($request); - $next = function () use ($response) { - return $response; - }; - - /** @var SessionMiddleware $sessionMiddleware */ - $sessionMiddleware = $this->app->make('Flasher\Laravel\Middleware\FlasherMiddleware'); - - return $sessionMiddleware->handle($request, $next); - } -} diff --git a/src/Laravel/Middleware/HttpKernelSessionMiddleware.php b/src/Laravel/Middleware/HttpKernelSessionMiddleware.php deleted file mode 100644 index 96cf73b8..00000000 --- a/src/Laravel/Middleware/HttpKernelSessionMiddleware.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace Flasher\Laravel\Middleware; - -use Illuminate\Http\Request; -use Symfony\Component\HttpFoundation\Request as SymfonyRequest; -use Symfony\Component\HttpKernel\HttpKernelInterface; - -final class HttpKernelSessionMiddleware implements HttpKernelInterface -{ - /** - * @var \Symfony\Component\HttpKernel\HttpKernelInterface - */ - private $app; - - public function __construct(HttpKernelInterface $app) - { - $this->app = $app; - } - - public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) - { - $response = $this->app->handle($request, $type, $catch); - - $request = Request::createFromBase($request); - $next = function () use ($response) { - return $response; - }; - - /** @var SessionMiddleware $sessionMiddleware */ - $sessionMiddleware = $this->app->make('Flasher\Laravel\Middleware\SessionMiddleware'); - - return $sessionMiddleware->handle($request, $next); - } -} diff --git a/src/Laravel/Middleware/SessionMiddleware.php b/src/Laravel/Middleware/SessionMiddleware.php index 5340ab1d..91635d03 100644 --- a/src/Laravel/Middleware/SessionMiddleware.php +++ b/src/Laravel/Middleware/SessionMiddleware.php @@ -1,39 +1,29 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Middleware; use Flasher\Laravel\Http\Request; use Flasher\Laravel\Http\Response; -use Flasher\Prime\Http\RequestExtension; +use Flasher\Prime\Http\RequestExtensionInterface; +use Illuminate\Http\JsonResponse as LaravelJsonResponse; use Illuminate\Http\Request as LaravelRequest; use Illuminate\Http\Response as LaravelResponse; -final class SessionMiddleware +final readonly class SessionMiddleware { - /** - * @var RequestExtension - */ - private $requestExtension; - - public function __construct(RequestExtension $requestExtension) + public function __construct(private RequestExtensionInterface $requestExtension) { - $this->requestExtension = $requestExtension; } - /** - * @return LaravelResponse - */ - public function handle(LaravelRequest $request, \Closure $next) + public function handle(LaravelRequest $request, \Closure $next): mixed { - /** @var LaravelResponse $response */ $response = $next($request); - $this->requestExtension->flash(new Request($request), new Response($response)); + if ($response instanceof LaravelJsonResponse || $response instanceof LaravelResponse) { + $this->requestExtension->flash(new Request($request), new Response($response)); + } return $response; } diff --git a/src/Laravel/Phpstan/stubs/ApplicationTestingHooks.stub b/src/Laravel/Phpstan/stubs/ApplicationTestingHooks.stub new file mode 100644 index 00000000..88b01d85 --- /dev/null +++ b/src/Laravel/Phpstan/stubs/ApplicationTestingHooks.stub @@ -0,0 +1,11 @@ +, + * filter: array, + * flash_bag: array, + * presets: array, + * plugins: array, + * } + * + * @phpstan-type PresetType array{ + * type: string, + * title: string, + * message: string, + * options: array, + * } + * + * @phpstan-type PluginType array{ + * scripts?: string[], + * styles?: string[], + * options?: array, + * } + */ +interface Repository +{ + /** + * @param string[]|string $key + * + * @phpstan-return ($key is 'flasher' ? ConfigType : + * ($key is 'flasher.default' ? string : + * ($key is 'flasher.main_script' ? string : + * ($key is 'flasher.filter' ? array : + * ($key is 'flasher.presets' ? array : + * ($key is 'flasher.plugins' ? array : + * ($key is 'flasher.flash_bag' ? array : + * mixed))))))) + */ + public function get(string|array $key, mixed $default = null): mixed; +} diff --git a/src/Laravel/README.md b/src/Laravel/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Laravel/README.md +++ b/src/Laravel/README.md @@ -36,7 +36,7 @@ Shining stars of our community: - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Laravel/Resources/config.php b/src/Laravel/Resources/config.php index 91ea00b0..2c78c3e2 100644 --- a/src/Laravel/Resources/config.php +++ b/src/Laravel/Resources/config.php @@ -1,193 +1,38 @@ - */ +declare(strict_types=1); -return array( - /* - |--------------------------------------------------------------------------- - | Default PHPFlasher library - |--------------------------------------------------------------------------- - | This option controls the default library that will be used by PHPFlasher - | to display notifications in your Laravel application. PHPFlasher supports - | several libraries, including "flasher", "toastr", "noty", "notyf", - | "sweetalert" and "pnotify". - | - | The "flasher" library is used by default. If you want to use a different - | library, you will need to install it using composer. For example, to use - | the "toastr" library, run the following command: - | composer require php-flasher/flasher-toastr-laravel - | - | Here is a list of the supported libraries and the corresponding composer - | commands to install them: - | - | "toastr" : composer require php-flasher/flasher-toastr-laravel - | "noty" : composer require php-flasher/flasher-noty-laravel - | "notyf" : composer require php-flasher/flasher-notyf-laravel - | "sweetalert" : composer require php-flasher/flasher-sweetalert-laravel - | "pnotify" : composer require php-flasher/flasher-pnotify-laravel - */ +namespace Flasher\Laravel\Resources; + +return [ + // Default notification library (e.g., 'flasher', 'toastr', 'noty', etc.) 'default' => 'flasher', - /* - |--------------------------------------------------------------------------- - | Main PHPFlasher javascript file - |--------------------------------------------------------------------------- - | This option specifies the location of the main javascript file that is - | required by PHPFlasher to display notifications in your Laravel application. - | - | By default, PHPFlasher uses a CDN to serve the latest version of the library. - | However, you can also choose to download the library locally or install it - | using npm. - | - | To use the local version of the library, run the following command: - | php artisan flasher:install - | - | This will copy the necessary assets to your application's public folder. - | You can then specify the local path to the javascript file in the 'local' - | field of this option. - */ - 'root_script' => array( - 'cdn' => 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.js', - 'local' => '/vendor/flasher/flasher.min.js', - ), + // Path to the main JavaScript file of PHPFlasher + 'main_script' => '/vendor/flasher/flasher.min.js', - /* - |--------------------------------------------------------------------------- - | PHPFlasher Stylesheet - |--------------------------------------------------------------------------- - | This option specifies the location of the stylesheet file that is - | required by PHPFlasher to style the notifications in your Laravel application. - | - | By default, PHPFlasher uses a CDN to serve the latest version of the stylesheet. - | However, you can also choose to download the stylesheet locally or include it - | from your assets. - | - | To use the local version of the stylesheet, make sure you have the necessary - | assets in your application's public folder. Then specify the local path to - | the stylesheet file in the 'local' field of this option. - */ - 'styles' => array( - 'cdn' => 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.css', - 'local' => '/vendor/flasher/flasher.min.css', - ), + // Path to the stylesheets for PHPFlasher notifications + 'styles' => [ + '/vendor/flasher/flasher.min.css', + ], - /* - |--------------------------------------------------------------------------- - | Whether to use CDN for PHPFlasher assets or not - |--------------------------------------------------------------------------- - | This option controls whether PHPFlasher should use CDN links or local assets - | for its javascript and CSS files. By default, PHPFlasher uses CDN links - | to serve the latest version of the library. However, you can also choose - | to use local assets by setting this option to 'false'. - | - | If you decide to use local assets, don't forget to publish the necessary - | files to your application's public folder by running the following command: - | php artisan flasher:install - | - | This will copy the necessary assets to your application's public folder. - */ - 'use_cdn' => true, + // Whether to translate PHPFlasher messages using Laravel's translation service + 'translate' => true, - /* - |--------------------------------------------------------------------------- - | Translate PHPFlasher messages - |--------------------------------------------------------------------------- - | This option controls whether PHPFlasher should pass its messages to the Laravel's - | translation service for localization. - | - | By default, this option is set to 'true', which means that PHPFlasher will - | attempt to translate its messages using the translation service. - | - | If you don't want PHPFlasher to use the Laravel's translation service, you can - | set this option to 'false'. In this case, PHPFlasher will use the messages - | as-is, without attempting to translate them. - */ - 'auto_translate' => true, + // Automatically inject PHPFlasher assets into HTML response + 'inject_assets' => true, - /* - |--------------------------------------------------------------------------- - | Inject PHPFlasher in Response - |--------------------------------------------------------------------------- - | This option controls whether PHPFlasher should automatically inject its - | javascript and CSS files into the HTML response of your Laravel application. - | - | By default, this option is set to 'true', which means that PHPFlasher will - | listen to the response of your application and automatically insert its - | scripts and stylesheets into the HTML before the closing `` tag. - | - | If you don't want PHPFlasher to automatically inject its scripts and stylesheets - | into the response, you can set this option to 'false'. In this case, you will - | need to manually include the necessary files in your application's layout. - */ - 'auto_render' => true, + // Configuration for the flash bag (converting Laravel flash messages) + // Map Laravel session keys to PHPFlasher types + 'flash_bag' => [ + 'success' => ['success'], + 'error' => ['error', 'danger'], + 'warning' => ['warning', 'alarm'], + 'info' => ['info', 'notice', 'alert'], + ], - 'flash_bag' => array( - /* - |----------------------------------------------------------------------- - | Enable flash bag - |----------------------------------------------------------------------- - | This option controls whether PHPFlasher should automatically convert - | Laravel's flash messages to PHPFlasher notifications. This feature is - | useful when you want to migrate from a legacy system or another - | library that uses similar conventions for flash messages. - | - | When this option is set to 'true', PHPFlasher will check for flash - | messages in the session and convert them to notifications using the - | mapping specified in the 'mapping' option. When this option is set - | to 'false', PHPFlasher will ignore flash messages in the session. - */ - 'enabled' => true, - - /* - |----------------------------------------------------------------------- - | Flash bag type mapping - |----------------------------------------------------------------------- - | This option allows you to map or convert session keys to PHPFlasher - | notification types. On the left side are the PHPFlasher types. - | On the right side are the Laravel session keys that you want to - | convert to PHPFlasher types. - | - | For example, if you want to convert Laravel's 'danger' flash - | messages to PHPFlasher's 'error' notifications, you can add - | the following entry to the mapping: - | 'error' => ['danger'], - */ - 'mapping' => array( - 'success' => array('success'), - 'error' => array('error', 'danger'), - 'warning' => array('warning', 'alarm'), - 'info' => array('info', 'notice', 'alert'), - ), - ), - - /* - |--------------------------------------------------------------------------- - | Global Filter Criteria - |--------------------------------------------------------------------------- - | This option allows you to filter the notifications that are displayed - | in your Laravel application. By default, all notifications are displayed, - | but you can use this option to limit the number of notifications or - | filter them by type. - | - | For example, to limit the number of notifications to 5, you can set - | the 'limit' field to 5: - | 'limit' => 5, - | - | To filter the notifications by type, you can specify an array of - | types that you want to display. For example, to only display - | error notifications, you can set the 'types' field to ['error']: - | 'types' => ['error'], - | - | You can also combine multiple criteria by specifying multiple fields. - | For example, to display up to 5 error notifications, you can set - | the 'limit' and 'types' fields like this: - | 'limit' => 5, - | 'types' => ['error'], - */ - 'filter_criteria' => array( - 'limit' => 5, // Limit the number of notifications to display - ), -); + // Filter criteria for notifications (e.g., limit number, types) + 'filter' => [ + 'limit' => 5, // Limit the number of displayed notifications + ], +]; diff --git a/src/Laravel/Storage/SessionBag.php b/src/Laravel/Storage/SessionBag.php index d5c3fd3c..82cf5aaa 100644 --- a/src/Laravel/Storage/SessionBag.php +++ b/src/Laravel/Storage/SessionBag.php @@ -1,44 +1,30 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Storage; +use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Storage\Bag\BagInterface; -use Illuminate\Session\Store; +use Illuminate\Session\SessionManager; -final class SessionBag implements BagInterface +final readonly class SessionBag implements BagInterface { - const ENVELOPES_NAMESPACE = 'flasher::envelopes'; + public const ENVELOPES_NAMESPACE = 'flasher::envelopes'; - /** - * @var Store - */ - private $session; - - /** - * @param Store $session - */ - public function __construct($session) + public function __construct(private SessionManager $session) { - $this->session = $session; } - /** - * {@inheritdoc} - */ - public function get() + public function get(): array { - return $this->session->get(self::ENVELOPES_NAMESPACE, array()); // @phpstan-ignore-line + /** @var Envelope[] $envelopes */ + $envelopes = $this->session->get(self::ENVELOPES_NAMESPACE, []); + + return $envelopes; } - /** - * {@inheritdoc} - */ - public function set(array $envelopes) + public function set(array $envelopes): void { $this->session->put(self::ENVELOPES_NAMESPACE, $envelopes); } diff --git a/src/Laravel/Support/Laravel.php b/src/Laravel/Support/Laravel.php deleted file mode 100644 index e766da8a..00000000 --- a/src/Laravel/Support/Laravel.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ - -namespace Flasher\Laravel\Support; - -use Illuminate\Foundation\Application; - -final class Laravel -{ - /** - * @param string $version - * @param string|null $operator - * - * @return bool - */ - public static function isVersion($version, $operator = null) - { - if (null !== $operator) { - return version_compare(Application::VERSION, $version, $operator); - } - - $parts = explode('.', $version); - ++$parts[\count($parts) - 1]; - $next = implode('.', $parts); - - return self::isVersion($version, '>=') && self::isVersion($next, '<'); - } -} diff --git a/src/Laravel/Support/PluginServiceProvider.php b/src/Laravel/Support/PluginServiceProvider.php new file mode 100644 index 00000000..7e576b4b --- /dev/null +++ b/src/Laravel/Support/PluginServiceProvider.php @@ -0,0 +1,94 @@ +plugin = $this->createPlugin(); + + $this->registerConfiguration(); + $this->afterRegister(); + } + + public function boot(): void + { + $this->registerFactory(); + $this->afterBoot(); + } + + public function getConfigurationFile(): string + { + return rtrim($this->getResourcesDir(), '/').'/config.php'; + } + + protected function getResourcesDir(): string + { + $r = new \ReflectionClass($this); + + return pathinfo($r->getFileName() ?: '', \PATHINFO_DIRNAME).'/Resources/'; + } + + protected function registerConfiguration(): void + { + if ($this->app instanceof CachesConfiguration && $this->app->configurationIsCached()) { + return; + } + + $alias = $this->plugin->getAlias(); + $config = $this->app->make('config'); + + $key = 'flasher' === $alias ? $alias : "flasher.plugins.$alias"; + /** + * @var array{ + * scripts?: string|string[], + * styles?: string|string[], + * options?: array, + * } $current + */ + $current = $config->get($key, []); + + $config->set($key, $this->plugin->normalizeConfig($current)); + } + + protected function afterRegister(): void + { + } + + protected function afterBoot(): void + { + } + + protected function registerFactory(): void + { + $this->app->singleton($this->plugin->getServiceId(), function (Application $app) { + $factory = $this->plugin->getFactory(); + + return new $factory($app->make('flasher.storage_manager')); + }); + + $identifier = $this->plugin->getServiceId(); + foreach ((array) $this->plugin->getServiceAliases() as $alias) { + $this->app->alias($identifier, $alias); + } + + $this->app->extend('flasher.factory_locator', function (NotificationFactoryLocator $factoryLocator, Application $app) { + $factoryLocator->addFactory($this->plugin->getAlias(), fn () => $app->make($this->plugin->getServiceId())); + + return $factoryLocator; + }); + } +} diff --git a/src/Laravel/Support/ServiceProvider.php b/src/Laravel/Support/ServiceProvider.php deleted file mode 100644 index a522c6be..00000000 --- a/src/Laravel/Support/ServiceProvider.php +++ /dev/null @@ -1,228 +0,0 @@ - - */ - -namespace Flasher\Laravel\Support; - -use Flasher\Prime\FlasherInterface; -use Flasher\Prime\Plugin\PluginInterface; -use Flasher\Prime\Response\Resource\ResourceManagerInterface; -use Illuminate\Container\Container; -use Illuminate\Contracts\Config\Repository; -use Illuminate\Support\ServiceProvider as BaseServiceProvider; - -abstract class ServiceProvider extends BaseServiceProvider -{ - /** - * @var PluginInterface|null - */ - protected $plugin; - - /** - * {@inheritdoc} - */ - public function register() - { - $this->plugin = $this->plugin ?: $this->createPlugin(); - - $this->processConfiguration(); - $this->afterRegister(); - } - - /** - * @return void - */ - public function boot() - { - $this->registerPublishing(); - $this->registerFactory(); - $this->afterBoot(); - } - - /** - * @return PluginInterface - */ - abstract public function createPlugin(); - - /** - * @return string - */ - public function getConfigurationFile() - { - return rtrim($this->getResourcesDir(), '/').'/config.php'; - } - - /** - * @return void - */ - protected function registerPublishing() - { - if (!in_array(\PHP_SAPI, array('cli', 'phpdbg'))) { - return; - } - - if (Laravel::isVersion('4')) { - return; - } - - $this->publishConfiguration(); - $this->publishAssets(); - } - - /** - * @return void - */ - protected function publishConfiguration() - { - if (null === $this->plugin) { - return; - } - - $file = $this->getConfigurationFile(); - if (!file_exists($file)) { - return; - } - - $paths = array($file => config_path($this->plugin->getName().'.php')); - - $this->publishes($paths); - - $groups = array( - 'flasher-config', - str_replace('_', '-', $this->plugin->getName()).'-config', - ); - - foreach ($groups as $group) { - if (!array_key_exists($group, static::$publishGroups)) { - static::$publishGroups[$group] = array(); - } - - static::$publishGroups[$group] = array_merge(static::$publishGroups[$group], $paths); - } - } - - /** - * @return void - */ - protected function publishAssets() - { - if (null === $this->plugin) { - return; - } - - $dir = $this->plugin->getAssetsDir(); - - if (!is_dir($dir)) { - return; - } - - $paths = array($dir => public_path('vendor/flasher/')); - - $this->publishes($paths); - - $groups = array( - 'flasher-assets', - str_replace('_', '-', $this->plugin->getName()).'-assets', - ); - - foreach ($groups as $group) { - if (!array_key_exists($group, static::$publishGroups)) { - static::$publishGroups[$group] = array(); - } - - static::$publishGroups[$group] = array_merge(static::$publishGroups[$group], $paths); - } - } - - /** - * @return string - */ - protected function getResourcesDir() - { - $r = new \ReflectionClass($this); - - return pathinfo($r->getFileName() ?: '', PATHINFO_DIRNAME).'/Resources/'; - } - - /** - * @return void - */ - protected function processConfiguration() - { - if (null === $this->plugin) { - return; - } - - /** @var Repository $config */ - $config = $this->app->make('config'); - - $name = $this->plugin->getName(); - - /** @var array $configuration */ - $configuration = $config->get($name, array()); - - $config->set($name, $this->plugin->processConfiguration($configuration)); - } - - /** - * @return void - */ - protected function afterRegister() - { - } - - /** - * @return void - */ - protected function afterBoot() - { - } - - /** - * @return void - */ - protected function registerFactory() - { - $plugin = $this->plugin; - if (null === $plugin) { - return; - } - - if (!class_exists($plugin->getFactory())) { - return; - } - - $this->app->singleton($plugin->getServiceID(), function (Container $app) use ($plugin) { - $factory = $plugin->getFactory(); - - return new $factory($app->make('flasher.storage_manager')); - }); - - $this->app->alias($plugin->getServiceID(), $plugin->getFactory()); - - $this->app->extend('flasher', function (FlasherInterface $flasher, Container $app) use ($plugin) { - $flasher->addFactory($plugin->getAlias(), $app->make($plugin->getServiceID())); // @phpstan-ignore-line - - return $flasher; - }); - - $config = $this->app->make('config')->get($this->plugin->getName(), array()); // @phpstan-ignore-line - $this->app->extend('flasher.resource_manager', function (ResourceManagerInterface $manager) use ($plugin, $config) { - $config = $plugin->normalizeConfig($config); - - $scripts = isset($config['scripts']) ? $config['scripts'] : array(); - $manager->addScripts($plugin->getAlias(), $scripts); - - $styles = isset($config['styles']) ? $config['styles'] : array(); - $manager->addStyles($plugin->getAlias(), $styles); - - $options = isset($config['options']) ? $config['options'] : array(); - $manager->addOptions($plugin->getAlias(), $options); - - return $manager; - }); - } -} diff --git a/src/Laravel/Template/BladeTemplateEngine.php b/src/Laravel/Template/BladeTemplateEngine.php index 13066fb9..6f646461 100644 --- a/src/Laravel/Template/BladeTemplateEngine.php +++ b/src/Laravel/Template/BladeTemplateEngine.php @@ -1,34 +1,20 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Template; use Flasher\Prime\Template\TemplateEngineInterface; use Illuminate\View\Factory; -final class BladeTemplateEngine implements TemplateEngineInterface +final readonly class BladeTemplateEngine implements TemplateEngineInterface { - /** - * @var Factory - */ - private $engine; - - /** - * @param Factory $engine - */ - public function __construct($engine) + public function __construct(private Factory $blade) { - $this->engine = $engine; } - public function render($name, array $context = array()) + public function render(string $name, array $context = []): string { - $view = $this->engine->make($name, $context); - - return $view->render(); + return $this->blade->make($name, $context)->render(); } } diff --git a/src/Laravel/Translation/Translator.php b/src/Laravel/Translation/Translator.php index 81f58f20..00c04c6a 100644 --- a/src/Laravel/Translation/Translator.php +++ b/src/Laravel/Translation/Translator.php @@ -1,37 +1,20 @@ - */ +declare(strict_types=1); namespace Flasher\Laravel\Translation; -use Flasher\Prime\Stamp\TranslationStamp; use Flasher\Prime\Translation\TranslatorInterface; use Illuminate\Translation\Translator as LaravelTranslator; -final class Translator implements TranslatorInterface +final readonly class Translator implements TranslatorInterface { - /** - * @var LaravelTranslator - */ - private $translator; - - public function __construct(LaravelTranslator $translator) + public function __construct(private LaravelTranslator $translator) { - $this->translator = $translator; } - /** - * {@inheritdoc} - */ - public function translate($id, $parameters = array(), $locale = null) + public function translate(string $id, array $parameters = [], ?string $locale = null): string { - $order = TranslationStamp::parametersOrder($parameters, $locale); - $parameters = $order['parameters']; - $locale = $order['locale']; - $translation = $this->translator->has('flasher::messages.'.$id, $locale) ? $this->translator->get('flasher::messages.'.$id, $parameters, $locale) : ($this->translator->has('messages.'.$id, $locale) @@ -45,10 +28,7 @@ final class Translator implements TranslatorInterface return $translation; } - /** - * {@inheritdoc} - */ - public function getLocale() + public function getLocale(): string { return $this->translator->getLocale(); } diff --git a/src/Laravel/Translation/lang/ar/messages.php b/src/Laravel/Translation/lang/ar/messages.php index 52e27520..084fd9ee 100644 --- a/src/Laravel/Translation/lang/ar/messages.php +++ b/src/Laravel/Translation/lang/ar/messages.php @@ -1,10 +1,5 @@ - */ +declare(strict_types=1); -use Flasher\Prime\Translation\Messages; - -return Messages::$ar; +return Flasher\Prime\Translation\Messages::get('ar'); diff --git a/src/Laravel/Translation/lang/de/messages.php b/src/Laravel/Translation/lang/de/messages.php new file mode 100644 index 00000000..57908c7e --- /dev/null +++ b/src/Laravel/Translation/lang/de/messages.php @@ -0,0 +1,5 @@ + - */ +declare(strict_types=1); -use Flasher\Prime\Translation\Messages; - -return Messages::$en; +return Flasher\Prime\Translation\Messages::get('en'); diff --git a/src/Laravel/Translation/lang/es/messages.php b/src/Laravel/Translation/lang/es/messages.php new file mode 100644 index 00000000..f7fe97e6 --- /dev/null +++ b/src/Laravel/Translation/lang/es/messages.php @@ -0,0 +1,5 @@ + - */ +declare(strict_types=1); -use Flasher\Prime\Translation\Messages; - -return Messages::$fr; +return Flasher\Prime\Translation\Messages::get('fr'); diff --git a/src/Laravel/Translation/lang/pt/messages.php b/src/Laravel/Translation/lang/pt/messages.php new file mode 100644 index 00000000..688f1ef9 --- /dev/null +++ b/src/Laravel/Translation/lang/pt/messages.php @@ -0,0 +1,5 @@ +=5.3", - "illuminate/support": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "illuminate/support": "^11.0", + "php-flasher/flasher": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Laravel\\": "" @@ -52,13 +46,18 @@ "sort-packages": true }, "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, "laravel": { - "aliases": { - "Flasher": "Flasher\\Laravel\\Facade\\Flasher" - }, "providers": [ "Flasher\\Laravel\\FlasherServiceProvider" - ] + ], + "aliases": { + "Flasher": "Flasher\\Laravel\\Facade\\Flasher" + } } } } diff --git a/src/Laravel/extension.neon b/src/Laravel/extension.neon new file mode 100644 index 00000000..16555c62 --- /dev/null +++ b/src/Laravel/extension.neon @@ -0,0 +1,4 @@ +parameters: + stubFiles: + - Phpstan/stubs/Repository.stub + - Phpstan/stubs/ApplicationTestingHooks.stub diff --git a/src/Noty/Laravel/.github/FUNDING.yml b/src/Noty/Laravel/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Noty/Laravel/.github/FUNDING.yml +++ b/src/Noty/Laravel/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Noty/Laravel/.github/workflows/auto_closer.yaml b/src/Noty/Laravel/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Noty/Laravel/.github/workflows/auto_closer.yaml +++ b/src/Noty/Laravel/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Noty/Laravel/Facade/Noty.php b/src/Noty/Laravel/Facade/Noty.php index fe43d953..b67d85a7 100644 --- a/src/Noty/Laravel/Facade/Noty.php +++ b/src/Noty/Laravel/Facade/Noty.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Noty\Laravel\Facade; @@ -56,9 +53,9 @@ use Illuminate\Support\Facades\Facade; * @method static NotyBuilder buttons(array $buttons) * @method static NotyBuilder visibilityControl(bool $visibilityControl) */ -class Noty extends Facade +final class Noty extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'flasher.noty'; } diff --git a/src/Noty/Laravel/FlasherNotyServiceProvider.php b/src/Noty/Laravel/FlasherNotyServiceProvider.php index abb34459..4322dcae 100644 --- a/src/Noty/Laravel/FlasherNotyServiceProvider.php +++ b/src/Noty/Laravel/FlasherNotyServiceProvider.php @@ -1,21 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\Noty\Laravel; -use Flasher\Laravel\Support\ServiceProvider; +use Flasher\Laravel\Support\PluginServiceProvider; use Flasher\Noty\Prime\NotyPlugin; -final class FlasherNotyServiceProvider extends ServiceProvider +final class FlasherNotyServiceProvider extends PluginServiceProvider { - /** - * {@inheritDoc} - */ - public function createPlugin() + public function createPlugin(): NotyPlugin { return new NotyPlugin(); } diff --git a/src/Noty/Laravel/LICENSE b/src/Noty/Laravel/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Noty/Laravel/LICENSE +++ b/src/Noty/Laravel/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Noty/Laravel/README.md b/src/Noty/Laravel/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Noty/Laravel/README.md +++ b/src/Noty/Laravel/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Noty/Laravel/Resources/config.php b/src/Noty/Laravel/Resources/config.php deleted file mode 100644 index cee47277..00000000 --- a/src/Noty/Laravel/Resources/config.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -return array( - 'scripts' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-noty@1.3.2/dist/flasher-noty.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-noty.min.js', - ), - ), - 'styles' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-noty@1.3.2/dist/flasher-noty.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-noty.min.css', - ), - ), -); diff --git a/src/Noty/Laravel/composer.json b/src/Noty/Laravel/composer.json index 2ffa7ba5..31aa9436 100644 --- a/src/Noty/Laravel/composer.json +++ b/src/Noty/Laravel/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-noty-laravel", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-laravel": "^1.15.14", - "php-flasher/flasher-noty": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-laravel": "^2.0", + "php-flasher/flasher-noty": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Noty\\Laravel\\": "" @@ -53,12 +47,12 @@ }, "extra": { "laravel": { - "aliases": { - "Noty": "Flasher\\Laravel\\Facade\\Flasher" - }, "providers": [ "Flasher\\Noty\\Laravel\\FlasherNotyServiceProvider" - ] + ], + "aliases": { + "Noty": "Flasher\\Noty\\Laravel\\Facade\\Noty" + } } } } diff --git a/src/Noty/Prime/.github/FUNDING.yml b/src/Noty/Prime/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Noty/Prime/.github/FUNDING.yml +++ b/src/Noty/Prime/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Noty/Prime/.github/workflows/auto_closer.yaml b/src/Noty/Prime/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Noty/Prime/.github/workflows/auto_closer.yaml +++ b/src/Noty/Prime/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Noty/Prime/.phpstorm.meta.php b/src/Noty/Prime/.phpstorm.meta.php index ddd3f946..abef64e2 100644 --- a/src/Noty/Prime/.phpstorm.meta.php +++ b/src/Noty/Prime/.phpstorm.meta.php @@ -3,6 +3,8 @@ namespace PHPSTORM_META; expectedArguments(\noty(), 1, 'success', 'error', 'info', 'warning'); +expectedArguments(\Flasher\Noty\Prime\noty(), 1, 'success', 'error', 'info', 'warning'); + expectedArguments(\Flasher\Noty\Prime\NotyBuilder::layout(), 0, 'top', 'topLeft', 'topCenter', 'topRight', 'center', 'centerLeft', 'centerRight', 'bottom', 'bottomLeft', 'bottomCenter', 'bottomRight'); expectedArguments(\Flasher\Noty\Prime\NotyBuilder::theme(), 0, 'relax', 'mint', 'metroui'); expectedArguments(\Flasher\Noty\Prime\NotyBuilder::timeout(), 0, false, 1000, 3000, 3500, 5000); @@ -12,10 +14,5 @@ expectedArguments(\Flasher\Noty\Prime\NotyBuilder::sounds(), 0, 'sources', 'volu expectedArguments(\Flasher\Noty\Prime\NotyBuilder::docTitle(), 0, 'conditions'); expectedArguments(\Flasher\Noty\Prime\NotyBuilder::queue(), 0, 'global'); -override(\Flasher\Prime\FlasherInterface::create(), map([ - 'noty' => \Flasher\Noty\Prime\NotyFactory::class -])); - -override(\Flasher\Prime\FlasherInterface::using(), map([ - 'noty' => \Flasher\Noty\Prime\NotyFactory::class -])); +override(\Flasher\Prime\FlasherInterface::use(), map(['noty' => \Flasher\Noty\Prime\NotyInterface::class])); +override(\Flasher\Prime\Container\FlasherContainer::create(), map(['flasher.noty' => \Flasher\Noty\Prime\NotyInterface::class])); diff --git a/src/Noty/Prime/LICENSE b/src/Noty/Prime/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Noty/Prime/LICENSE +++ b/src/Noty/Prime/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Noty/Prime/Noty.php b/src/Noty/Prime/Noty.php new file mode 100644 index 00000000..738b9f15 --- /dev/null +++ b/src/Noty/Prime/Noty.php @@ -0,0 +1,18 @@ +storageManager); + } +} diff --git a/src/Noty/Prime/NotyBuilder.php b/src/Noty/Prime/NotyBuilder.php index 6050d3ab..430c7958 100644 --- a/src/Noty/Prime/NotyBuilder.php +++ b/src/Noty/Prime/NotyBuilder.php @@ -1,52 +1,45 @@ - */ +declare(strict_types=1); namespace Flasher\Noty\Prime; use Flasher\Prime\Notification\NotificationBuilder; -/** - * @SuppressWarnings(PHPMD.TooManyMethods) - * @SuppressWarnings(PHPMD.TooManyPublicMethods) - */ final class NotyBuilder extends NotificationBuilder { /** * This string can contain HTML too. But be careful and don't pass user inputs to this parameter. - * - * @param string $text - * - * @return static */ - public function text($text) + public function text(string $text): self { return $this->message($text); } /** - * @param string $message * @param array $options - * - * @return static */ - public function alert($message = null, array $options = array()) + public function alert(?string $message = null, array $options = []): self { - return $this->type('alert', $message, $options); + $this->type('alert'); + + if ($message) { + $this->message($message); + } + + if ([] !== $options) { + $this->options($options); + } + + return $this; } /** - * top, topLeft, topCenter, topRight, center, centerLeft, centerRight, bottom, bottomLeft, bottomCenter, bottomRight - * - ClassName generator uses this value → noty_layout__${layout}. + * @param "top"|"topLeft"|"topCenter"|"topRight"|"center"|"centerLeft"|"centerRight"|"bottom"|"bottomLeft"|"bottomCenter"|"bottomRight" $layout * - * @param string $layout - * - * @return static + * - ClassName generator uses this value → noty_layout__${layout} */ - public function layout($layout) + public function layout(string $layout): self { $this->option('layout', $layout); @@ -54,13 +47,11 @@ final class NotyBuilder extends NotificationBuilder } /** - * relax, mint, metroui - ClassName generator uses this value → noty_theme__${theme}. + * @param "relax"|"mint"|"metroui" $theme * - * @param string $theme - * - * @return static + * ClassName generator uses this value → noty_theme__${theme} */ - public function theme($theme) + public function theme(string $theme): self { $this->option('theme', $theme); @@ -69,12 +60,8 @@ final class NotyBuilder extends NotificationBuilder /** * false, 1000, 3000, 3500, etc. Delay for closing event in milliseconds (ms). Set 'false' for sticky notifications. - * - * @param bool|int $timeout - * - * @return static */ - public function timeout($timeout) + public function timeout(bool|int $timeout): self { $this->option('timeout', $timeout); @@ -83,12 +70,8 @@ final class NotyBuilder extends NotificationBuilder /** * true, false - Displays a progress bar if timeout is not false. - * - * @param bool $progressBar - * - * @return static */ - public function progressBar($progressBar = false) + public function progressBar(bool $progressBar = false): self { $this->option('progressBar', $progressBar); @@ -98,11 +81,9 @@ final class NotyBuilder extends NotificationBuilder /** * click, button. * - * @param array|string $closeWith - * - * @return static + * @param string|string[] $closeWith */ - public function closeWith($closeWith) + public function closeWith(string|array $closeWith): self { $this->option('closeWith', (array) $closeWith); @@ -112,51 +93,29 @@ final class NotyBuilder extends NotificationBuilder /** * If string, assumed to be CSS class name. If null, no animation at all. If function, runs the function. (v3.0.1+) * You can use animate.css class names or your custom css animations as well. - * - * @param string $animation - * @param string $effect - * - * @return static */ - public function animation($animation, $effect) + public function animation(string $animation, string $effect): self { $this->option('animation.'.$animation, $effect); return $this; } - /** - * @param string $option - * @param mixed $value - * - * @return static - */ - public function sounds($option, $value) + public function sounds(string $option, mixed $value): self { $this->option('sounds.'.$option, $value); return $this; } - /** - * @param string $option - * @param mixed $docTitle - * - * @return static - */ - public function docTitle($option, $docTitle) + public function docTitle(string $option, string $docTitle): self { $this->option('docTitle'.$option, $docTitle); return $this; } - /** - * @param bool $modal - * - * @return static - */ - public function modal($modal = true) + public function modal(bool $modal = true): self { $this->option('modal', $modal); @@ -165,15 +124,8 @@ final class NotyBuilder extends NotificationBuilder /** * You can use this id with querySelectors. Generated automatically if false. - * - * @param bool|string $id - * - * @return static - * - * @SuppressWarnings(PHPMD.ShortMethodName) - * @SuppressWarnings(PHPMD.ShortVariable) */ - public function id($id) + public function id(bool|string $id): self { $this->option('id', $id); @@ -182,24 +134,15 @@ final class NotyBuilder extends NotificationBuilder /** * DOM insert method depends on this parameter. If false uses append, if true uses prepend. - * - * @param bool $force - * - * @return static */ - public function force($force = true) + public function force(bool $force = true): self { $this->option('force', $force); return $this; } - /** - * @param string $queue - * - * @return static - */ - public function queue($queue) + public function queue(string $queue): self { $this->option('queue', $queue); @@ -209,12 +152,8 @@ final class NotyBuilder extends NotificationBuilder /** * If true closes all visible notifications and shows itself. If string(queueName) closes all visible notification * on this queue and shows itself. - * - * @param bool|string $killer - * - * @return static */ - public function killer($killer) + public function killer(bool|string $killer): self { $this->option('killer', $killer); @@ -223,12 +162,8 @@ final class NotyBuilder extends NotificationBuilder /** * Custom container selector string. Like '.my-custom-container'. Layout parameter will be ignored. - * - * @param bool|string $container - * - * @return static */ - public function container($container) + public function container(bool|string $container): self { $this->option('container', $container); @@ -238,11 +173,9 @@ final class NotyBuilder extends NotificationBuilder /** * An array of Noty.button, for creating confirmation dialogs. * - * @param array $buttons - * - * @return static + * @param string[] $buttons */ - public function buttons($buttons) + public function buttons(array $buttons): self { $this->option('buttons', $buttons); @@ -251,12 +184,8 @@ final class NotyBuilder extends NotificationBuilder /** * If true Noty uses PageVisibility API to handle timeout. To ensure that users do not miss their notifications. - * - * @param bool $visibilityControl - * - * @return static */ - public function visibilityControl($visibilityControl) + public function visibilityControl(bool $visibilityControl): self { $this->option('visibilityControl', $visibilityControl); diff --git a/src/Noty/Prime/NotyFactory.php b/src/Noty/Prime/NotyFactory.php deleted file mode 100644 index 2525201b..00000000 --- a/src/Noty/Prime/NotyFactory.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Flasher\Noty\Prime; - -use Flasher\Prime\Factory\NotificationFactory; -use Flasher\Prime\Notification\Notification; - -/** - * @mixin NotyBuilder - */ -final class NotyFactory extends NotificationFactory -{ - public function createNotificationBuilder() - { - return new NotyBuilder($this->getStorageManager(), new Notification(), 'noty'); - } -} diff --git a/src/Noty/Prime/NotyInterface.php b/src/Noty/Prime/NotyInterface.php new file mode 100644 index 00000000..2a866d45 --- /dev/null +++ b/src/Noty/Prime/NotyInterface.php @@ -0,0 +1,14 @@ + - */ +declare(strict_types=1); namespace Flasher\Noty\Prime; use Flasher\Prime\Plugin\Plugin; -class NotyPlugin extends Plugin +final class NotyPlugin extends Plugin { - /** - * {@inheritdoc} - */ - public function getScripts() + public function getAlias(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-noty@1.3.2/dist/flasher-noty.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-noty.min.js', - ), - ); + return 'noty'; } - /** - * {@inheritdoc} - */ - public function getStyles() + public function getFactory(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-noty@1.3.2/dist/flasher-noty.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-noty.min.css', - ), - ); + return Noty::class; + } + + public function getServiceAliases(): string + { + return NotyInterface::class; + } + + public function getScripts(): string|array + { + return [ + '/vendor/flasher/noty.min.js', + '/vendor/flasher/flasher-noty.min.js', + ]; + } + + public function getStyles(): string|array + { + return [ + '/vendor/flasher/noty.css', + '/vendor/flasher/mint.css', + ]; } } diff --git a/src/Noty/Prime/README.md b/src/Noty/Prime/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Noty/Prime/README.md +++ b/src/Noty/Prime/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Noty/Prime/Resources/assets/flasher-noty.min.css b/src/Noty/Prime/Resources/assets/flasher-noty.min.css deleted file mode 100644 index 97da8507..00000000 --- a/src/Noty/Prime/Resources/assets/flasher-noty.min.css +++ /dev/null @@ -1,2 +0,0 @@ -#noty_layout__bottom,#noty_layout__bottomCenter,#noty_layout__bottomLeft,#noty_layout__bottomRight,#noty_layout__center,#noty_layout__centerLeft,#noty_layout__centerRight,#noty_layout__top,#noty_layout__topCenter,#noty_layout__topLeft,#noty_layout__topRight,.noty_layout_mixin{-webkit-font-smoothing:subpixel-antialiased;-webkit-backface-visibility:hidden;backface-visibility:hidden;filter:blur(0);-webkit-filter:blur(0);margin:0;max-width:90%;padding:0;position:fixed;-webkit-transform:translateZ(0) scale(1);transform:translateZ(0) scale(1);z-index:9999999}#noty_layout__top{left:5%;top:0;width:90%}#noty_layout__topLeft{left:20px;top:20px;width:325px}#noty_layout__topCenter{left:50%;top:5%;-webkit-transform:translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1);transform:translate(calc(-50% - .5px)) translateZ(0) scale(1);width:325px}#noty_layout__topRight{right:20px;top:20px;width:325px}#noty_layout__bottom{bottom:0;left:5%;width:90%}#noty_layout__bottomLeft{bottom:20px;left:20px;width:325px}#noty_layout__bottomCenter{bottom:5%;left:50%;-webkit-transform:translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1);transform:translate(calc(-50% - .5px)) translateZ(0) scale(1);width:325px}#noty_layout__bottomRight{bottom:20px;right:20px;width:325px}#noty_layout__center{left:50%;top:50%;-webkit-transform:translate(-webkit-calc(-50% - .5px),-webkit-calc(-50% - .5px)) translateZ(0) scale(1);transform:translate(calc(-50% - .5px),calc(-50% - .5px)) translateZ(0) scale(1);width:325px}#noty_layout__centerLeft{left:20px}#noty_layout__centerLeft,#noty_layout__centerRight{top:50%;-webkit-transform:translateY(-webkit-calc(-50% - .5px)) translateZ(0) scale(1);transform:translateY(calc(-50% - .5px)) translateZ(0) scale(1);width:325px}#noty_layout__centerRight{right:20px}.noty_progressbar{display:none}.noty_has_timeout.noty_has_progressbar .noty_progressbar{background-color:#646464;bottom:0;display:block;filter:alpha(opacity=10);height:3px;left:0;opacity:.2;position:absolute;width:100%}.noty_bar{-webkit-font-smoothing:subpixel-antialiased;-webkit-backface-visibility:hidden;overflow:hidden;-webkit-transform:translate(0) translateZ(0) scale(1);-ms-transform:translate(0) scale(1);transform:translate(0) scale(1)}.noty_effects_open{-webkit-animation:noty_anim_in .5s cubic-bezier(.68,-.55,.265,1.55);animation:noty_anim_in .5s cubic-bezier(.68,-.55,.265,1.55);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;opacity:0;-webkit-transform:translate(50%);-ms-transform:translate(50%);transform:translate(50%)}.noty_effects_close{-webkit-animation:noty_anim_out .5s cubic-bezier(.68,-.55,.265,1.55);animation:noty_anim_out .5s cubic-bezier(.68,-.55,.265,1.55);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.noty_fix_effects_height{-webkit-animation:noty_anim_height 75ms ease-out;animation:noty_anim_height 75ms ease-out}.noty_close_with_click{cursor:pointer}.noty_close_button{background-color:rgba(0,0,0,.05);border-radius:2px;cursor:pointer;font-weight:700;height:20px;line-height:20px;position:absolute;right:2px;text-align:center;top:2px;-webkit-transition:all .2s ease-out;transition:all .2s ease-out;width:20px}.noty_close_button:hover{background-color:rgba(0,0,0,.1)}.noty_modal{background-color:#000;height:100%;left:0;opacity:.3;position:fixed;top:0;width:100%;z-index:10000}.noty_modal.noty_modal_open{-webkit-animation:noty_modal_in .3s ease-out;animation:noty_modal_in .3s ease-out;opacity:0}.noty_modal.noty_modal_close{-webkit-animation:noty_modal_out .3s ease-out;animation:noty_modal_out .3s ease-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@-webkit-keyframes noty_modal_in{to{opacity:.3}}@keyframes noty_modal_in{to{opacity:.3}}@-webkit-keyframes noty_modal_out{to{opacity:0}}@keyframes noty_modal_out{to{opacity:0}}@-webkit-keyframes noty_anim_in{to{opacity:1;-webkit-transform:translate(0);transform:translate(0)}}@keyframes noty_anim_in{to{opacity:1;-webkit-transform:translate(0);transform:translate(0)}}@-webkit-keyframes noty_anim_out{to{opacity:0;-webkit-transform:translate(50%);transform:translate(50%)}}@keyframes noty_anim_out{to{opacity:0;-webkit-transform:translate(50%);transform:translate(50%)}}@-webkit-keyframes noty_anim_height{to{height:0}}@keyframes noty_anim_height{to{height:0}} -.noty_theme__mint.noty_bar{border-radius:2px;margin:4px 0;overflow:hidden;position:relative}.noty_theme__mint.noty_bar .noty_body{font-size:14px;padding:10px}.noty_theme__mint.noty_bar .noty_buttons{padding:10px}.noty_theme__mint.noty_type__alert,.noty_theme__mint.noty_type__notification{background-color:#fff;border-bottom:1px solid #d1d1d1;color:#2f2f2f}.noty_theme__mint.noty_type__warning{background-color:#ffae42;border-bottom:1px solid #e89f3c;color:#fff}.noty_theme__mint.noty_type__error{background-color:#de636f;border-bottom:1px solid #ca5a65;color:#fff}.noty_theme__mint.noty_type__info,.noty_theme__mint.noty_type__information{background-color:#7f7eff;border-bottom:1px solid #7473e8;color:#fff}.noty_theme__mint.noty_type__success{background-color:#afc765;border-bottom:1px solid #a0b55c;color:#fff} \ No newline at end of file diff --git a/src/Noty/Prime/Resources/assets/flasher-noty.min.js b/src/Noty/Prime/Resources/assets/flasher-noty.min.js deleted file mode 100644 index 8f3238d4..00000000 --- a/src/Noty/Prime/Resources/assets/flasher-noty.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):((t="undefined"!=typeof globalThis?globalThis:t||self).flasher=t.flasher||{},t.flasher.noty=e(t.flasher))}(this,(function(t){"use strict";var e=function(){return e=Object.assign||function(t){for(var e,o=1,n=arguments.length;o0&&void 0!==arguments[0]?arguments[0]:"",e="noty_"+t+"_";return e+="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)}))},e.outerHeight=function(t){var e=t.offsetHeight,o=window.getComputedStyle(t);return e+=parseInt(o.marginTop)+parseInt(o.marginBottom)},e.addListener=r,e.hasClass=s,e.addClass=function(t,e){var o=u(t),n=o+e;s(o,e)||(t.className=n.substring(1))},e.removeClass=function(t,e){var o=u(t),n=void 0;s(t,e)&&(n=o.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))},e.remove=a,e.classList=u,e.visibilityChangeFlow=function(){var t=void 0,e=void 0;function o(){i.PageHidden?setTimeout((function(){Object.keys(i.Store).forEach((function(t){i.Store.hasOwnProperty(t)&&i.Store[t].options.visibilityControl&&i.Store[t].stop()}))}),100):setTimeout((function(){Object.keys(i.Store).forEach((function(t){i.Store.hasOwnProperty(t)&&i.Store[t].options.visibilityControl&&i.Store[t].resume()})),i.queueRenderAll()}),100)}void 0!==document.hidden?(t="hidden",e="visibilitychange"):void 0!==document.msHidden?(t="msHidden",e="msvisibilitychange"):void 0!==document.webkitHidden&&(t="webkitHidden",e="webkitvisibilitychange"),e&&r(document,e,(function(){i.PageHidden=document[t],o()})),r(window,"blur",(function(){i.PageHidden=!0,o()})),r(window,"focus",(function(){i.PageHidden=!1,o()}))},e.createAudioElements=function(t){if(t.hasSound){var e=document.createElement("audio");t.options.sounds.sources.forEach((function(t){var o=document.createElement("source");o.src=t,o.type="audio/"+t.match(/\.([^.]+)$/)[1],e.appendChild(o)})),t.barDom?t.barDom.appendChild(e):document.querySelector("body").appendChild(e),e.volume=t.options.sounds.volume,t.soundPlayed||(e.play(),t.soundPlayed=!0),e.onended=function(){a(e)}}};var i=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e.default=t,e}(o(1));function r(t,e,o){var n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];e=e.split(" ");for(var i=0;i=0}function a(t){t.parentNode&&t.parentNode.removeChild(t)}function u(t){return(" "+(t&&t.className||"")+" ").replace(/\s+/gi," ")}e.animationEndEvents="webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",e.deepExtend=function t(e){e=e||{};for(var o=1;o0&&void 0!==arguments[0]?arguments[0]:"global",e=0,o=a;return u.hasOwnProperty(t)&&(o=u[t].maxVisible,Object.keys(l).forEach((function(o){l[o].options.queue!==t||l[o].closed||e++}))),{current:e,maxVisible:o}},e.addToQueue=function(t){u.hasOwnProperty(t.options.queue)||(u[t.options.queue]={maxVisible:a,queue:[]}),u[t.options.queue].queue.push(t)},e.removeFromQueue=function(t){if(u.hasOwnProperty(t.options.queue)){var e=[];Object.keys(u[t.options.queue].queue).forEach((function(o){u[t.options.queue].queue[o].id!==t.id&&e.push(u[t.options.queue].queue[o])})),u[t.options.queue].queue=e}},e.queueRender=c,e.queueRenderAll=function(){Object.keys(u).forEach((function(t){c(t)}))},e.ghostFix=function(t){var e=n.generateID("ghost"),o=document.createElement("div");o.setAttribute("id",e),n.css(o,{height:n.outerHeight(t.barDom)+"px"}),t.barDom.insertAdjacentHTML("afterend",o.outerHTML),n.remove(t.barDom),o=document.getElementById(e),n.addClass(o,"noty_fix_effects_height"),n.addListener(o,n.animationEndEvents,(function(){n.remove(o)}))},e.build=function(t){!function(t){if(t.options.container)t.layoutDom=document.querySelector(t.options.container);else{var e="noty_layout__"+t.options.layout;t.layoutDom=document.querySelector("div#"+e),t.layoutDom||(t.layoutDom=document.createElement("div"),t.layoutDom.setAttribute("id",e),t.layoutDom.setAttribute("role","alert"),t.layoutDom.setAttribute("aria-live","polite"),n.addClass(t.layoutDom,"noty_layout"),document.querySelector("body").appendChild(t.layoutDom))}}(t);var e='
'+t.options.text+"
"+function(t){if(f(t)){var e=document.createElement("div");return n.addClass(e,"noty_buttons"),Object.keys(t.options.buttons).forEach((function(o){e.appendChild(t.options.buttons[o].dom)})),t.options.buttons.forEach((function(t){e.appendChild(t.dom)})),e.outerHTML}return""}(t)+'
';t.barDom=document.createElement("div"),t.barDom.setAttribute("id",t.id),n.addClass(t.barDom,"noty_bar noty_type__"+t.options.type+" noty_theme__"+t.options.theme),t.barDom.innerHTML=e,p(t,"onTemplate")},e.hasButtons=f,e.handleModal=function(t){var o,r;t.options.modal&&(0===i&&(o=document.querySelector("body"),r=document.createElement("div"),n.addClass(r,"noty_modal"),o.insertBefore(r,o.firstChild),n.addClass(r,"noty_modal_open"),n.addListener(r,n.animationEndEvents,(function(){n.removeClass(r,"noty_modal_open")}))),e.DocModalCount=i+=1)},e.handleModalClose=function(t){if(t.options.modal&&i>0&&(e.DocModalCount=i-=1,i<=0)){var o=document.querySelector(".noty_modal");o&&(n.removeClass(o,"noty_modal_open"),n.addClass(o,"noty_modal_close"),n.addListener(o,n.animationEndEvents,(function(){n.remove(o)})))}},e.queueClose=d,e.dequeueClose=h,e.fire=p,e.openFlow=function(t){p(t,"afterShow"),d(t),n.addListener(t.barDom,"mouseenter",(function(){h(t)})),n.addListener(t.barDom,"mouseleave",(function(){d(t)}))},e.closeFlow=function(t){delete l[t.id],t.closing=!1,p(t,"afterClose"),n.remove(t.barDom),0!==t.layoutDom.querySelectorAll(".noty_bar").length||t.options.container||n.remove(t.layoutDom),(n.inArray("docVisible",t.options.titleCount.conditions)||n.inArray("docHidden",t.options.titleCount.conditions))&&s.decrement(),c(t.options.queue)};var n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e.default=t,e}(o(0));e.PageHidden=!1;var i=e.DocModalCount=0,r={originalTitle:null,count:0,changed:!1,timer:-1},s=e.docTitle={increment:function(){r.count++,s._update()},decrement:function(){r.count--,r.count<=0?s._clear():s._update()},_update:function(){var t=document.title;r.changed?document.title="("+r.count+") "+r.originalTitle:(r.originalTitle=t,document.title="("+r.count+") "+t,r.changed=!0)},_clear:function(){r.changed&&(r.count=0,document.title=r.originalTitle,r.changed=!1)}},a=e.DefaultMaxVisible=5,u=e.Queues={global:{maxVisible:a,queue:[]}},l=e.Store={};function c(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"global";if(u.hasOwnProperty(t)){var e=u[t].queue.shift();e&&e.show()}}function f(t){return!(!t.options.buttons||!Object.keys(t.options.buttons).length)}function d(t){t.options.timeout&&(t.options.progressBar&&t.progressDom&&n.css(t.progressDom,{transition:"width "+t.options.timeout+"ms linear",width:"0%"}),clearTimeout(t.closeTimer),t.closeTimer=setTimeout((function(){t.close()}),t.options.timeout))}function h(t){t.options.timeout&&t.closeTimer&&(clearTimeout(t.closeTimer),t.closeTimer=-1,t.options.progressBar&&t.progressDom&&n.css(t.progressDom,{transition:"width 0ms linear",width:"100%"}))}function p(t,e){t.listeners.hasOwnProperty(e)&&t.listeners[e].forEach((function(e){"function"==typeof e&&e.apply(t)}))}e.Defaults={type:"alert",layout:"topRight",theme:"mint",text:"",timeout:!1,progressBar:!0,closeWith:["click"],animation:{open:"noty_effects_open",close:"noty_effects_close"},id:!1,force:!1,killer:!1,queue:"global",container:!1,buttons:[],callbacks:{beforeShow:null,onShow:null,afterShow:null,onClose:null,afterClose:null,onClick:null,onHover:null,onTemplate:null},sounds:{sources:[],volume:1,conditions:[]},titleCount:{conditions:[]},modal:!1,visibilityControl:!1}},function(t,e,o){Object.defineProperty(e,"__esModule",{value:!0}),e.NotyButton=void 0;var n=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e.default=t,e}(o(0));e.NotyButton=function t(e,o,i){var r=this,s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.dom=document.createElement("button"),this.dom.innerHTML=e,this.id=s.id=s.id||n.generateID("button"),this.cb=i,Object.keys(s).forEach((function(t){r.dom.setAttribute(t,s[t])})),n.addClass(this.dom,o||"noty_btn"),this}},function(t,e,o){Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var o=0;o0&&void 0!==arguments[0]?arguments[0]:"/service-worker.js";return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.subData={},this.workerPath=e,this.listeners={onPermissionGranted:[],onPermissionDenied:[],onSubscriptionSuccess:[],onSubscriptionCancel:[],onWorkerError:[],onWorkerSuccess:[],onWorkerNotSupported:[]},this}return n(t,[{key:"on",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};return"function"==typeof e&&this.listeners.hasOwnProperty(t)&&this.listeners[t].push(e),this}},{key:"fire",value:function(t){var e=this,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];this.listeners.hasOwnProperty(t)&&this.listeners[t].forEach((function(t){"function"==typeof t&&t.apply(e,o)}))}},{key:"create",value:function(){console.log("NOT IMPLEMENTED YET")}},{key:"isSupported",value:function(){var t=!1;try{t=window.Notification||window.webkitNotifications||navigator.mozNotification||window.external&&void 0!==window.external.msIsSiteMode()}catch(t){}return t}},{key:"getPermissionStatus",value:function(){var t="default";if(window.Notification&&window.Notification.permissionLevel)t=window.Notification.permissionLevel;else if(window.webkitNotifications&&window.webkitNotifications.checkPermission)switch(window.webkitNotifications.checkPermission()){case 1:t="default";break;case 0:t="granted";break;default:t="denied"}else window.Notification&&window.Notification.permission?t=window.Notification.permission:navigator.mozNotification?t="granted":window.external&&void 0!==window.external.msIsSiteMode()&&(t=window.external.msIsSiteMode()?"granted":"default");return t.toString().toLowerCase()}},{key:"getEndpoint",value:function(t){var e=t.endpoint,o=t.subscriptionId;return o&&-1===e.indexOf(o)&&(e+="/"+o),e}},{key:"isSWRegistered",value:function(){try{return"activated"===navigator.serviceWorker.controller.state}catch(t){return!1}}},{key:"unregisterWorker",value:function(){var t=this;"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then((function(e){var o=!0,n=!1,i=void 0;try{for(var r,s=e[Symbol.iterator]();!(o=(r=s.next()).done);o=!0)r.value.unregister(),t.fire("onSubscriptionCancel")}catch(t){n=!0,i=t}finally{try{!o&&s.return&&s.return()}finally{if(n)throw i}}}))}},{key:"requestSubscription",value:function(){var t=this,e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],o=this,n=this.getPermissionStatus(),i=function(n){"granted"===n?(t.fire("onPermissionGranted"),"serviceWorker"in navigator?navigator.serviceWorker.register(t.workerPath).then((function(){navigator.serviceWorker.ready.then((function(t){o.fire("onWorkerSuccess"),t.pushManager.subscribe({userVisibleOnly:e}).then((function(t){var e=t.getKey("p256dh"),n=t.getKey("auth");o.subData={endpoint:o.getEndpoint(t),p256dh:e?window.btoa(String.fromCharCode.apply(null,new Uint8Array(e))):null,auth:n?window.btoa(String.fromCharCode.apply(null,new Uint8Array(n))):null},o.fire("onSubscriptionSuccess",[o.subData])})).catch((function(t){o.fire("onWorkerError",[t])}))}))})):o.fire("onWorkerNotSupported")):"denied"===n&&(t.fire("onPermissionDenied"),t.unregisterWorker())};"default"===n?window.Notification&&window.Notification.requestPermission?window.Notification.requestPermission(i):window.webkitNotifications&&window.webkitNotifications.checkPermission&&window.webkitNotifications.requestPermission(i):i(n)}}]),t}()},function(t,e,o){(function(e,n){var i;i=function(){function t(t){return"function"==typeof t}var i=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},r=0,s=void 0,a=void 0,u=function(t,e){m[r]=t,m[r+1]=e,2===(r+=2)&&(a?a(v):_())},l="undefined"!=typeof window?window:void 0,c=l||{},f=c.MutationObserver||c.WebKitMutationObserver,d="undefined"==typeof self&&void 0!==e&&"[object process]"==={}.toString.call(e),h="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function p(){var t=setTimeout;return function(){return t(v,1)}}var m=new Array(1e3);function v(){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{};return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.options=a.deepExtend({},u.Defaults,e),u.Store[this.options.id]?u.Store[this.options.id]:(this.id=this.options.id||a.generateID("bar"),this.closeTimer=-1,this.barDom=null,this.layoutDom=null,this.progressDom=null,this.showing=!1,this.shown=!1,this.closed=!1,this.closing=!1,this.killable=this.options.timeout||this.options.closeWith.length>0,this.hasSound=this.options.sounds.sources.length>0,this.soundPlayed=!1,this.listeners={beforeShow:[],onShow:[],afterShow:[],onClose:[],afterClose:[],onClick:[],onHover:[],onTemplate:[]},this.promises={show:null,close:null},this.on("beforeShow",this.options.callbacks.beforeShow),this.on("onShow",this.options.callbacks.onShow),this.on("afterShow",this.options.callbacks.afterShow),this.on("onClose",this.options.callbacks.onClose),this.on("afterClose",this.options.callbacks.afterClose),this.on("onClick",this.options.callbacks.onClick),this.on("onHover",this.options.callbacks.onHover),this.on("onTemplate",this.options.callbacks.onTemplate),this)}return n(t,[{key:"on",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};return"function"==typeof e&&this.listeners.hasOwnProperty(t)&&this.listeners[t].push(e),this}},{key:"show",value:function(){var e=this;if(this.showing||this.shown)return this;!0===this.options.killer?t.closeAll():"string"==typeof this.options.killer&&t.closeAll(this.options.killer);var o=u.getQueueCounts(this.options.queue);if(o.current>=o.maxVisible||u.PageHidden&&this.options.visibilityControl)return u.addToQueue(this),u.PageHidden&&this.hasSound&&a.inArray("docHidden",this.options.sounds.conditions)&&a.createAudioElements(this),u.PageHidden&&a.inArray("docHidden",this.options.titleCount.conditions)&&u.docTitle.increment(),this;if(u.Store[this.id]=this,u.fire(this,"beforeShow"),this.showing=!0,this.closing)return this.showing=!1,this;if(u.build(this),u.handleModal(this),this.options.force?this.layoutDom.insertBefore(this.barDom,this.layoutDom.firstChild):this.layoutDom.appendChild(this.barDom),this.hasSound&&!this.soundPlayed&&a.inArray("docVisible",this.options.sounds.conditions)&&a.createAudioElements(this),a.inArray("docVisible",this.options.titleCount.conditions)&&u.docTitle.increment(),this.shown=!0,this.closed=!1,u.hasButtons(this)&&Object.keys(this.options.buttons).forEach((function(t){var o=e.barDom.querySelector("#"+e.options.buttons[t].id);a.addListener(o,"click",(function(o){a.stopPropagation(o),e.options.buttons[t].cb(e)}))})),this.progressDom=this.barDom.querySelector(".noty_progressbar"),a.inArray("click",this.options.closeWith)&&(a.addClass(this.barDom,"noty_close_with_click"),a.addListener(this.barDom,"click",(function(t){a.stopPropagation(t),u.fire(e,"onClick"),e.close()}),!1)),a.addListener(this.barDom,"mouseenter",(function(){u.fire(e,"onHover")}),!1),this.options.timeout&&a.addClass(this.barDom,"noty_has_timeout"),this.options.progressBar&&a.addClass(this.barDom,"noty_has_progressbar"),a.inArray("button",this.options.closeWith)){a.addClass(this.barDom,"noty_close_with_button");var n=document.createElement("div");a.addClass(n,"noty_close_button"),n.innerHTML="×",this.barDom.appendChild(n),a.addListener(n,"click",(function(t){a.stopPropagation(t),e.close()}),!1)}return u.fire(this,"onShow"),null===this.options.animation.open?this.promises.show=new s.default((function(t){t()})):"function"==typeof this.options.animation.open?this.promises.show=new s.default(this.options.animation.open.bind(this)):(a.addClass(this.barDom,this.options.animation.open),this.promises.show=new s.default((function(t){a.addListener(e.barDom,a.animationEndEvents,(function(){a.removeClass(e.barDom,e.options.animation.open),t()}))}))),this.promises.show.then((function(){var t=e;setTimeout((function(){u.openFlow(t)}),100)})),this}},{key:"stop",value:function(){return u.dequeueClose(this),this}},{key:"resume",value:function(){return u.queueClose(this),this}},{key:"setTimeout",value:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}((function(t){if(this.stop(),this.options.timeout=t,this.barDom){this.options.timeout?a.addClass(this.barDom,"noty_has_timeout"):a.removeClass(this.barDom,"noty_has_timeout");var e=this;setTimeout((function(){e.resume()}),100)}return this}))},{key:"setText",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.barDom&&(this.barDom.querySelector(".noty_body").innerHTML=t),e&&(this.options.text=t),this}},{key:"setType",value:function(t){var e=this,o=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.barDom&&(a.classList(this.barDom).split(" ").forEach((function(t){"noty_type__"===t.substring(0,11)&&a.removeClass(e.barDom,t)})),a.addClass(this.barDom,"noty_type__"+t)),o&&(this.options.type=t),this}},{key:"setTheme",value:function(t){var e=this,o=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.barDom&&(a.classList(this.barDom).split(" ").forEach((function(t){"noty_theme__"===t.substring(0,12)&&a.removeClass(e.barDom,t)})),a.addClass(this.barDom,"noty_theme__"+t)),o&&(this.options.theme=t),this}},{key:"close",value:function(){var t=this;return this.closed?this:this.shown?(u.fire(this,"onClose"),this.closing=!0,null===this.options.animation.close||!1===this.options.animation.close?this.promises.close=new s.default((function(t){t()})):"function"==typeof this.options.animation.close?this.promises.close=new s.default(this.options.animation.close.bind(this)):(a.addClass(this.barDom,this.options.animation.close),this.promises.close=new s.default((function(e){a.addListener(t.barDom,a.animationEndEvents,(function(){t.options.force?a.remove(t.barDom):u.ghostFix(t),e()}))}))),this.promises.close.then((function(){u.closeFlow(t),u.handleModalClose(t)})),this.closed=!0,this):(u.removeFromQueue(this),this)}}],[{key:"closeAll",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return Object.keys(u.Store).forEach((function(e){t?u.Store[e].options.queue===t&&u.Store[e].killable&&u.Store[e].close():u.Store[e].killable&&u.Store[e].close()})),this}},{key:"clearQueue",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"global";return u.Queues.hasOwnProperty(t)&&(u.Queues[t].queue=[]),this}},{key:"overrideDefaults",value:function(t){return u.Defaults=a.deepExtend({},u.Defaults,t),this}},{key:"setMaxVisible",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:u.DefaultMaxVisible,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"global";return u.Queues.hasOwnProperty(e)||(u.Queues[e]={maxVisible:t,queue:[]}),u.Queues[e].maxVisible=t,this}},{key:"button",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,o=arguments[2],n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return new l.NotyButton(t,e,o,n)}},{key:"version",value:function(){return"3.2.0-beta"}},{key:"Push",value:function(t){return new c.Push(t)}},{key:"Queues",get:function(){return u.Queues}},{key:"PageHidden",get:function(){return u.PageHidden}}]),t}();e.default=d,"undefined"!=typeof window&&a.visibilityChangeFlow(),t.exports=e.default},function(t,e){var o,n,i=t.exports={};function r(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function a(t){if(o===setTimeout)return setTimeout(t,0);if((o===r||!o)&&setTimeout)return o=setTimeout,setTimeout(t,0);try{return o(t,0)}catch(e){try{return o.call(null,t,0)}catch(e){return o.call(this,t,0)}}}!function(){try{o="function"==typeof setTimeout?setTimeout:r}catch(t){o=r}try{n="function"==typeof clearTimeout?clearTimeout:s}catch(t){n=s}}();var u,l=[],c=!1,f=-1;function d(){c&&u&&(c=!1,u.length?l=u.concat(l):f=-1,l.length&&h())}function h(){if(!c){var t=a(d);c=!0;for(var e=l.length;e;){for(u=l,l=[];++f1)for(var o=1;o { + const options: Noty.Options = { + text: envelope.message, + type: envelope.type as Type, + ...envelope.options, + } + + const noty = new Noty(options) + noty.show() + // @ts-expect-error + noty.layoutDom?.dataset.turboCache = 'false' + }) + } + + public renderOptions(options: Options): void { + Noty.overrideDefaults({ + timeout: options.timeout || 5000, + ...options, + }) + } +} diff --git a/src/Noty/Prime/Resources/dist/flasher-noty.esm.js b/src/Noty/Prime/Resources/dist/flasher-noty.esm.js new file mode 100644 index 00000000..5102e850 --- /dev/null +++ b/src/Noty/Prime/Resources/dist/flasher-noty.esm.js @@ -0,0 +1,68 @@ +import flasher from '@flasher/flasher'; +import Noty from 'noty'; + +class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } +} + +class NotyPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + envelopes.forEach((envelope) => { + var _a; + const options = Object.assign({ text: envelope.message, type: envelope.type }, envelope.options); + const noty = new Noty(options); + noty.show(); + (_a = noty.layoutDom) === null || _a === void 0 ? void 0 : _a.dataset.turboCache = 'false'; + }); + } + renderOptions(options) { + Noty.overrideDefaults(Object.assign({ timeout: options.timeout || 5000 }, options)); + } +} + +const noty = new NotyPlugin(); +flasher.addPlugin('noty', noty); + +export { noty as default }; diff --git a/src/Noty/Prime/Resources/dist/flasher-noty.js b/src/Noty/Prime/Resources/dist/flasher-noty.js new file mode 100644 index 00000000..78d29d50 --- /dev/null +++ b/src/Noty/Prime/Resources/dist/flasher-noty.js @@ -0,0 +1,73 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@flasher/flasher'), require('noty')) : + typeof define === 'function' && define.amd ? define(['@flasher/flasher', 'noty'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Noty = factory(global.flasher, global.Noty)); +})(this, (function (flasher, Noty) { 'use strict'; + + class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } + } + + class NotyPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + envelopes.forEach((envelope) => { + var _a; + const options = Object.assign({ text: envelope.message, type: envelope.type }, envelope.options); + const noty = new Noty(options); + noty.show(); + (_a = noty.layoutDom) === null || _a === void 0 ? void 0 : _a.dataset.turboCache = 'false'; + }); + } + renderOptions(options) { + Noty.overrideDefaults(Object.assign({ timeout: options.timeout || 5000 }, options)); + } + } + + const noty = new NotyPlugin(); + flasher.addPlugin('noty', noty); + + return noty; + +})); diff --git a/src/Noty/Prime/Resources/dist/flasher-noty.min.js b/src/Noty/Prime/Resources/dist/flasher-noty.min.js new file mode 100644 index 00000000..ea5c1af7 --- /dev/null +++ b/src/Noty/Prime/Resources/dist/flasher-noty.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("noty")):"function"==typeof define&&define.amd?define(["@flasher/flasher","noty"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).Noty=t(e.flasher,e.Noty)}(this,(function(e,t){"use strict";class s{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,o){if("object"==typeof e?(e=(o=e).type,t=o.message,s=o.title):"object"==typeof t?(t=(o=t).message,s=o.title):"object"==typeof s&&(s=(o=s).title),void 0===t)throw new Error("message option is required");const n={type:e,message:t,title:s||e,options:o||{},metadata:{plugin:""}};this.renderOptions(o||{}),this.renderEnvelopes([n])}}const o=new class extends s{renderEnvelopes(e){e.forEach((e=>{var s;const o=Object.assign({text:e.message,type:e.type},e.options),n=new t(o);n.show(),null===(s=n.layoutDom)||void 0===s||(s.dataset.turboCache="false")}))}renderOptions(e){t.overrideDefaults(Object.assign({timeout:e.timeout||5e3},e))}};return e.addPlugin("noty",o),o})); diff --git a/src/Noty/Prime/Resources/dist/index.d.ts b/src/Noty/Prime/Resources/dist/index.d.ts new file mode 100644 index 00000000..fe59a6f1 --- /dev/null +++ b/src/Noty/Prime/Resources/dist/index.d.ts @@ -0,0 +1,3 @@ +import NotyPlugin from './noty'; +declare const noty: NotyPlugin; +export default noty; diff --git a/src/Noty/Prime/Resources/dist/noty.d.ts b/src/Noty/Prime/Resources/dist/noty.d.ts new file mode 100644 index 00000000..c31fd0b8 --- /dev/null +++ b/src/Noty/Prime/Resources/dist/noty.d.ts @@ -0,0 +1,6 @@ +import { AbstractPlugin } from '@flasher/flasher/dist/plugin'; +import type { Envelope, Options } from '@flasher/flasher/dist/types'; +export default class NotyPlugin extends AbstractPlugin { + renderEnvelopes(envelopes: Envelope[]): void; + renderOptions(options: Options): void; +} diff --git a/src/Noty/Prime/Resources/package.json b/src/Noty/Prime/Resources/package.json new file mode 100644 index 00000000..93c083fa --- /dev/null +++ b/src/Noty/Prime/Resources/package.json @@ -0,0 +1,17 @@ +{ + "name": "@flasher/flasher-noty", + "version": "2.0.0", + "type": "module", + "license": "MIT", + "main": "dist/flasher-noty.cjs.js", + "module": "dist/flasher-noty.esm.js", + "browser": "dist/flasher-noty.umd.js", + "types": "dist/noty.d.ts", + "scripts": { + "ncu": "ncu -u" + }, + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "noty": "^3.2.0-beta-deprecated" + } +} diff --git a/src/Noty/Prime/Resources/public/flasher-noty.min.js b/src/Noty/Prime/Resources/public/flasher-noty.min.js new file mode 100644 index 00000000..ea5c1af7 --- /dev/null +++ b/src/Noty/Prime/Resources/public/flasher-noty.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("noty")):"function"==typeof define&&define.amd?define(["@flasher/flasher","noty"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).Noty=t(e.flasher,e.Noty)}(this,(function(e,t){"use strict";class s{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,o){if("object"==typeof e?(e=(o=e).type,t=o.message,s=o.title):"object"==typeof t?(t=(o=t).message,s=o.title):"object"==typeof s&&(s=(o=s).title),void 0===t)throw new Error("message option is required");const n={type:e,message:t,title:s||e,options:o||{},metadata:{plugin:""}};this.renderOptions(o||{}),this.renderEnvelopes([n])}}const o=new class extends s{renderEnvelopes(e){e.forEach((e=>{var s;const o=Object.assign({text:e.message,type:e.type},e.options),n=new t(o);n.show(),null===(s=n.layoutDom)||void 0===s||(s.dataset.turboCache="false")}))}renderOptions(e){t.overrideDefaults(Object.assign({timeout:e.timeout||5e3},e))}};return e.addPlugin("noty",o),o})); diff --git a/src/Noty/Prime/Resources/public/mint.css b/src/Noty/Prime/Resources/public/mint.css new file mode 100644 index 00000000..5d33b8cb --- /dev/null +++ b/src/Noty/Prime/Resources/public/mint.css @@ -0,0 +1,37 @@ +.noty_theme__mint.noty_bar { + margin: 4px 0; + overflow: hidden; + border-radius: 2px; + position: relative; } + .noty_theme__mint.noty_bar .noty_body { + padding: 10px; + font-size: 14px; } + .noty_theme__mint.noty_bar .noty_buttons { + padding: 10px; } + +.noty_theme__mint.noty_type__alert, +.noty_theme__mint.noty_type__notification { + background-color: #fff; + border-bottom: 1px solid #D1D1D1; + color: #2F2F2F; } + +.noty_theme__mint.noty_type__warning { + background-color: #FFAE42; + border-bottom: 1px solid #E89F3C; + color: #fff; } + +.noty_theme__mint.noty_type__error { + background-color: #DE636F; + border-bottom: 1px solid #CA5A65; + color: #fff; } + +.noty_theme__mint.noty_type__info, +.noty_theme__mint.noty_type__information { + background-color: #7F7EFF; + border-bottom: 1px solid #7473E8; + color: #fff; } + +.noty_theme__mint.noty_type__success { + background-color: #AFC765; + border-bottom: 1px solid #A0B55C; + color: #fff; } diff --git a/src/Noty/Prime/Resources/public/noty.css b/src/Noty/Prime/Resources/public/noty.css new file mode 100644 index 00000000..7cbdfb40 --- /dev/null +++ b/src/Noty/Prime/Resources/public/noty.css @@ -0,0 +1,216 @@ +.noty_layout_mixin, #noty_layout__top, #noty_layout__topLeft, #noty_layout__topCenter, #noty_layout__topRight, #noty_layout__bottom, #noty_layout__bottomLeft, #noty_layout__bottomCenter, #noty_layout__bottomRight, #noty_layout__center, #noty_layout__centerLeft, #noty_layout__centerRight { + position: fixed; + margin: 0; + padding: 0; + z-index: 9999999; + -webkit-transform: translateZ(0) scale(1, 1); + transform: translateZ(0) scale(1, 1); + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-font-smoothing: subpixel-antialiased; + filter: blur(0); + -webkit-filter: blur(0); + max-width: 90%; } + +#noty_layout__top { + top: 0; + left: 5%; + width: 90%; } + +#noty_layout__topLeft { + top: 20px; + left: 20px; + width: 325px; } + +#noty_layout__topCenter { + top: 5%; + left: 50%; + width: 325px; + -webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); + transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); } + +#noty_layout__topRight { + top: 20px; + right: 20px; + width: 325px; } + +#noty_layout__bottom { + bottom: 0; + left: 5%; + width: 90%; } + +#noty_layout__bottomLeft { + bottom: 20px; + left: 20px; + width: 325px; } + +#noty_layout__bottomCenter { + bottom: 5%; + left: 50%; + width: 325px; + -webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); + transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); } + +#noty_layout__bottomRight { + bottom: 20px; + right: 20px; + width: 325px; } + +#noty_layout__center { + top: 50%; + left: 50%; + width: 325px; + -webkit-transform: translate(-webkit-calc(-50% - .5px), -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); + transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1, 1); } + +#noty_layout__centerLeft { + top: 50%; + left: 20px; + width: 325px; + -webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); + transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); } + +#noty_layout__centerRight { + top: 50%; + right: 20px; + width: 325px; + -webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1); + transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); } + +.noty_progressbar { + display: none; } + +.noty_has_timeout.noty_has_progressbar .noty_progressbar { + display: block; + position: absolute; + left: 0; + bottom: 0; + height: 3px; + width: 100%; + background-color: #646464; + opacity: 0.2; + filter: alpha(opacity=10); } + +.noty_bar { + -webkit-backface-visibility: hidden; + -webkit-transform: translate(0, 0) translateZ(0) scale(1, 1); + -ms-transform: translate(0, 0) scale(1, 1); + transform: translate(0, 0) scale(1, 1); + -webkit-font-smoothing: subpixel-antialiased; + overflow: hidden; } + +.noty_effects_open { + opacity: 0; + -webkit-transform: translate(50%); + -ms-transform: translate(50%); + transform: translate(50%); + -webkit-animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); + animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); + -webkit-animation-fill-mode: forwards; + animation-fill-mode: forwards; } + +.noty_effects_close { + -webkit-animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); + animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); + -webkit-animation-fill-mode: forwards; + animation-fill-mode: forwards; } + +.noty_fix_effects_height { + -webkit-animation: noty_anim_height 75ms ease-out; + animation: noty_anim_height 75ms ease-out; } + +.noty_close_with_click { + cursor: pointer; } + +.noty_close_button { + position: absolute; + top: 2px; + right: 2px; + font-weight: bold; + width: 20px; + height: 20px; + text-align: center; + line-height: 20px; + background-color: rgba(0, 0, 0, 0.05); + border-radius: 2px; + cursor: pointer; + -webkit-transition: all .2s ease-out; + transition: all .2s ease-out; } + +.noty_close_button:hover { + background-color: rgba(0, 0, 0, 0.1); } + +.noty_modal { + position: fixed; + width: 100%; + height: 100%; + background-color: #000; + z-index: 10000; + opacity: .3; + left: 0; + top: 0; } + +.noty_modal.noty_modal_open { + opacity: 0; + -webkit-animation: noty_modal_in .3s ease-out; + animation: noty_modal_in .3s ease-out; } + +.noty_modal.noty_modal_close { + -webkit-animation: noty_modal_out .3s ease-out; + animation: noty_modal_out .3s ease-out; + -webkit-animation-fill-mode: forwards; + animation-fill-mode: forwards; } + +@-webkit-keyframes noty_modal_in { + 100% { + opacity: .3; } } + +@keyframes noty_modal_in { + 100% { + opacity: .3; } } + +@-webkit-keyframes noty_modal_out { + 100% { + opacity: 0; } } + +@keyframes noty_modal_out { + 100% { + opacity: 0; } } + +@keyframes noty_modal_out { + 100% { + opacity: 0; } } + +@-webkit-keyframes noty_anim_in { + 100% { + -webkit-transform: translate(0); + transform: translate(0); + opacity: 1; } } + +@keyframes noty_anim_in { + 100% { + -webkit-transform: translate(0); + transform: translate(0); + opacity: 1; } } + +@-webkit-keyframes noty_anim_out { + 100% { + -webkit-transform: translate(50%); + transform: translate(50%); + opacity: 0; } } + +@keyframes noty_anim_out { + 100% { + -webkit-transform: translate(50%); + transform: translate(50%); + opacity: 0; } } + +@-webkit-keyframes noty_anim_height { + 100% { + height: 0; } } + +@keyframes noty_anim_height { + 100% { + height: 0; } } + +/*# sourceMappingURL=noty.css.map*/ \ No newline at end of file diff --git a/src/Noty/Prime/Resources/public/noty.min.js b/src/Noty/Prime/Resources/public/noty.min.js new file mode 100644 index 00000000..7419fe09 --- /dev/null +++ b/src/Noty/Prime/Resources/public/noty.min.js @@ -0,0 +1,17 @@ +/* + @package NOTY - Dependency-free notification library + @version version: 3.2.0-beta + @contributors https://github.com/needim/noty/graphs/contributors + @documentation Examples and Documentation - https://ned.im/noty + @license Licensed under the MIT licenses: http://www.opensource.org/licenses/mit-license.php +*/ + +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("Noty",[],e):"object"==typeof exports?exports.Noty=e():t.Noty=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return t[o].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,o){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=6)}([function(t,e,n){"use strict";function o(t,e,n){var o=void 0;if(!n){for(o in e)if(e.hasOwnProperty(o)&&e[o]===t)return!0}else for(o in e)if(e.hasOwnProperty(o)&&e[o]===t)return!0;return!1}function i(t){t=t||window.event,void 0!==t.stopPropagation?t.stopPropagation():t.cancelBubble=!0}function r(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",e="noty_"+t+"_";return e+="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(t){var e=16*Math.random()|0;return("x"===t?e:3&e|8).toString(16)})}function s(t){var e=t.offsetHeight,n=window.getComputedStyle(t);return e+=parseInt(n.marginTop)+parseInt(n.marginBottom)}function u(t,e,n){var o=arguments.length>3&&void 0!==arguments[3]&&arguments[3];e=e.split(" ");for(var i=0;i=0}function c(t,e){var n=f(t),o=n+e;a(n,e)||(t.className=o.substring(1))}function l(t,e){var n=f(t),o=void 0;a(t,e)&&(o=n.replace(" "+e+" "," "),t.className=o.substring(1,o.length-1))}function d(t){t.parentNode&&t.parentNode.removeChild(t)}function f(t){return(" "+(t&&t.className||"")+" ").replace(/\s+/gi," ")}function h(){function t(){b.PageHidden=document[s],o()}function e(){b.PageHidden=!0,o()}function n(){b.PageHidden=!1,o()}function o(){b.PageHidden?i():r()}function i(){setTimeout(function(){Object.keys(b.Store).forEach(function(t){b.Store.hasOwnProperty(t)&&b.Store[t].options.visibilityControl&&b.Store[t].stop()})},100)}function r(){setTimeout(function(){Object.keys(b.Store).forEach(function(t){b.Store.hasOwnProperty(t)&&b.Store[t].options.visibilityControl&&b.Store[t].resume()}),b.queueRenderAll()},100)}var s=void 0,a=void 0;void 0!==document.hidden?(s="hidden",a="visibilitychange"):void 0!==document.msHidden?(s="msHidden",a="msvisibilitychange"):void 0!==document.webkitHidden&&(s="webkitHidden",a="webkitvisibilitychange"),a&&u(document,a,t),u(window,"blur",e),u(window,"focus",n)}function p(t){if(t.hasSound){var e=document.createElement("audio");t.options.sounds.sources.forEach(function(t){var n=document.createElement("source");n.src=t,n.type="audio/"+m(t),e.appendChild(n)}),t.barDom?t.barDom.appendChild(e):document.querySelector("body").appendChild(e),e.volume=t.options.sounds.volume,t.soundPlayed||(e.play(),t.soundPlayed=!0),e.onended=function(){d(e)}}}function m(t){return t.match(/\.([^.]+)$/)[1]}Object.defineProperty(e,"__esModule",{value:!0}),e.css=e.deepExtend=e.animationEndEvents=void 0;var v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};e.inArray=o,e.stopPropagation=i,e.generateID=r,e.outerHeight=s,e.addListener=u,e.hasClass=a,e.addClass=c,e.removeClass=l,e.remove=d,e.classList=f,e.visibilityChangeFlow=h,e.createAudioElements=p;var y=n(1),b=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}(y);e.animationEndEvents="webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",e.deepExtend=function t(e){e=e||{};for(var n=1;n0&&void 0!==arguments[0]?arguments[0]:"global",e=0,n=x;return E.hasOwnProperty(t)&&(n=E[t].maxVisible,Object.keys(P).forEach(function(n){P[n].options.queue!==t||P[n].closed||e++})),{current:e,maxVisible:n}}function i(t){E.hasOwnProperty(t.options.queue)||(E[t.options.queue]={maxVisible:x,queue:[]}),E[t.options.queue].queue.push(t)}function r(t){if(E.hasOwnProperty(t.options.queue)){var e=[];Object.keys(E[t.options.queue].queue).forEach(function(n){E[t.options.queue].queue[n].id!==t.id&&e.push(E[t.options.queue].queue[n])}),E[t.options.queue].queue=e}}function s(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"global";if(E.hasOwnProperty(t)){var e=E[t].queue.shift();e&&e.show()}}function u(){Object.keys(E).forEach(function(t){s(t)})}function a(t){var e=k.generateID("ghost"),n=document.createElement("div");n.setAttribute("id",e),k.css(n,{height:k.outerHeight(t.barDom)+"px"}),t.barDom.insertAdjacentHTML("afterend",n.outerHTML),k.remove(t.barDom),n=document.getElementById(e),k.addClass(n,"noty_fix_effects_height"),k.addListener(n,k.animationEndEvents,function(){k.remove(n)})}function c(t){m(t);var e='
'+t.options.text+"
"+d(t)+'
';t.barDom=document.createElement("div"),t.barDom.setAttribute("id",t.id),k.addClass(t.barDom,"noty_bar noty_type__"+t.options.type+" noty_theme__"+t.options.theme),t.barDom.innerHTML=e,b(t,"onTemplate")}function l(t){return!(!t.options.buttons||!Object.keys(t.options.buttons).length)}function d(t){if(l(t)){var e=document.createElement("div");return k.addClass(e,"noty_buttons"),Object.keys(t.options.buttons).forEach(function(n){e.appendChild(t.options.buttons[n].dom)}),t.options.buttons.forEach(function(t){e.appendChild(t.dom)}),e.outerHTML}return""}function f(t){t.options.modal&&(0===C&&p(),e.DocModalCount=C+=1)}function h(t){if(t.options.modal&&C>0&&(e.DocModalCount=C-=1,C<=0)){var n=document.querySelector(".noty_modal");n&&(k.removeClass(n,"noty_modal_open"),k.addClass(n,"noty_modal_close"),k.addListener(n,k.animationEndEvents,function(){k.remove(n)}))}}function p(){var t=document.querySelector("body"),e=document.createElement("div");k.addClass(e,"noty_modal"),t.insertBefore(e,t.firstChild),k.addClass(e,"noty_modal_open"),k.addListener(e,k.animationEndEvents,function(){k.removeClass(e,"noty_modal_open")})}function m(t){if(t.options.container)return void(t.layoutDom=document.querySelector(t.options.container));var e="noty_layout__"+t.options.layout;t.layoutDom=document.querySelector("div#"+e),t.layoutDom||(t.layoutDom=document.createElement("div"),t.layoutDom.setAttribute("id",e),t.layoutDom.setAttribute("role","alert"),t.layoutDom.setAttribute("aria-live","polite"),k.addClass(t.layoutDom,"noty_layout"),document.querySelector("body").appendChild(t.layoutDom))}function v(t){t.options.timeout&&(t.options.progressBar&&t.progressDom&&k.css(t.progressDom,{transition:"width "+t.options.timeout+"ms linear",width:"0%"}),clearTimeout(t.closeTimer),t.closeTimer=setTimeout(function(){t.close()},t.options.timeout))}function y(t){t.options.timeout&&t.closeTimer&&(clearTimeout(t.closeTimer),t.closeTimer=-1,t.options.progressBar&&t.progressDom&&k.css(t.progressDom,{transition:"width 0ms linear",width:"100%"}))}function b(t,e){t.listeners.hasOwnProperty(e)&&t.listeners[e].forEach(function(e){"function"==typeof e&&e.apply(t)})}function w(t){b(t,"afterShow"),v(t),k.addListener(t.barDom,"mouseenter",function(){y(t)}),k.addListener(t.barDom,"mouseleave",function(){v(t)})}function g(t){delete P[t.id],t.closing=!1,b(t,"afterClose"),k.remove(t.barDom),0!==t.layoutDom.querySelectorAll(".noty_bar").length||t.options.container||k.remove(t.layoutDom),(k.inArray("docVisible",t.options.titleCount.conditions)||k.inArray("docHidden",t.options.titleCount.conditions))&&D.decrement(),s(t.options.queue)}Object.defineProperty(e,"__esModule",{value:!0}),e.Defaults=e.Store=e.Queues=e.DefaultMaxVisible=e.docTitle=e.DocModalCount=e.PageHidden=void 0,e.getQueueCounts=o,e.addToQueue=i,e.removeFromQueue=r,e.queueRender=s,e.queueRenderAll=u,e.ghostFix=a,e.build=c,e.hasButtons=l,e.handleModal=f,e.handleModalClose=h,e.queueClose=v,e.dequeueClose=y,e.fire=b,e.openFlow=w,e.closeFlow=g;var _=n(0),k=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}(_),C=(e.PageHidden=!1,e.DocModalCount=0),S={originalTitle:null,count:0,changed:!1,timer:-1},D=e.docTitle={increment:function(){S.count++,D._update()},decrement:function(){if(--S.count<=0)return void D._clear();D._update()},_update:function(){var t=document.title;S.changed?document.title="("+S.count+") "+S.originalTitle:(S.originalTitle=t,document.title="("+S.count+") "+t,S.changed=!0)},_clear:function(){S.changed&&(S.count=0,document.title=S.originalTitle,S.changed=!1)}},x=e.DefaultMaxVisible=5,E=e.Queues={global:{maxVisible:x,queue:[]}},P=e.Store={};e.Defaults={type:"alert",layout:"topRight",theme:"mint",text:"",timeout:!1,progressBar:!0,closeWith:["click"],animation:{open:"noty_effects_open",close:"noty_effects_close"},id:!1,force:!1,killer:!1,queue:"global",container:!1,buttons:[],callbacks:{beforeShow:null,onShow:null,afterShow:null,onClose:null,afterClose:null,onClick:null,onHover:null,onTemplate:null},sounds:{sources:[],volume:1,conditions:[]},titleCount:{conditions:[]},modal:!1,visibilityControl:!1}},function(t,e,n){"use strict";function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0}),e.NotyButton=void 0;var i=n(0),r=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e.default=t,e}(i);e.NotyButton=function t(e,n,i){var s=this,u=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return o(this,t),this.dom=document.createElement("button"),this.dom.innerHTML=e,this.id=u.id=u.id||r.generateID("button"),this.cb=i,Object.keys(u).forEach(function(t){s.dom.setAttribute(t,u[t])}),r.addClass(this.dom,n||"noty_btn"),this}},function(t,e,n){"use strict";function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:"/service-worker.js";return o(this,t),this.subData={},this.workerPath=e,this.listeners={onPermissionGranted:[],onPermissionDenied:[],onSubscriptionSuccess:[],onSubscriptionCancel:[],onWorkerError:[],onWorkerSuccess:[],onWorkerNotSupported:[]},this}return i(t,[{key:"on",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};return"function"==typeof e&&this.listeners.hasOwnProperty(t)&&this.listeners[t].push(e),this}},{key:"fire",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];this.listeners.hasOwnProperty(t)&&this.listeners[t].forEach(function(t){"function"==typeof t&&t.apply(e,n)})}},{key:"create",value:function(){console.log("NOT IMPLEMENTED YET")}},{key:"isSupported",value:function(){var t=!1;try{t=window.Notification||window.webkitNotifications||navigator.mozNotification||window.external&&void 0!==window.external.msIsSiteMode()}catch(t){}return t}},{key:"getPermissionStatus",value:function(){var t="default";if(window.Notification&&window.Notification.permissionLevel)t=window.Notification.permissionLevel;else if(window.webkitNotifications&&window.webkitNotifications.checkPermission)switch(window.webkitNotifications.checkPermission()){case 1:t="default";break;case 0:t="granted";break;default:t="denied"}else window.Notification&&window.Notification.permission?t=window.Notification.permission:navigator.mozNotification?t="granted":window.external&&void 0!==window.external.msIsSiteMode()&&(t=window.external.msIsSiteMode()?"granted":"default");return t.toString().toLowerCase()}},{key:"getEndpoint",value:function(t){var e=t.endpoint,n=t.subscriptionId;return n&&-1===e.indexOf(n)&&(e+="/"+n),e}},{key:"isSWRegistered",value:function(){try{return"activated"===navigator.serviceWorker.controller.state}catch(t){return!1}}},{key:"unregisterWorker",value:function(){var t=this;"serviceWorker"in navigator&&navigator.serviceWorker.getRegistrations().then(function(e){var n=!0,o=!1,i=void 0;try{for(var r,s=e[Symbol.iterator]();!(n=(r=s.next()).done);n=!0){r.value.unregister(),t.fire("onSubscriptionCancel")}}catch(t){o=!0,i=t}finally{try{!n&&s.return&&s.return()}finally{if(o)throw i}}})}},{key:"requestSubscription",value:function(){var t=this,e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],n=this,o=this.getPermissionStatus(),i=function(o){"granted"===o?(t.fire("onPermissionGranted"),"serviceWorker"in navigator?navigator.serviceWorker.register(t.workerPath).then(function(){navigator.serviceWorker.ready.then(function(t){n.fire("onWorkerSuccess"),t.pushManager.subscribe({userVisibleOnly:e}).then(function(t){var e=t.getKey("p256dh"),o=t.getKey("auth");n.subData={endpoint:n.getEndpoint(t),p256dh:e?window.btoa(String.fromCharCode.apply(null,new Uint8Array(e))):null,auth:o?window.btoa(String.fromCharCode.apply(null,new Uint8Array(o))):null},n.fire("onSubscriptionSuccess",[n.subData])}).catch(function(t){n.fire("onWorkerError",[t])})})}):n.fire("onWorkerNotSupported")):"denied"===o&&(t.fire("onPermissionDenied"),t.unregisterWorker())};"default"===o?window.Notification&&window.Notification.requestPermission?window.Notification.requestPermission(i):window.webkitNotifications&&window.webkitNotifications.checkPermission&&window.webkitNotifications.requestPermission(i):i(o)}}]),t}()},function(t,e,n){(function(e,o){/*! + * @overview es6-promise - a tiny implementation of Promises/A+. + * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) + * @license Licensed under MIT license + * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE + * @version 4.1.1 + */ +!function(e,n){t.exports=n()}(0,function(){"use strict";function t(t){var e=typeof t;return null!==t&&("object"===e||"function"===e)}function i(t){return"function"==typeof t}function r(t){z=t}function s(t){U=t}function u(){return void 0!==R?function(){R(c)}:a()}function a(){var t=setTimeout;return function(){return t(c,1)}}function c(){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{};return i(this,t),this.options=c.deepExtend({},d.Defaults,e),d.Store[this.options.id]?d.Store[this.options.id]:(this.id=this.options.id||c.generateID("bar"),this.closeTimer=-1,this.barDom=null,this.layoutDom=null,this.progressDom=null,this.showing=!1,this.shown=!1,this.closed=!1,this.closing=!1,this.killable=this.options.timeout||this.options.closeWith.length>0,this.hasSound=this.options.sounds.sources.length>0,this.soundPlayed=!1,this.listeners={beforeShow:[],onShow:[],afterShow:[],onClose:[],afterClose:[],onClick:[],onHover:[],onTemplate:[]},this.promises={show:null,close:null},this.on("beforeShow",this.options.callbacks.beforeShow),this.on("onShow",this.options.callbacks.onShow),this.on("afterShow",this.options.callbacks.afterShow),this.on("onClose",this.options.callbacks.onClose),this.on("afterClose",this.options.callbacks.afterClose),this.on("onClick",this.options.callbacks.onClick),this.on("onHover",this.options.callbacks.onHover),this.on("onTemplate",this.options.callbacks.onTemplate),this)}return r(t,[{key:"on",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};return"function"==typeof e&&this.listeners.hasOwnProperty(t)&&this.listeners[t].push(e),this}},{key:"show",value:function(){var e=this;if(this.showing||this.shown)return this;!0===this.options.killer?t.closeAll():"string"==typeof this.options.killer&&t.closeAll(this.options.killer);var n=d.getQueueCounts(this.options.queue);if(n.current>=n.maxVisible||d.PageHidden&&this.options.visibilityControl)return d.addToQueue(this),d.PageHidden&&this.hasSound&&c.inArray("docHidden",this.options.sounds.conditions)&&c.createAudioElements(this),d.PageHidden&&c.inArray("docHidden",this.options.titleCount.conditions)&&d.docTitle.increment(),this;if(d.Store[this.id]=this,d.fire(this,"beforeShow"),this.showing=!0,this.closing)return this.showing=!1,this;if(d.build(this),d.handleModal(this),this.options.force?this.layoutDom.insertBefore(this.barDom,this.layoutDom.firstChild):this.layoutDom.appendChild(this.barDom),this.hasSound&&!this.soundPlayed&&c.inArray("docVisible",this.options.sounds.conditions)&&c.createAudioElements(this),c.inArray("docVisible",this.options.titleCount.conditions)&&d.docTitle.increment(),this.shown=!0,this.closed=!1,d.hasButtons(this)&&Object.keys(this.options.buttons).forEach(function(t){var n=e.barDom.querySelector("#"+e.options.buttons[t].id);c.addListener(n,"click",function(n){c.stopPropagation(n),e.options.buttons[t].cb(e)})}),this.progressDom=this.barDom.querySelector(".noty_progressbar"),c.inArray("click",this.options.closeWith)&&(c.addClass(this.barDom,"noty_close_with_click"),c.addListener(this.barDom,"click",function(t){c.stopPropagation(t),d.fire(e,"onClick"),e.close()},!1)),c.addListener(this.barDom,"mouseenter",function(){d.fire(e,"onHover")},!1),this.options.timeout&&c.addClass(this.barDom,"noty_has_timeout"),this.options.progressBar&&c.addClass(this.barDom,"noty_has_progressbar"),c.inArray("button",this.options.closeWith)){c.addClass(this.barDom,"noty_close_with_button");var o=document.createElement("div");c.addClass(o,"noty_close_button"),o.innerHTML="×",this.barDom.appendChild(o),c.addListener(o,"click",function(t){c.stopPropagation(t),e.close()},!1)}return d.fire(this,"onShow"),null===this.options.animation.open?this.promises.show=new u.default(function(t){t()}):"function"==typeof this.options.animation.open?this.promises.show=new u.default(this.options.animation.open.bind(this)):(c.addClass(this.barDom,this.options.animation.open),this.promises.show=new u.default(function(t){c.addListener(e.barDom,c.animationEndEvents,function(){c.removeClass(e.barDom,e.options.animation.open),t()})})),this.promises.show.then(function(){var t=e;setTimeout(function(){d.openFlow(t)},100)}),this}},{key:"stop",value:function(){return d.dequeueClose(this),this}},{key:"resume",value:function(){return d.queueClose(this),this}},{key:"setTimeout",value:function(t){function e(e){return t.apply(this,arguments)}return e.toString=function(){return t.toString()},e}(function(t){if(this.stop(),this.options.timeout=t,this.barDom){this.options.timeout?c.addClass(this.barDom,"noty_has_timeout"):c.removeClass(this.barDom,"noty_has_timeout");var e=this;setTimeout(function(){e.resume()},100)}return this})},{key:"setText",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return this.barDom&&(this.barDom.querySelector(".noty_body").innerHTML=t),e&&(this.options.text=t),this}},{key:"setType",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(this.barDom){c.classList(this.barDom).split(" ").forEach(function(t){"noty_type__"===t.substring(0,11)&&c.removeClass(e.barDom,t)}),c.addClass(this.barDom,"noty_type__"+t)}return n&&(this.options.type=t),this}},{key:"setTheme",value:function(t){var e=this,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(this.barDom){c.classList(this.barDom).split(" ").forEach(function(t){"noty_theme__"===t.substring(0,12)&&c.removeClass(e.barDom,t)}),c.addClass(this.barDom,"noty_theme__"+t)}return n&&(this.options.theme=t),this}},{key:"close",value:function(){var t=this;return this.closed?this:this.shown?(d.fire(this,"onClose"),this.closing=!0,null===this.options.animation.close||!1===this.options.animation.close?this.promises.close=new u.default(function(t){t()}):"function"==typeof this.options.animation.close?this.promises.close=new u.default(this.options.animation.close.bind(this)):(c.addClass(this.barDom,this.options.animation.close),this.promises.close=new u.default(function(e){c.addListener(t.barDom,c.animationEndEvents,function(){t.options.force?c.remove(t.barDom):d.ghostFix(t),e()})})),this.promises.close.then(function(){d.closeFlow(t),d.handleModalClose(t)}),this.closed=!0,this):(d.removeFromQueue(this),this)}}],[{key:"closeAll",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];return Object.keys(d.Store).forEach(function(e){t?d.Store[e].options.queue===t&&d.Store[e].killable&&d.Store[e].close():d.Store[e].killable&&d.Store[e].close()}),this}},{key:"clearQueue",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"global";return d.Queues.hasOwnProperty(t)&&(d.Queues[t].queue=[]),this}},{key:"overrideDefaults",value:function(t){return d.Defaults=c.deepExtend({},d.Defaults,t),this}},{key:"setMaxVisible",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:d.DefaultMaxVisible,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"global";return d.Queues.hasOwnProperty(e)||(d.Queues[e]={maxVisible:t,queue:[]}),d.Queues[e].maxVisible=t,this}},{key:"button",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=arguments[2],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return new f.NotyButton(t,e,n,o)}},{key:"version",value:function(){return"3.2.0-beta"}},{key:"Push",value:function(t){return new h.Push(t)}},{key:"Queues",get:function(){return d.Queues}},{key:"PageHidden",get:function(){return d.PageHidden}}]),t}();e.default=p,"undefined"!=typeof window&&c.visibilityChangeFlow(),t.exports=e.default},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function i(t){if(l===setTimeout)return setTimeout(t,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(t,0);try{return l(t,0)}catch(e){try{return l.call(null,t,0)}catch(e){return l.call(this,t,0)}}}function r(t){if(d===clearTimeout)return clearTimeout(t);if((d===o||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(t);try{return d(t)}catch(e){try{return d.call(null,t)}catch(e){return d.call(this,t)}}}function s(){m&&h&&(m=!1,h.length?p=h.concat(p):v=-1,p.length&&u())}function u(){if(!m){var t=i(s);m=!0;for(var e=p.length;e;){for(h=p,p=[];++v1)for(var n=1;n=5.3", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Noty\\Prime\\": "" }, "files": [ + "functions.php", "helpers.php" ] }, diff --git a/src/Noty/Prime/functions.php b/src/Noty/Prime/functions.php new file mode 100644 index 00000000..6f3b17ae --- /dev/null +++ b/src/Noty/Prime/functions.php @@ -0,0 +1,42 @@ + $options additional options for the Noty notification + * @param string|null $title the title of the notification + * + * @return Envelope|NotyInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of NotyInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Noty factory: $noty = noty(); + * 2. With arguments - Create and return a Noty notification: + * noty('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); + */ + function noty(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|NotyInterface + { + $factory = FlasherContainer::create('flasher.noty'); + + if (0 === \func_num_args()) { + return $factory; + } + + return $factory->flash($type, $message, $options, $title); + } +} diff --git a/src/Noty/Prime/helpers.php b/src/Noty/Prime/helpers.php index fb463340..9db91fe1 100644 --- a/src/Noty/Prime/helpers.php +++ b/src/Noty/Prime/helpers.php @@ -1,32 +1,41 @@ - */ +declare(strict_types=1); -use Flasher\Noty\Prime\NotyFactory; +use Flasher\Noty\Prime\NotyInterface; use Flasher\Prime\Container\FlasherContainer; use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; +use Flasher\Prime\Notification\Type; if (!function_exists('noty')) { /** - * @param string $message - * @param string $type - * @param array $options + * Creates a Noty notification or returns the Noty factory. * - * @return Envelope|NotyFactory + * This function simplifies the process of creating Noty notifications. + * When called with no arguments, it returns an instance of NotyInterface. + * When called with arguments, it creates a Noty notification and returns an Envelope. + * + * @param string|null $message the message content of the notification + * @param string $type The type of the notification (e.g., success, error, warning, info). + * @param array $options additional options for the Noty notification + * @param string|null $title the title of the notification + * + * @return Envelope|NotyInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of NotyInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Noty factory: $noty = noty(); + * 2. With arguments - Create and return a Noty notification: + * noty('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); */ - function noty($message = null, $type = NotificationInterface::SUCCESS, array $options = array()) + function noty(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|NotyInterface { - /** @var NotyFactory $factory */ $factory = FlasherContainer::create('flasher.noty'); if (0 === func_num_args()) { return $factory; } - return $factory->addFlash($type, $message, $options); + return $factory->flash($type, $message, $options, $title); } } diff --git a/src/Noty/Symfony/.github/FUNDING.yml b/src/Noty/Symfony/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Noty/Symfony/.github/FUNDING.yml +++ b/src/Noty/Symfony/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Noty/Symfony/.github/workflows/auto_closer.yaml b/src/Noty/Symfony/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Noty/Symfony/.github/workflows/auto_closer.yaml +++ b/src/Noty/Symfony/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Noty/Symfony/FlasherNotyBundle.php b/src/Noty/Symfony/FlasherNotyBundle.php new file mode 100644 index 00000000..a033cf08 --- /dev/null +++ b/src/Noty/Symfony/FlasherNotyBundle.php @@ -0,0 +1,17 @@ + - */ - -namespace Flasher\Noty\Symfony; - -use Flasher\Noty\Prime\NotyPlugin; -use Flasher\Symfony\Support\Bundle; - -class FlasherNotySymfonyBundle extends Bundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - /** - * {@inheritDoc} - */ - public function createPlugin() - { - return new NotyPlugin(); - } -} diff --git a/src/Noty/Symfony/LICENSE b/src/Noty/Symfony/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Noty/Symfony/LICENSE +++ b/src/Noty/Symfony/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Noty/Symfony/README.md b/src/Noty/Symfony/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Noty/Symfony/README.md +++ b/src/Noty/Symfony/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Noty/Symfony/Resources/config/config.yaml b/src/Noty/Symfony/Resources/config/config.yaml deleted file mode 100644 index d347668f..00000000 --- a/src/Noty/Symfony/Resources/config/config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -flasher_noty: - scripts: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-noty@1.3.2/dist/flasher-noty.min.js' - local: - - '/vendor/flasher/flasher-noty.min.js' - - styles: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-noty@1.3.2/dist/flasher-noty.min.css' - local: - - '/vendor/flasher/flasher-noty.min.css' diff --git a/src/Noty/Symfony/composer.json b/src/Noty/Symfony/composer.json index c67412b5..ce3222a5 100644 --- a/src/Noty/Symfony/composer.json +++ b/src/Noty/Symfony/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-noty-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "symfony-bundle", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-noty": "^1.15.14", - "php-flasher/flasher-symfony": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-noty": "^2.0", + "php-flasher/flasher-symfony": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Noty\\Symfony\\": "" diff --git a/src/Notyf/Laravel/.github/FUNDING.yml b/src/Notyf/Laravel/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Notyf/Laravel/.github/FUNDING.yml +++ b/src/Notyf/Laravel/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Notyf/Laravel/.github/workflows/auto_closer.yaml b/src/Notyf/Laravel/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Notyf/Laravel/.github/workflows/auto_closer.yaml +++ b/src/Notyf/Laravel/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Notyf/Laravel/Facade/Notyf.php b/src/Notyf/Laravel/Facade/Notyf.php index feebf75a..9b73a72e 100644 --- a/src/Notyf/Laravel/Facade/Notyf.php +++ b/src/Notyf/Laravel/Facade/Notyf.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Notyf\Laravel\Facade; @@ -42,9 +39,9 @@ use Illuminate\Support\Facades\Facade; * @method static NotyfBuilder position(string $position, string $value) * @method static NotyfBuilder dismissible(bool $dismissible) */ -class Notyf extends Facade +final class Notyf extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'flasher.notyf'; } diff --git a/src/Notyf/Laravel/FlasherNotyfServiceProvider.php b/src/Notyf/Laravel/FlasherNotyfServiceProvider.php index 39beb321..d43ca3a4 100644 --- a/src/Notyf/Laravel/FlasherNotyfServiceProvider.php +++ b/src/Notyf/Laravel/FlasherNotyfServiceProvider.php @@ -1,21 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\Notyf\Laravel; -use Flasher\Laravel\Support\ServiceProvider; +use Flasher\Laravel\Support\PluginServiceProvider; use Flasher\Notyf\Prime\NotyfPlugin; -final class FlasherNotyfServiceProvider extends ServiceProvider +final class FlasherNotyfServiceProvider extends PluginServiceProvider { - /** - * {@inheritDoc} - */ - public function createPlugin() + public function createPlugin(): NotyfPlugin { return new NotyfPlugin(); } diff --git a/src/Notyf/Laravel/LICENSE b/src/Notyf/Laravel/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Notyf/Laravel/LICENSE +++ b/src/Notyf/Laravel/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Notyf/Laravel/README.md b/src/Notyf/Laravel/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Notyf/Laravel/README.md +++ b/src/Notyf/Laravel/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Notyf/Laravel/Resources/config.php b/src/Notyf/Laravel/Resources/config.php deleted file mode 100644 index 3dec6121..00000000 --- a/src/Notyf/Laravel/Resources/config.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -return array( - 'scripts' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-notyf@1.3.2/dist/flasher-notyf.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-notyf.min.js', - ), - ), - 'styles' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-notyf@1.3.2/dist/flasher-notyf.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-notyf.min.css', - ), - ), -); diff --git a/src/Notyf/Laravel/composer.json b/src/Notyf/Laravel/composer.json index b830239e..c5b8ba29 100644 --- a/src/Notyf/Laravel/composer.json +++ b/src/Notyf/Laravel/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-notyf-laravel", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-laravel": "^1.15.14", - "php-flasher/flasher-notyf": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-laravel": "^2.0", + "php-flasher/flasher-notyf": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Notyf\\Laravel\\": "" @@ -53,12 +47,12 @@ }, "extra": { "laravel": { - "aliases": { - "Notyf": "Flasher\\Notyf\\Laravel\\Facade\\Notyf" - }, "providers": [ "Flasher\\Notyf\\Laravel\\FlasherNotyfServiceProvider" - ] + ], + "aliases": { + "Notyf": "Flasher\\Notyf\\Laravel\\Facade\\Notyf" + } } } } diff --git a/src/Notyf/Prime/.github/FUNDING.yml b/src/Notyf/Prime/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Notyf/Prime/.github/FUNDING.yml +++ b/src/Notyf/Prime/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Notyf/Prime/.github/workflows/auto_closer.yaml b/src/Notyf/Prime/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Notyf/Prime/.github/workflows/auto_closer.yaml +++ b/src/Notyf/Prime/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Notyf/Prime/.phpstorm.meta.php b/src/Notyf/Prime/.phpstorm.meta.php index bb3c887d..a00f6082 100644 --- a/src/Notyf/Prime/.phpstorm.meta.php +++ b/src/Notyf/Prime/.phpstorm.meta.php @@ -3,14 +3,12 @@ namespace PHPSTORM_META; expectedArguments(\notyf(), 1, 'success', 'error', 'info', 'warning'); +expectedArguments(\Flasher\Notyf\Prime\notyf(), 1, 'success', 'error', 'info', 'warning'); + expectedArguments(\Flasher\Notyf\Prime\NotyfBuilder::duration(), 0, 1000, 2000, 3000, 4000, 5000); expectedArguments(\Flasher\Notyf\Prime\NotyfBuilder::position(), 0, 'x', 'y'); expectedArguments(\Flasher\Notyf\Prime\NotyfBuilder::position(), 1, 'top', 'right', 'bottom', 'left', 'center'); -override(\Flasher\Prime\FlasherInterface::create(), map([ - 'notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, -])); +override(\Flasher\Prime\FlasherInterface::use(), map(['notyf' => \Flasher\Notyf\Prime\NotyfInterface::class])); +override(\Flasher\Prime\Container\FlasherContainer::create(), map(['flasher.notyf' => \Notyf\Notyf\Prime\NotyfInterface::class])); -override(\Flasher\Prime\FlasherInterface::using(), map([ - 'notyf' => \Flasher\Notyf\Prime\NotyfFactory::class, -])); diff --git a/src/Notyf/Prime/LICENSE b/src/Notyf/Prime/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Notyf/Prime/LICENSE +++ b/src/Notyf/Prime/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Notyf/Prime/Notyf.php b/src/Notyf/Prime/Notyf.php new file mode 100644 index 00000000..66d5faf7 --- /dev/null +++ b/src/Notyf/Prime/Notyf.php @@ -0,0 +1,18 @@ +storageManager); + } +} diff --git a/src/Notyf/Prime/NotyfBuilder.php b/src/Notyf/Prime/NotyfBuilder.php index 80ddfbdc..468a391c 100644 --- a/src/Notyf/Prime/NotyfBuilder.php +++ b/src/Notyf/Prime/NotyfBuilder.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Notyf\Prime; @@ -13,12 +10,8 @@ final class NotyfBuilder extends NotificationBuilder { /** * Number of miliseconds before hiding the notification. Use 0 for infinite duration. - * - * @param int $duration - * - * @return static */ - public function duration($duration) + public function duration(int $duration): self { $this->option('duration', $duration); @@ -27,12 +20,8 @@ final class NotyfBuilder extends NotificationBuilder /** * Whether to show the notification with a ripple effect. - * - * @param bool $ripple - * - * @return static */ - public function ripple($ripple) + public function ripple(bool $ripple = true): self { $this->option('ripple', $ripple); @@ -42,14 +31,12 @@ final class NotyfBuilder extends NotificationBuilder /** * Viewport location where notifications are rendered. * - * @param string $position - * @param string $value - * - * @return static + * @param "x"|"y" $position + * @param "left"|"center"|"right"|"top"|"bottom" $value */ - public function position($position, $value) + public function position(string $position, string $value): self { - $option = $this->getEnvelope()->getOption('position', array()); + $option = $this->getEnvelope()->getOption('position', []); $option[$position] = $value; // @phpstan-ignore-line $this->option('position', $option); @@ -59,12 +46,8 @@ final class NotyfBuilder extends NotificationBuilder /** * Whether to allow users to dismiss the notification with a button. - * - * @param bool $dismissible - * - * @return static */ - public function dismissible($dismissible) + public function dismissible(bool $dismissible): self { $this->option('dismissible', $dismissible); diff --git a/src/Notyf/Prime/NotyfFactory.php b/src/Notyf/Prime/NotyfFactory.php deleted file mode 100644 index 23e8a71e..00000000 --- a/src/Notyf/Prime/NotyfFactory.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Flasher\Notyf\Prime; - -use Flasher\Prime\Factory\NotificationFactory; -use Flasher\Prime\Notification\Notification; - -/** - * @mixin NotyfBuilder - */ -final class NotyfFactory extends NotificationFactory -{ - public function createNotificationBuilder() - { - return new NotyfBuilder($this->getStorageManager(), new Notification(), 'notyf'); - } -} diff --git a/src/Notyf/Prime/NotyfInterface.php b/src/Notyf/Prime/NotyfInterface.php new file mode 100644 index 00000000..b638e7d4 --- /dev/null +++ b/src/Notyf/Prime/NotyfInterface.php @@ -0,0 +1,14 @@ + - */ +declare(strict_types=1); namespace Flasher\Notyf\Prime; use Flasher\Prime\Plugin\Plugin; -class NotyfPlugin extends Plugin +final class NotyfPlugin extends Plugin { - /** - * {@inheritdoc} - */ - public function getScripts() + public function getAlias(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-notyf@1.3.2/dist/flasher-notyf.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-notyf.min.js', - ), - ); + return 'notyf'; } - /** - * {@inheritdoc} - */ - public function getStyles() + public function getFactory(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-notyf@1.3.2/dist/flasher-notyf.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-notyf.min.css', - ), - ); + return Notyf::class; + } + + public function getServiceAliases(): string + { + return NotyfInterface::class; + } + + public function getScripts(): string|array + { + return [ + '/vendor/flasher/flasher-notyf.min.js', + ]; + } + + public function getStyles(): string|array + { + return [ + '/vendor/flasher/flasher-notyf.min.css', + ]; } } diff --git a/src/Notyf/Prime/README.md b/src/Notyf/Prime/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Notyf/Prime/README.md +++ b/src/Notyf/Prime/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Notyf/Prime/Resources/assets/flasher-notyf.min.css b/src/Notyf/Prime/Resources/assets/flasher-notyf.min.css deleted file mode 100644 index bdd85b3a..00000000 --- a/src/Notyf/Prime/Resources/assets/flasher-notyf.min.css +++ /dev/null @@ -1,2 +0,0 @@ -.notyf__icon--info,.notyf__icon--warning{background:#fff;border-radius:50%;box-sizing:border-box;display:block;height:1em;margin:0 auto;position:relative;width:1em}.notyf__icon--info:after,.notyf__icon--info:before,.notyf__icon--warning:after,.notyf__icon--warning:before{border-width:0;box-sizing:border-box;content:"";position:absolute;transition:all 1s}.notyf__icon--info:after,.notyf__icon--info:before{background-color:currentColor;border-radius:.03em;left:50%;transform:translateX(-50%);width:.15em}.notyf__icon--info:before{height:.38em;top:.4em}.notyf__icon--info:after{box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.notyf__icon--warning:after,.notyf__icon--warning:before{background-color:currentColor;border-radius:.03em;left:50%;transform:translateX(-50%);width:.15em}.notyf__icon--warning:before{height:.38em;top:.21em}.notyf__icon--warning:after{height:.13em;top:.65em} -@-webkit-keyframes notyf-fadeinup{0%{opacity:0;transform:translateY(25%)}to{opacity:1;transform:translateY(0)}}@keyframes notyf-fadeinup{0%{opacity:0;transform:translateY(25%)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes notyf-fadeinleft{0%{opacity:0;transform:translateX(25%)}to{opacity:1;transform:translateX(0)}}@keyframes notyf-fadeinleft{0%{opacity:0;transform:translateX(25%)}to{opacity:1;transform:translateX(0)}}@-webkit-keyframes notyf-fadeoutright{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(25%)}}@keyframes notyf-fadeoutright{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(25%)}}@-webkit-keyframes notyf-fadeoutdown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(25%)}}@keyframes notyf-fadeoutdown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(25%)}}@-webkit-keyframes ripple{0%{transform:scale(0) translateY(-45%) translateX(13%)}to{transform:scale(1) translateY(-45%) translateX(13%)}}@keyframes ripple{0%{transform:scale(0) translateY(-45%) translateX(13%)}to{transform:scale(1) translateY(-45%) translateX(13%)}}.notyf{align-items:flex-end;box-sizing:border-box;color:#fff;display:flex;flex-direction:column;height:100%;justify-content:flex-end;left:0;padding:20px;pointer-events:none;position:fixed;top:0;width:100%;z-index:9999}.notyf__icon--error,.notyf__icon--success{background:#fff;border-radius:50%;display:block;height:21px;margin:0 auto;position:relative;width:21px}.notyf__icon--error:after,.notyf__icon--error:before{background:currentColor;border-radius:3px;content:"";display:block;height:12px;left:9px;position:absolute;top:5px;width:3px}.notyf__icon--error:after{transform:rotate(-45deg)}.notyf__icon--error:before{transform:rotate(45deg)}.notyf__icon--success:after,.notyf__icon--success:before{background:currentColor;border-radius:3px;content:"";display:block;position:absolute;width:3px}.notyf__icon--success:after{height:6px;left:6px;top:9px;transform:rotate(-45deg)}.notyf__icon--success:before{height:11px;left:10px;top:5px;transform:rotate(45deg)}.notyf__toast{-webkit-animation:notyf-fadeinup .3s ease-in forwards;animation:notyf-fadeinup .3s ease-in forwards;border-radius:2px;box-shadow:0 3px 7px 0 rgba(0,0,0,.25);box-sizing:border-box;display:block;flex-shrink:0;max-width:300px;overflow:hidden;padding:0 15px;pointer-events:auto;position:relative;transform:translateY(25%)}.notyf__toast--disappear{-webkit-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;-webkit-animation-delay:.25s;animation-delay:.25s;transform:translateY(0)}.notyf__toast--disappear .notyf__icon,.notyf__toast--disappear .notyf__message{-webkit-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;opacity:1;transform:translateY(0)}.notyf__toast--disappear .notyf__dismiss{-webkit-animation:notyf-fadeoutright .3s forwards;animation:notyf-fadeoutright .3s forwards;opacity:1;transform:translateX(0)}.notyf__toast--disappear .notyf__message{-webkit-animation-delay:.05s;animation-delay:.05s}.notyf__toast--upper{margin-bottom:20px}.notyf__toast--lower{margin-top:20px}.notyf__toast--dismissible .notyf__wrapper{padding-right:30px}.notyf__ripple{-webkit-animation:ripple .4s ease-out forwards;animation:ripple .4s ease-out forwards;border-radius:50%;height:400px;position:absolute;right:0;top:0;transform:scale(0) translateY(-51%) translateX(13%);transform-origin:bottom right;width:400px;z-index:5}.notyf__wrapper{align-items:center;border-radius:3px;display:flex;padding-bottom:17px;padding-right:15px;padding-top:17px;position:relative;z-index:10}.notyf__icon{-webkit-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.3s;animation-delay:.3s;font-size:1.3em;margin-right:13px;opacity:0;text-align:center;width:22px}.notyf__dismiss{-webkit-animation:notyf-fadeinleft .3s forwards;animation:notyf-fadeinleft .3s forwards;-webkit-animation-delay:.35s;animation-delay:.35s;height:100%;margin-right:-15px;opacity:0;position:absolute;right:0;top:0;width:26px}.notyf__dismiss-btn{background-color:rgba(0,0,0,.25);border:none;cursor:pointer;height:100%;opacity:.35;outline:none;transition:opacity .2s ease,background-color .2s ease;width:100%}.notyf__dismiss-btn:after,.notyf__dismiss-btn:before{background:#fff;border-radius:3px;content:"";height:12px;left:calc(50% - 1px);position:absolute;top:calc(50% - 5px);width:2px}.notyf__dismiss-btn:after{transform:rotate(-45deg)}.notyf__dismiss-btn:before{transform:rotate(45deg)}.notyf__dismiss-btn:hover{background-color:rgba(0,0,0,.15);opacity:.7}.notyf__dismiss-btn:active{opacity:.8}.notyf__message{-webkit-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.25s;animation-delay:.25s;line-height:1.5em;opacity:0;position:relative;vertical-align:middle}@media only screen and (max-width:480px){.notyf{padding:0}.notyf__ripple{-webkit-animation-duration:.5s;animation-duration:.5s;height:600px;width:600px}.notyf__toast{border-radius:0;box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);max-width:none;width:100%}.notyf__dismiss{width:56px}} \ No newline at end of file diff --git a/src/Notyf/Prime/Resources/assets/flasher-notyf.min.js b/src/Notyf/Prime/Resources/assets/flasher-notyf.min.js deleted file mode 100644 index e7e0a3a9..00000000 --- a/src/Notyf/Prime/Resources/assets/flasher-notyf.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):((t="undefined"!=typeof globalThis?globalThis:t||self).flasher=t.flasher||{},t.flasher.notyf=i(t.flasher))}(this,(function(t){"use strict";var i,n=function(){return n=Object.assign||function(t){for(var i,n=1,e=arguments.length;n { + const options = { ...envelope, ...envelope.options } + this.notyf?.open(options) + }) + + // @ts-expect-error + this.notyf.view.container.dataset.turboCache = 'false' + // @ts-expect-error + this.notyf.view.a11yContainer.dataset.turboCache = 'false' + } + + public renderOptions(options: Options): void { + const nOptions = { + duration: options.duration || 5000, + ...options, + } as unknown as INotyfOptions + + nOptions.types = nOptions.types || [] + + nOptions.types.push({ + type: 'info', + className: 'notyf__toast--info', + background: '#5784E5', + icon: { + className: 'notyf__icon--info', + tagName: 'i', + }, + }) + + nOptions.types.push({ + type: 'warning', + className: 'notyf__toast--warning', + background: '#E3A008', + icon: { + className: 'notyf__icon--warning', + tagName: 'i', + }, + }) + + this.notyf = this.notyf || new Notyf(nOptions as Partial) + } +} diff --git a/src/Notyf/Prime/Resources/dist/flasher-notyf.esm.js b/src/Notyf/Prime/Resources/dist/flasher-notyf.esm.js new file mode 100644 index 00000000..c90a8d39 --- /dev/null +++ b/src/Notyf/Prime/Resources/dist/flasher-notyf.esm.js @@ -0,0 +1,460 @@ +import flasher from '@flasher/flasher'; + +class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } +} + +var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var NotyfNotification = (function () { + function NotyfNotification(options) { + this.options = options; + this.listeners = {}; + } + NotyfNotification.prototype.on = function (eventType, cb) { + var callbacks = this.listeners[eventType] || []; + this.listeners[eventType] = callbacks.concat([cb]); + }; + NotyfNotification.prototype.triggerEvent = function (eventType, event) { + var _this = this; + var callbacks = this.listeners[eventType] || []; + callbacks.forEach(function (cb) { return cb({ target: _this, event: event }); }); + }; + return NotyfNotification; +}()); +var NotyfArrayEvent; +(function (NotyfArrayEvent) { + NotyfArrayEvent[NotyfArrayEvent["Add"] = 0] = "Add"; + NotyfArrayEvent[NotyfArrayEvent["Remove"] = 1] = "Remove"; +})(NotyfArrayEvent || (NotyfArrayEvent = {})); +var NotyfArray = (function () { + function NotyfArray() { + this.notifications = []; + } + NotyfArray.prototype.push = function (elem) { + this.notifications.push(elem); + this.updateFn(elem, NotyfArrayEvent.Add, this.notifications); + }; + NotyfArray.prototype.splice = function (index, num) { + var elem = this.notifications.splice(index, num)[0]; + this.updateFn(elem, NotyfArrayEvent.Remove, this.notifications); + return elem; + }; + NotyfArray.prototype.indexOf = function (elem) { + return this.notifications.indexOf(elem); + }; + NotyfArray.prototype.onUpdate = function (fn) { + this.updateFn = fn; + }; + return NotyfArray; +}()); +var NotyfEvent; +(function (NotyfEvent) { + NotyfEvent["Dismiss"] = "dismiss"; + NotyfEvent["Click"] = "click"; +})(NotyfEvent || (NotyfEvent = {})); +var DEFAULT_OPTIONS = { + types: [ + { + type: 'success', + className: 'notyf__toast--success', + backgroundColor: '#3dc763', + icon: { + className: 'notyf__icon--success', + tagName: 'i', + }, + }, + { + type: 'error', + className: 'notyf__toast--error', + backgroundColor: '#ed3d3d', + icon: { + className: 'notyf__icon--error', + tagName: 'i', + }, + }, + ], + duration: 2000, + ripple: true, + position: { + x: 'right', + y: 'bottom', + }, + dismissible: false, +}; +var NotyfView = (function () { + function NotyfView() { + this.notifications = []; + this.events = {}; + this.X_POSITION_FLEX_MAP = { + left: 'flex-start', + center: 'center', + right: 'flex-end', + }; + this.Y_POSITION_FLEX_MAP = { + top: 'flex-start', + center: 'center', + bottom: 'flex-end', + }; + var docFrag = document.createDocumentFragment(); + var notyfContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf' }); + docFrag.appendChild(notyfContainer); + document.body.appendChild(docFrag); + this.container = notyfContainer; + this.animationEndEventName = this._getAnimationEndEventName(); + this._createA11yContainer(); + } + NotyfView.prototype.on = function (event, cb) { + var _a; + this.events = __assign(__assign({}, this.events), (_a = {}, _a[event] = cb, _a)); + }; + NotyfView.prototype.update = function (notification, type) { + if (type === NotyfArrayEvent.Add) { + this.addNotification(notification); + } + else if (type === NotyfArrayEvent.Remove) { + this.removeNotification(notification); + } + }; + NotyfView.prototype.removeNotification = function (notification) { + var _this = this; + var renderedNotification = this._popRenderedNotification(notification); + var node; + if (!renderedNotification) { + return; + } + node = renderedNotification.node; + node.classList.add('notyf__toast--disappear'); + var handleEvent; + node.addEventListener(this.animationEndEventName, (handleEvent = function (event) { + if (event.target === node) { + node.removeEventListener(_this.animationEndEventName, handleEvent); + _this.container.removeChild(node); + } + })); + }; + NotyfView.prototype.addNotification = function (notification) { + var node = this._renderNotification(notification); + this.notifications.push({ notification: notification, node: node }); + this._announce(notification.options.message || 'Notification'); + }; + NotyfView.prototype._renderNotification = function (notification) { + var _a; + var card = this._buildNotificationCard(notification); + var className = notification.options.className; + if (className) { + (_a = card.classList).add.apply(_a, className.split(' ')); + } + this.container.appendChild(card); + return card; + }; + NotyfView.prototype._popRenderedNotification = function (notification) { + var idx = -1; + for (var i = 0; i < this.notifications.length && idx < 0; i++) { + if (this.notifications[i].notification === notification) { + idx = i; + } + } + if (idx !== -1) { + return this.notifications.splice(idx, 1)[0]; + } + return; + }; + NotyfView.prototype.getXPosition = function (options) { + var _a; + return ((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.x) || 'right'; + }; + NotyfView.prototype.getYPosition = function (options) { + var _a; + return ((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.y) || 'bottom'; + }; + NotyfView.prototype.adjustContainerAlignment = function (options) { + var align = this.X_POSITION_FLEX_MAP[this.getXPosition(options)]; + var justify = this.Y_POSITION_FLEX_MAP[this.getYPosition(options)]; + var style = this.container.style; + style.setProperty('justify-content', justify); + style.setProperty('align-items', align); + }; + NotyfView.prototype._buildNotificationCard = function (notification) { + var _this = this; + var options = notification.options; + var iconOpts = options.icon; + this.adjustContainerAlignment(options); + var notificationElem = this._createHTMLElement({ tagName: 'div', className: 'notyf__toast' }); + var ripple = this._createHTMLElement({ tagName: 'div', className: 'notyf__ripple' }); + var wrapper = this._createHTMLElement({ tagName: 'div', className: 'notyf__wrapper' }); + var message = this._createHTMLElement({ tagName: 'div', className: 'notyf__message' }); + message.innerHTML = options.message || ''; + var mainColor = options.background || options.backgroundColor; + if (iconOpts) { + var iconContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf__icon' }); + if (typeof iconOpts === 'string' || iconOpts instanceof String) + iconContainer.innerHTML = new String(iconOpts).valueOf(); + if (typeof iconOpts === 'object') { + var _a = iconOpts.tagName, tagName = _a === void 0 ? 'i' : _a, className_1 = iconOpts.className, text = iconOpts.text, _b = iconOpts.color, color = _b === void 0 ? mainColor : _b; + var iconElement = this._createHTMLElement({ tagName: tagName, className: className_1, text: text }); + if (color) + iconElement.style.color = color; + iconContainer.appendChild(iconElement); + } + wrapper.appendChild(iconContainer); + } + wrapper.appendChild(message); + notificationElem.appendChild(wrapper); + if (mainColor) { + if (options.ripple) { + ripple.style.background = mainColor; + notificationElem.appendChild(ripple); + } + else { + notificationElem.style.background = mainColor; + } + } + if (options.dismissible) { + var dismissWrapper = this._createHTMLElement({ tagName: 'div', className: 'notyf__dismiss' }); + var dismissButton = this._createHTMLElement({ + tagName: 'button', + className: 'notyf__dismiss-btn', + }); + dismissWrapper.appendChild(dismissButton); + wrapper.appendChild(dismissWrapper); + notificationElem.classList.add("notyf__toast--dismissible"); + dismissButton.addEventListener('click', function (event) { + var _a, _b; + (_b = (_a = _this.events)[NotyfEvent.Dismiss]) === null || _b === void 0 ? void 0 : _b.call(_a, { target: notification, event: event }); + event.stopPropagation(); + }); + } + notificationElem.addEventListener('click', function (event) { var _a, _b; return (_b = (_a = _this.events)[NotyfEvent.Click]) === null || _b === void 0 ? void 0 : _b.call(_a, { target: notification, event: event }); }); + var className = this.getYPosition(options) === 'top' ? 'upper' : 'lower'; + notificationElem.classList.add("notyf__toast--" + className); + return notificationElem; + }; + NotyfView.prototype._createHTMLElement = function (_a) { + var tagName = _a.tagName, className = _a.className, text = _a.text; + var elem = document.createElement(tagName); + if (className) { + elem.className = className; + } + elem.textContent = text || null; + return elem; + }; + NotyfView.prototype._createA11yContainer = function () { + var a11yContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf-announcer' }); + a11yContainer.setAttribute('aria-atomic', 'true'); + a11yContainer.setAttribute('aria-live', 'polite'); + a11yContainer.style.border = '0'; + a11yContainer.style.clip = 'rect(0 0 0 0)'; + a11yContainer.style.height = '1px'; + a11yContainer.style.margin = '-1px'; + a11yContainer.style.overflow = 'hidden'; + a11yContainer.style.padding = '0'; + a11yContainer.style.position = 'absolute'; + a11yContainer.style.width = '1px'; + a11yContainer.style.outline = '0'; + document.body.appendChild(a11yContainer); + this.a11yContainer = a11yContainer; + }; + NotyfView.prototype._announce = function (message) { + var _this = this; + this.a11yContainer.textContent = ''; + setTimeout(function () { + _this.a11yContainer.textContent = message; + }, 100); + }; + NotyfView.prototype._getAnimationEndEventName = function () { + var el = document.createElement('_fake'); + var transitions = { + MozTransition: 'animationend', + OTransition: 'oAnimationEnd', + WebkitTransition: 'webkitAnimationEnd', + transition: 'animationend', + }; + var t; + for (t in transitions) { + if (el.style[t] !== undefined) { + return transitions[t]; + } + } + return 'animationend'; + }; + return NotyfView; +}()); +var Notyf = (function () { + function Notyf(opts) { + var _this = this; + this.dismiss = this._removeNotification; + this.notifications = new NotyfArray(); + this.view = new NotyfView(); + var types = this.registerTypes(opts); + this.options = __assign(__assign({}, DEFAULT_OPTIONS), opts); + this.options.types = types; + this.notifications.onUpdate(function (elem, type) { return _this.view.update(elem, type); }); + this.view.on(NotyfEvent.Dismiss, function (_a) { + var target = _a.target, event = _a.event; + _this._removeNotification(target); + target['triggerEvent'](NotyfEvent.Dismiss, event); + }); + this.view.on(NotyfEvent.Click, function (_a) { + var target = _a.target, event = _a.event; + return target['triggerEvent'](NotyfEvent.Click, event); + }); + } + Notyf.prototype.error = function (payload) { + var options = this.normalizeOptions('error', payload); + return this.open(options); + }; + Notyf.prototype.success = function (payload) { + var options = this.normalizeOptions('success', payload); + return this.open(options); + }; + Notyf.prototype.open = function (options) { + var defaultOpts = this.options.types.find(function (_a) { + var type = _a.type; + return type === options.type; + }) || {}; + var config = __assign(__assign({}, defaultOpts), options); + this.assignProps(['ripple', 'position', 'dismissible'], config); + var notification = new NotyfNotification(config); + this._pushNotification(notification); + return notification; + }; + Notyf.prototype.dismissAll = function () { + while (this.notifications.splice(0, 1)) + ; + }; + Notyf.prototype.assignProps = function (props, config) { + var _this = this; + props.forEach(function (prop) { + config[prop] = config[prop] == null ? _this.options[prop] : config[prop]; + }); + }; + Notyf.prototype._pushNotification = function (notification) { + var _this = this; + this.notifications.push(notification); + var duration = notification.options.duration !== undefined ? notification.options.duration : this.options.duration; + if (duration) { + setTimeout(function () { return _this._removeNotification(notification); }, duration); + } + }; + Notyf.prototype._removeNotification = function (notification) { + var index = this.notifications.indexOf(notification); + if (index !== -1) { + this.notifications.splice(index, 1); + } + }; + Notyf.prototype.normalizeOptions = function (type, payload) { + var options = { type: type }; + if (typeof payload === 'string') { + options.message = payload; + } + else if (typeof payload === 'object') { + options = __assign(__assign({}, options), payload); + } + return options; + }; + Notyf.prototype.registerTypes = function (opts) { + var incomingTypes = ((opts && opts.types) || []).slice(); + var finalDefaultTypes = DEFAULT_OPTIONS.types.map(function (defaultType) { + var userTypeIdx = -1; + incomingTypes.forEach(function (t, idx) { + if (t.type === defaultType.type) + userTypeIdx = idx; + }); + var userType = userTypeIdx !== -1 ? incomingTypes.splice(userTypeIdx, 1)[0] : {}; + return __assign(__assign({}, defaultType), userType); + }); + return finalDefaultTypes.concat(incomingTypes); + }; + return Notyf; +}()); + +class NotyfPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + envelopes.forEach((envelope) => { + var _a; + const options = Object.assign(Object.assign({}, envelope), envelope.options); + (_a = this.notyf) === null || _a === void 0 ? void 0 : _a.open(options); + }); + this.notyf.view.container.dataset.turboCache = 'false'; + this.notyf.view.a11yContainer.dataset.turboCache = 'false'; + } + renderOptions(options) { + const nOptions = Object.assign({ duration: options.duration || 5000 }, options); + nOptions.types = nOptions.types || []; + nOptions.types.push({ + type: 'info', + className: 'notyf__toast--info', + background: '#5784E5', + icon: { + className: 'notyf__icon--info', + tagName: 'i', + }, + }); + nOptions.types.push({ + type: 'warning', + className: 'notyf__toast--warning', + background: '#E3A008', + icon: { + className: 'notyf__icon--warning', + tagName: 'i', + }, + }); + this.notyf = this.notyf || new Notyf(nOptions); + } +} + +const notyf = new NotyfPlugin(); +flasher.addPlugin('notyf', notyf); + +export { notyf as default }; diff --git a/src/Notyf/Prime/Resources/dist/flasher-notyf.js b/src/Notyf/Prime/Resources/dist/flasher-notyf.js new file mode 100644 index 00000000..75b93402 --- /dev/null +++ b/src/Notyf/Prime/Resources/dist/flasher-notyf.js @@ -0,0 +1,466 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@flasher/flasher')) : + typeof define === 'function' && define.amd ? define(['@flasher/flasher'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.notyf = factory(global.flasher)); +})(this, (function (flasher) { 'use strict'; + + class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } + } + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + var NotyfNotification = (function () { + function NotyfNotification(options) { + this.options = options; + this.listeners = {}; + } + NotyfNotification.prototype.on = function (eventType, cb) { + var callbacks = this.listeners[eventType] || []; + this.listeners[eventType] = callbacks.concat([cb]); + }; + NotyfNotification.prototype.triggerEvent = function (eventType, event) { + var _this = this; + var callbacks = this.listeners[eventType] || []; + callbacks.forEach(function (cb) { return cb({ target: _this, event: event }); }); + }; + return NotyfNotification; + }()); + var NotyfArrayEvent; + (function (NotyfArrayEvent) { + NotyfArrayEvent[NotyfArrayEvent["Add"] = 0] = "Add"; + NotyfArrayEvent[NotyfArrayEvent["Remove"] = 1] = "Remove"; + })(NotyfArrayEvent || (NotyfArrayEvent = {})); + var NotyfArray = (function () { + function NotyfArray() { + this.notifications = []; + } + NotyfArray.prototype.push = function (elem) { + this.notifications.push(elem); + this.updateFn(elem, NotyfArrayEvent.Add, this.notifications); + }; + NotyfArray.prototype.splice = function (index, num) { + var elem = this.notifications.splice(index, num)[0]; + this.updateFn(elem, NotyfArrayEvent.Remove, this.notifications); + return elem; + }; + NotyfArray.prototype.indexOf = function (elem) { + return this.notifications.indexOf(elem); + }; + NotyfArray.prototype.onUpdate = function (fn) { + this.updateFn = fn; + }; + return NotyfArray; + }()); + var NotyfEvent; + (function (NotyfEvent) { + NotyfEvent["Dismiss"] = "dismiss"; + NotyfEvent["Click"] = "click"; + })(NotyfEvent || (NotyfEvent = {})); + var DEFAULT_OPTIONS = { + types: [ + { + type: 'success', + className: 'notyf__toast--success', + backgroundColor: '#3dc763', + icon: { + className: 'notyf__icon--success', + tagName: 'i', + }, + }, + { + type: 'error', + className: 'notyf__toast--error', + backgroundColor: '#ed3d3d', + icon: { + className: 'notyf__icon--error', + tagName: 'i', + }, + }, + ], + duration: 2000, + ripple: true, + position: { + x: 'right', + y: 'bottom', + }, + dismissible: false, + }; + var NotyfView = (function () { + function NotyfView() { + this.notifications = []; + this.events = {}; + this.X_POSITION_FLEX_MAP = { + left: 'flex-start', + center: 'center', + right: 'flex-end', + }; + this.Y_POSITION_FLEX_MAP = { + top: 'flex-start', + center: 'center', + bottom: 'flex-end', + }; + var docFrag = document.createDocumentFragment(); + var notyfContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf' }); + docFrag.appendChild(notyfContainer); + document.body.appendChild(docFrag); + this.container = notyfContainer; + this.animationEndEventName = this._getAnimationEndEventName(); + this._createA11yContainer(); + } + NotyfView.prototype.on = function (event, cb) { + var _a; + this.events = __assign(__assign({}, this.events), (_a = {}, _a[event] = cb, _a)); + }; + NotyfView.prototype.update = function (notification, type) { + if (type === NotyfArrayEvent.Add) { + this.addNotification(notification); + } + else if (type === NotyfArrayEvent.Remove) { + this.removeNotification(notification); + } + }; + NotyfView.prototype.removeNotification = function (notification) { + var _this = this; + var renderedNotification = this._popRenderedNotification(notification); + var node; + if (!renderedNotification) { + return; + } + node = renderedNotification.node; + node.classList.add('notyf__toast--disappear'); + var handleEvent; + node.addEventListener(this.animationEndEventName, (handleEvent = function (event) { + if (event.target === node) { + node.removeEventListener(_this.animationEndEventName, handleEvent); + _this.container.removeChild(node); + } + })); + }; + NotyfView.prototype.addNotification = function (notification) { + var node = this._renderNotification(notification); + this.notifications.push({ notification: notification, node: node }); + this._announce(notification.options.message || 'Notification'); + }; + NotyfView.prototype._renderNotification = function (notification) { + var _a; + var card = this._buildNotificationCard(notification); + var className = notification.options.className; + if (className) { + (_a = card.classList).add.apply(_a, className.split(' ')); + } + this.container.appendChild(card); + return card; + }; + NotyfView.prototype._popRenderedNotification = function (notification) { + var idx = -1; + for (var i = 0; i < this.notifications.length && idx < 0; i++) { + if (this.notifications[i].notification === notification) { + idx = i; + } + } + if (idx !== -1) { + return this.notifications.splice(idx, 1)[0]; + } + return; + }; + NotyfView.prototype.getXPosition = function (options) { + var _a; + return ((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.x) || 'right'; + }; + NotyfView.prototype.getYPosition = function (options) { + var _a; + return ((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.y) || 'bottom'; + }; + NotyfView.prototype.adjustContainerAlignment = function (options) { + var align = this.X_POSITION_FLEX_MAP[this.getXPosition(options)]; + var justify = this.Y_POSITION_FLEX_MAP[this.getYPosition(options)]; + var style = this.container.style; + style.setProperty('justify-content', justify); + style.setProperty('align-items', align); + }; + NotyfView.prototype._buildNotificationCard = function (notification) { + var _this = this; + var options = notification.options; + var iconOpts = options.icon; + this.adjustContainerAlignment(options); + var notificationElem = this._createHTMLElement({ tagName: 'div', className: 'notyf__toast' }); + var ripple = this._createHTMLElement({ tagName: 'div', className: 'notyf__ripple' }); + var wrapper = this._createHTMLElement({ tagName: 'div', className: 'notyf__wrapper' }); + var message = this._createHTMLElement({ tagName: 'div', className: 'notyf__message' }); + message.innerHTML = options.message || ''; + var mainColor = options.background || options.backgroundColor; + if (iconOpts) { + var iconContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf__icon' }); + if (typeof iconOpts === 'string' || iconOpts instanceof String) + iconContainer.innerHTML = new String(iconOpts).valueOf(); + if (typeof iconOpts === 'object') { + var _a = iconOpts.tagName, tagName = _a === void 0 ? 'i' : _a, className_1 = iconOpts.className, text = iconOpts.text, _b = iconOpts.color, color = _b === void 0 ? mainColor : _b; + var iconElement = this._createHTMLElement({ tagName: tagName, className: className_1, text: text }); + if (color) + iconElement.style.color = color; + iconContainer.appendChild(iconElement); + } + wrapper.appendChild(iconContainer); + } + wrapper.appendChild(message); + notificationElem.appendChild(wrapper); + if (mainColor) { + if (options.ripple) { + ripple.style.background = mainColor; + notificationElem.appendChild(ripple); + } + else { + notificationElem.style.background = mainColor; + } + } + if (options.dismissible) { + var dismissWrapper = this._createHTMLElement({ tagName: 'div', className: 'notyf__dismiss' }); + var dismissButton = this._createHTMLElement({ + tagName: 'button', + className: 'notyf__dismiss-btn', + }); + dismissWrapper.appendChild(dismissButton); + wrapper.appendChild(dismissWrapper); + notificationElem.classList.add("notyf__toast--dismissible"); + dismissButton.addEventListener('click', function (event) { + var _a, _b; + (_b = (_a = _this.events)[NotyfEvent.Dismiss]) === null || _b === void 0 ? void 0 : _b.call(_a, { target: notification, event: event }); + event.stopPropagation(); + }); + } + notificationElem.addEventListener('click', function (event) { var _a, _b; return (_b = (_a = _this.events)[NotyfEvent.Click]) === null || _b === void 0 ? void 0 : _b.call(_a, { target: notification, event: event }); }); + var className = this.getYPosition(options) === 'top' ? 'upper' : 'lower'; + notificationElem.classList.add("notyf__toast--" + className); + return notificationElem; + }; + NotyfView.prototype._createHTMLElement = function (_a) { + var tagName = _a.tagName, className = _a.className, text = _a.text; + var elem = document.createElement(tagName); + if (className) { + elem.className = className; + } + elem.textContent = text || null; + return elem; + }; + NotyfView.prototype._createA11yContainer = function () { + var a11yContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf-announcer' }); + a11yContainer.setAttribute('aria-atomic', 'true'); + a11yContainer.setAttribute('aria-live', 'polite'); + a11yContainer.style.border = '0'; + a11yContainer.style.clip = 'rect(0 0 0 0)'; + a11yContainer.style.height = '1px'; + a11yContainer.style.margin = '-1px'; + a11yContainer.style.overflow = 'hidden'; + a11yContainer.style.padding = '0'; + a11yContainer.style.position = 'absolute'; + a11yContainer.style.width = '1px'; + a11yContainer.style.outline = '0'; + document.body.appendChild(a11yContainer); + this.a11yContainer = a11yContainer; + }; + NotyfView.prototype._announce = function (message) { + var _this = this; + this.a11yContainer.textContent = ''; + setTimeout(function () { + _this.a11yContainer.textContent = message; + }, 100); + }; + NotyfView.prototype._getAnimationEndEventName = function () { + var el = document.createElement('_fake'); + var transitions = { + MozTransition: 'animationend', + OTransition: 'oAnimationEnd', + WebkitTransition: 'webkitAnimationEnd', + transition: 'animationend', + }; + var t; + for (t in transitions) { + if (el.style[t] !== undefined) { + return transitions[t]; + } + } + return 'animationend'; + }; + return NotyfView; + }()); + var Notyf = (function () { + function Notyf(opts) { + var _this = this; + this.dismiss = this._removeNotification; + this.notifications = new NotyfArray(); + this.view = new NotyfView(); + var types = this.registerTypes(opts); + this.options = __assign(__assign({}, DEFAULT_OPTIONS), opts); + this.options.types = types; + this.notifications.onUpdate(function (elem, type) { return _this.view.update(elem, type); }); + this.view.on(NotyfEvent.Dismiss, function (_a) { + var target = _a.target, event = _a.event; + _this._removeNotification(target); + target['triggerEvent'](NotyfEvent.Dismiss, event); + }); + this.view.on(NotyfEvent.Click, function (_a) { + var target = _a.target, event = _a.event; + return target['triggerEvent'](NotyfEvent.Click, event); + }); + } + Notyf.prototype.error = function (payload) { + var options = this.normalizeOptions('error', payload); + return this.open(options); + }; + Notyf.prototype.success = function (payload) { + var options = this.normalizeOptions('success', payload); + return this.open(options); + }; + Notyf.prototype.open = function (options) { + var defaultOpts = this.options.types.find(function (_a) { + var type = _a.type; + return type === options.type; + }) || {}; + var config = __assign(__assign({}, defaultOpts), options); + this.assignProps(['ripple', 'position', 'dismissible'], config); + var notification = new NotyfNotification(config); + this._pushNotification(notification); + return notification; + }; + Notyf.prototype.dismissAll = function () { + while (this.notifications.splice(0, 1)) + ; + }; + Notyf.prototype.assignProps = function (props, config) { + var _this = this; + props.forEach(function (prop) { + config[prop] = config[prop] == null ? _this.options[prop] : config[prop]; + }); + }; + Notyf.prototype._pushNotification = function (notification) { + var _this = this; + this.notifications.push(notification); + var duration = notification.options.duration !== undefined ? notification.options.duration : this.options.duration; + if (duration) { + setTimeout(function () { return _this._removeNotification(notification); }, duration); + } + }; + Notyf.prototype._removeNotification = function (notification) { + var index = this.notifications.indexOf(notification); + if (index !== -1) { + this.notifications.splice(index, 1); + } + }; + Notyf.prototype.normalizeOptions = function (type, payload) { + var options = { type: type }; + if (typeof payload === 'string') { + options.message = payload; + } + else if (typeof payload === 'object') { + options = __assign(__assign({}, options), payload); + } + return options; + }; + Notyf.prototype.registerTypes = function (opts) { + var incomingTypes = ((opts && opts.types) || []).slice(); + var finalDefaultTypes = DEFAULT_OPTIONS.types.map(function (defaultType) { + var userTypeIdx = -1; + incomingTypes.forEach(function (t, idx) { + if (t.type === defaultType.type) + userTypeIdx = idx; + }); + var userType = userTypeIdx !== -1 ? incomingTypes.splice(userTypeIdx, 1)[0] : {}; + return __assign(__assign({}, defaultType), userType); + }); + return finalDefaultTypes.concat(incomingTypes); + }; + return Notyf; + }()); + + class NotyfPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + envelopes.forEach((envelope) => { + var _a; + const options = Object.assign(Object.assign({}, envelope), envelope.options); + (_a = this.notyf) === null || _a === void 0 ? void 0 : _a.open(options); + }); + this.notyf.view.container.dataset.turboCache = 'false'; + this.notyf.view.a11yContainer.dataset.turboCache = 'false'; + } + renderOptions(options) { + const nOptions = Object.assign({ duration: options.duration || 5000 }, options); + nOptions.types = nOptions.types || []; + nOptions.types.push({ + type: 'info', + className: 'notyf__toast--info', + background: '#5784E5', + icon: { + className: 'notyf__icon--info', + tagName: 'i', + }, + }); + nOptions.types.push({ + type: 'warning', + className: 'notyf__toast--warning', + background: '#E3A008', + icon: { + className: 'notyf__icon--warning', + tagName: 'i', + }, + }); + this.notyf = this.notyf || new Notyf(nOptions); + } + } + + const notyf = new NotyfPlugin(); + flasher.addPlugin('notyf', notyf); + + return notyf; + +})); diff --git a/src/Notyf/Prime/Resources/dist/flasher-notyf.min.css b/src/Notyf/Prime/Resources/dist/flasher-notyf.min.css new file mode 100644 index 00000000..f6e64571 --- /dev/null +++ b/src/Notyf/Prime/Resources/dist/flasher-notyf.min.css @@ -0,0 +1,2 @@ +.notyf__icon--info,.notyf__icon--warning{background:#fff;border-radius:50%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;height:1em;margin:0 auto;position:relative;width:1em}.notyf__icon--info:after,.notyf__icon--info:before,.notyf__icon--warning:after,.notyf__icon--warning:before{border-width:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;content:"";position:absolute;-webkit-transition:all 1s;-moz-transition:all 1s;transition:all 1s}.notyf__icon--info:after,.notyf__icon--info:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.notyf__icon--info:before{height:.38em;top:.4em}.notyf__icon--info:after{-webkit-box-shadow:-.06em .19em,-.06em .44em,.06em .44em;box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.notyf__icon--warning:after,.notyf__icon--warning:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.notyf__icon--warning:before{height:.38em;top:.21em}.notyf__icon--warning:after{height:.13em;top:.65em} +@-webkit-keyframes notyf-fadeinup{0%{opacity:0;-webkit-transform:translateY(25%);transform:translateY(25%)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes notyf-fadeinup{0%{opacity:0;-moz-transform:translateY(25%);transform:translateY(25%)}to{opacity:1;-moz-transform:translateY(0);transform:translateY(0)}}@keyframes notyf-fadeinup{0%{opacity:0;-webkit-transform:translateY(25%);-moz-transform:translateY(25%);transform:translateY(25%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes notyf-fadeinleft{0%{opacity:0;-webkit-transform:translateX(25%);transform:translateX(25%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-moz-keyframes notyf-fadeinleft{0%{opacity:0;-moz-transform:translateX(25%);transform:translateX(25%)}to{opacity:1;-moz-transform:translateX(0);transform:translateX(0)}}@keyframes notyf-fadeinleft{0%{opacity:0;-webkit-transform:translateX(25%);-moz-transform:translateX(25%);transform:translateX(25%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes notyf-fadeoutright{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(25%);transform:translateX(25%)}}@-moz-keyframes notyf-fadeoutright{0%{opacity:1;-moz-transform:translateX(0);transform:translateX(0)}to{opacity:0;-moz-transform:translateX(25%);transform:translateX(25%)}}@keyframes notyf-fadeoutright{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(25%);-moz-transform:translateX(25%);transform:translateX(25%)}}@-webkit-keyframes notyf-fadeoutdown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(25%);transform:translateY(25%)}}@-moz-keyframes notyf-fadeoutdown{0%{opacity:1;-moz-transform:translateY(0);transform:translateY(0)}to{opacity:0;-moz-transform:translateY(25%);transform:translateY(25%)}}@keyframes notyf-fadeoutdown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(25%);-moz-transform:translateY(25%);transform:translateY(25%)}}@-webkit-keyframes ripple{0%{-webkit-transform:scale(0) translateY(-45%) translateX(13%);transform:scale(0) translateY(-45%) translateX(13%)}to{-webkit-transform:scale(1) translateY(-45%) translateX(13%);transform:scale(1) translateY(-45%) translateX(13%)}}@-moz-keyframes ripple{0%{-moz-transform:scale(0) translateY(-45%) translateX(13%);transform:scale(0) translateY(-45%) translateX(13%)}to{-moz-transform:scale(1) translateY(-45%) translateX(13%);transform:scale(1) translateY(-45%) translateX(13%)}}@keyframes ripple{0%{-webkit-transform:scale(0) translateY(-45%) translateX(13%);-moz-transform:scale(0) translateY(-45%) translateX(13%);transform:scale(0) translateY(-45%) translateX(13%)}to{-webkit-transform:scale(1) translateY(-45%) translateX(13%);-moz-transform:scale(1) translateY(-45%) translateX(13%);transform:scale(1) translateY(-45%) translateX(13%)}}.notyf{-webkit-box-align:end;-webkit-align-items:flex-end;-moz-box-align:end;align-items:flex-end;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#fff;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-moz-box-orient:vertical;-moz-box-direction:normal;flex-direction:column;height:100%;-webkit-box-pack:end;-webkit-justify-content:flex-end;-moz-box-pack:end;justify-content:flex-end;left:0;padding:20px;pointer-events:none;position:fixed;top:0;width:100%;z-index:9999}.notyf__icon--error,.notyf__icon--success{background:#fff;border-radius:50%;display:block;height:21px;margin:0 auto;position:relative;width:21px}.notyf__icon--error:after,.notyf__icon--error:before{background:currentColor;border-radius:3px;content:"";display:block;height:12px;left:9px;position:absolute;top:5px;width:3px}.notyf__icon--error:after{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.notyf__icon--error:before{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.notyf__icon--success:after,.notyf__icon--success:before{background:currentColor;border-radius:3px;content:"";display:block;position:absolute;width:3px}.notyf__icon--success:after{height:6px;left:6px;top:9px;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.notyf__icon--success:before{height:11px;left:10px;top:5px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.notyf__toast{-webkit-animation:notyf-fadeinup .3s ease-in forwards;-moz-animation:notyf-fadeinup .3s ease-in forwards;animation:notyf-fadeinup .3s ease-in forwards;border-radius:2px;-webkit-box-shadow:0 3px 7px 0 rgba(0,0,0,.25);box-shadow:0 3px 7px 0 rgba(0,0,0,.25);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;-webkit-flex-shrink:0;flex-shrink:0;max-width:300px;overflow:hidden;padding:0 15px;pointer-events:auto;position:relative;-webkit-transform:translateY(25%);-moz-transform:translateY(25%);-ms-transform:translateY(25%);transform:translateY(25%)}.notyf__toast--disappear{-webkit-animation:notyf-fadeoutdown .3s forwards;-moz-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;-webkit-animation-delay:.25s;-moz-animation-delay:.25s;animation-delay:.25s;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.notyf__toast--disappear .notyf__icon,.notyf__toast--disappear .notyf__message{-webkit-animation:notyf-fadeoutdown .3s forwards;-moz-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.notyf__toast--disappear .notyf__dismiss{-webkit-animation:notyf-fadeoutright .3s forwards;-moz-animation:notyf-fadeoutright .3s forwards;animation:notyf-fadeoutright .3s forwards;opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.notyf__toast--disappear .notyf__message{-webkit-animation-delay:.05s;-moz-animation-delay:.05s;animation-delay:.05s}.notyf__toast--upper{margin-bottom:20px}.notyf__toast--lower{margin-top:20px}.notyf__toast--dismissible .notyf__wrapper{padding-right:30px}.notyf__ripple{-webkit-animation:ripple .4s ease-out forwards;-moz-animation:ripple .4s ease-out forwards;animation:ripple .4s ease-out forwards;border-radius:50%;height:400px;position:absolute;right:0;top:0;-webkit-transform:scale(0) translateY(-51%) translateX(13%);-moz-transform:scale(0) translateY(-51%) translateX(13%);-ms-transform:scale(0) translateY(-51%) translateX(13%);transform:scale(0) translateY(-51%) translateX(13%);-webkit-transform-origin:bottom right;-moz-transform-origin:bottom right;-ms-transform-origin:bottom right;transform-origin:bottom right;width:400px;z-index:5}.notyf__wrapper{-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;align-items:center;border-radius:3px;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex;padding-bottom:17px;padding-right:15px;padding-top:17px;position:relative;z-index:10}.notyf__icon{-webkit-animation:notyf-fadeinup .3s forwards;-moz-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s;font-size:1.3em;margin-right:13px;opacity:0;text-align:center;width:22px}.notyf__dismiss{-webkit-animation:notyf-fadeinleft .3s forwards;-moz-animation:notyf-fadeinleft .3s forwards;animation:notyf-fadeinleft .3s forwards;-webkit-animation-delay:.35s;-moz-animation-delay:.35s;animation-delay:.35s;height:100%;margin-right:-15px;opacity:0;position:absolute;right:0;top:0;width:26px}.notyf__dismiss-btn{background-color:rgba(0,0,0,.25);border:none;cursor:pointer;height:100%;opacity:.35;outline:none;-webkit-transition:opacity .2s ease,background-color .2s ease;-moz-transition:opacity .2s ease,background-color .2s ease;transition:opacity .2s ease,background-color .2s ease;width:100%}.notyf__dismiss-btn:after,.notyf__dismiss-btn:before{background:#fff;border-radius:3px;content:"";height:12px;left:-webkit-calc(50% - 1px);left:-moz-calc(50% - 1px);left:calc(50% - 1px);position:absolute;top:-webkit-calc(50% - 5px);top:-moz-calc(50% - 5px);top:calc(50% - 5px);width:2px}.notyf__dismiss-btn:after{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.notyf__dismiss-btn:before{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.notyf__dismiss-btn:hover{background-color:rgba(0,0,0,.15);opacity:.7}.notyf__dismiss-btn:active{opacity:.8}.notyf__message{-webkit-animation:notyf-fadeinup .3s forwards;-moz-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.25s;-moz-animation-delay:.25s;animation-delay:.25s;line-height:1.5em;opacity:0;position:relative;vertical-align:middle}@media only screen and (max-width:480px){.notyf{padding:0}.notyf__ripple{-webkit-animation-duration:.5s;-moz-animation-duration:.5s;animation-duration:.5s;height:600px;width:600px}.notyf__toast{border-radius:0;-webkit-box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);max-width:none;width:100%}.notyf__dismiss{width:56px}} \ No newline at end of file diff --git a/src/Notyf/Prime/Resources/dist/flasher-notyf.min.js b/src/Notyf/Prime/Resources/dist/flasher-notyf.min.js new file mode 100644 index 00000000..6d8dd4df --- /dev/null +++ b/src/Notyf/Prime/Resources/dist/flasher-notyf.min.js @@ -0,0 +1 @@ +!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):(t="undefined"!=typeof globalThis?globalThis:t||self).notyf=i(t.flasher)}(this,(function(t){"use strict";class i{success(t,i,e){this.flash("success",t,i,e)}error(t,i,e){this.flash("error",t,i,e)}info(t,i,e){this.flash("info",t,i,e)}warning(t,i,e){this.flash("warning",t,i,e)}flash(t,i,e,n){if("object"==typeof t?(t=(n=t).type,i=n.message,e=n.title):"object"==typeof i?(i=(n=i).message,e=n.title):"object"==typeof e&&(e=(n=e).title),void 0===i)throw new Error("message option is required");const o={type:t,message:i,title:e||t,options:n||{},metadata:{plugin:""}};this.renderOptions(n||{}),this.renderEnvelopes([o])}}var e,n=function(){return n=Object.assign||function(t){for(var i,e=1,n=arguments.length;e{var i;const e=Object.assign(Object.assign({},t),t.options);null===(i=this.notyf)||void 0===i||i.open(e)})),this.notyf.view.container.dataset.turboCache="false",this.notyf.view.a11yContainer.dataset.turboCache="false"}renderOptions(t){const i=Object.assign({duration:t.duration||5e3},t);i.types=i.types||[],i.types.push({type:"info",className:"notyf__toast--info",background:"#5784E5",icon:{className:"notyf__icon--info",tagName:"i"}}),i.types.push({type:"warning",className:"notyf__toast--warning",background:"#E3A008",icon:{className:"notyf__icon--warning",tagName:"i"}}),this.notyf=this.notyf||new p(i)}};return t.addPlugin("notyf",f),f})); diff --git a/src/Notyf/Prime/Resources/dist/index.d.ts b/src/Notyf/Prime/Resources/dist/index.d.ts new file mode 100644 index 00000000..5c846c2e --- /dev/null +++ b/src/Notyf/Prime/Resources/dist/index.d.ts @@ -0,0 +1,4 @@ +import './notyf.scss'; +import NotyfPlugin from './notyf'; +declare const notyf: NotyfPlugin; +export default notyf; diff --git a/src/Notyf/Prime/Resources/dist/notyf.d.ts b/src/Notyf/Prime/Resources/dist/notyf.d.ts new file mode 100644 index 00000000..d98a8ab7 --- /dev/null +++ b/src/Notyf/Prime/Resources/dist/notyf.d.ts @@ -0,0 +1,9 @@ +import { AbstractPlugin } from '@flasher/flasher/dist/plugin'; +import type { Envelope, Options } from '@flasher/flasher/dist/types'; +import { Notyf } from 'notyf'; +import 'notyf/notyf.min.css'; +export default class NotyfPlugin extends AbstractPlugin { + notyf?: Notyf; + renderEnvelopes(envelopes: Envelope[]): void; + renderOptions(options: Options): void; +} diff --git a/src/Notyf/Prime/Resources/package.json b/src/Notyf/Prime/Resources/package.json new file mode 100644 index 00000000..d487449a --- /dev/null +++ b/src/Notyf/Prime/Resources/package.json @@ -0,0 +1,17 @@ +{ + "name": "@flasher/flasher-notyf", + "version": "2.0.0", + "type": "module", + "license": "MIT", + "main": "dist/flasher-notyf.cjs.js", + "module": "dist/flasher-notyf.esm.js", + "browser": "dist/flasher-notyf.umd.js", + "types": "dist/notyf.d.ts", + "scripts": { + "ncu": "ncu -u" + }, + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "notyf": "^3.10.0" + } +} diff --git a/src/Notyf/Prime/Resources/public/flasher-notyf.min.css b/src/Notyf/Prime/Resources/public/flasher-notyf.min.css new file mode 100644 index 00000000..f6e64571 --- /dev/null +++ b/src/Notyf/Prime/Resources/public/flasher-notyf.min.css @@ -0,0 +1,2 @@ +.notyf__icon--info,.notyf__icon--warning{background:#fff;border-radius:50%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;height:1em;margin:0 auto;position:relative;width:1em}.notyf__icon--info:after,.notyf__icon--info:before,.notyf__icon--warning:after,.notyf__icon--warning:before{border-width:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;content:"";position:absolute;-webkit-transition:all 1s;-moz-transition:all 1s;transition:all 1s}.notyf__icon--info:after,.notyf__icon--info:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.notyf__icon--info:before{height:.38em;top:.4em}.notyf__icon--info:after{-webkit-box-shadow:-.06em .19em,-.06em .44em,.06em .44em;box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.notyf__icon--warning:after,.notyf__icon--warning:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.notyf__icon--warning:before{height:.38em;top:.21em}.notyf__icon--warning:after{height:.13em;top:.65em} +@-webkit-keyframes notyf-fadeinup{0%{opacity:0;-webkit-transform:translateY(25%);transform:translateY(25%)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes notyf-fadeinup{0%{opacity:0;-moz-transform:translateY(25%);transform:translateY(25%)}to{opacity:1;-moz-transform:translateY(0);transform:translateY(0)}}@keyframes notyf-fadeinup{0%{opacity:0;-webkit-transform:translateY(25%);-moz-transform:translateY(25%);transform:translateY(25%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes notyf-fadeinleft{0%{opacity:0;-webkit-transform:translateX(25%);transform:translateX(25%)}to{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}}@-moz-keyframes notyf-fadeinleft{0%{opacity:0;-moz-transform:translateX(25%);transform:translateX(25%)}to{opacity:1;-moz-transform:translateX(0);transform:translateX(0)}}@keyframes notyf-fadeinleft{0%{opacity:0;-webkit-transform:translateX(25%);-moz-transform:translateX(25%);transform:translateX(25%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes notyf-fadeoutright{0%{opacity:1;-webkit-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(25%);transform:translateX(25%)}}@-moz-keyframes notyf-fadeoutright{0%{opacity:1;-moz-transform:translateX(0);transform:translateX(0)}to{opacity:0;-moz-transform:translateX(25%);transform:translateX(25%)}}@keyframes notyf-fadeoutright{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(25%);-moz-transform:translateX(25%);transform:translateX(25%)}}@-webkit-keyframes notyf-fadeoutdown{0%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(25%);transform:translateY(25%)}}@-moz-keyframes notyf-fadeoutdown{0%{opacity:1;-moz-transform:translateY(0);transform:translateY(0)}to{opacity:0;-moz-transform:translateY(25%);transform:translateY(25%)}}@keyframes notyf-fadeoutdown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(25%);-moz-transform:translateY(25%);transform:translateY(25%)}}@-webkit-keyframes ripple{0%{-webkit-transform:scale(0) translateY(-45%) translateX(13%);transform:scale(0) translateY(-45%) translateX(13%)}to{-webkit-transform:scale(1) translateY(-45%) translateX(13%);transform:scale(1) translateY(-45%) translateX(13%)}}@-moz-keyframes ripple{0%{-moz-transform:scale(0) translateY(-45%) translateX(13%);transform:scale(0) translateY(-45%) translateX(13%)}to{-moz-transform:scale(1) translateY(-45%) translateX(13%);transform:scale(1) translateY(-45%) translateX(13%)}}@keyframes ripple{0%{-webkit-transform:scale(0) translateY(-45%) translateX(13%);-moz-transform:scale(0) translateY(-45%) translateX(13%);transform:scale(0) translateY(-45%) translateX(13%)}to{-webkit-transform:scale(1) translateY(-45%) translateX(13%);-moz-transform:scale(1) translateY(-45%) translateX(13%);transform:scale(1) translateY(-45%) translateX(13%)}}.notyf{-webkit-box-align:end;-webkit-align-items:flex-end;-moz-box-align:end;align-items:flex-end;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#fff;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-moz-box-orient:vertical;-moz-box-direction:normal;flex-direction:column;height:100%;-webkit-box-pack:end;-webkit-justify-content:flex-end;-moz-box-pack:end;justify-content:flex-end;left:0;padding:20px;pointer-events:none;position:fixed;top:0;width:100%;z-index:9999}.notyf__icon--error,.notyf__icon--success{background:#fff;border-radius:50%;display:block;height:21px;margin:0 auto;position:relative;width:21px}.notyf__icon--error:after,.notyf__icon--error:before{background:currentColor;border-radius:3px;content:"";display:block;height:12px;left:9px;position:absolute;top:5px;width:3px}.notyf__icon--error:after{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.notyf__icon--error:before{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.notyf__icon--success:after,.notyf__icon--success:before{background:currentColor;border-radius:3px;content:"";display:block;position:absolute;width:3px}.notyf__icon--success:after{height:6px;left:6px;top:9px;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.notyf__icon--success:before{height:11px;left:10px;top:5px;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.notyf__toast{-webkit-animation:notyf-fadeinup .3s ease-in forwards;-moz-animation:notyf-fadeinup .3s ease-in forwards;animation:notyf-fadeinup .3s ease-in forwards;border-radius:2px;-webkit-box-shadow:0 3px 7px 0 rgba(0,0,0,.25);box-shadow:0 3px 7px 0 rgba(0,0,0,.25);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;-webkit-flex-shrink:0;flex-shrink:0;max-width:300px;overflow:hidden;padding:0 15px;pointer-events:auto;position:relative;-webkit-transform:translateY(25%);-moz-transform:translateY(25%);-ms-transform:translateY(25%);transform:translateY(25%)}.notyf__toast--disappear{-webkit-animation:notyf-fadeoutdown .3s forwards;-moz-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;-webkit-animation-delay:.25s;-moz-animation-delay:.25s;animation-delay:.25s;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.notyf__toast--disappear .notyf__icon,.notyf__toast--disappear .notyf__message{-webkit-animation:notyf-fadeoutdown .3s forwards;-moz-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.notyf__toast--disappear .notyf__dismiss{-webkit-animation:notyf-fadeoutright .3s forwards;-moz-animation:notyf-fadeoutright .3s forwards;animation:notyf-fadeoutright .3s forwards;opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.notyf__toast--disappear .notyf__message{-webkit-animation-delay:.05s;-moz-animation-delay:.05s;animation-delay:.05s}.notyf__toast--upper{margin-bottom:20px}.notyf__toast--lower{margin-top:20px}.notyf__toast--dismissible .notyf__wrapper{padding-right:30px}.notyf__ripple{-webkit-animation:ripple .4s ease-out forwards;-moz-animation:ripple .4s ease-out forwards;animation:ripple .4s ease-out forwards;border-radius:50%;height:400px;position:absolute;right:0;top:0;-webkit-transform:scale(0) translateY(-51%) translateX(13%);-moz-transform:scale(0) translateY(-51%) translateX(13%);-ms-transform:scale(0) translateY(-51%) translateX(13%);transform:scale(0) translateY(-51%) translateX(13%);-webkit-transform-origin:bottom right;-moz-transform-origin:bottom right;-ms-transform-origin:bottom right;transform-origin:bottom right;width:400px;z-index:5}.notyf__wrapper{-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;align-items:center;border-radius:3px;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex;padding-bottom:17px;padding-right:15px;padding-top:17px;position:relative;z-index:10}.notyf__icon{-webkit-animation:notyf-fadeinup .3s forwards;-moz-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.3s;-moz-animation-delay:.3s;animation-delay:.3s;font-size:1.3em;margin-right:13px;opacity:0;text-align:center;width:22px}.notyf__dismiss{-webkit-animation:notyf-fadeinleft .3s forwards;-moz-animation:notyf-fadeinleft .3s forwards;animation:notyf-fadeinleft .3s forwards;-webkit-animation-delay:.35s;-moz-animation-delay:.35s;animation-delay:.35s;height:100%;margin-right:-15px;opacity:0;position:absolute;right:0;top:0;width:26px}.notyf__dismiss-btn{background-color:rgba(0,0,0,.25);border:none;cursor:pointer;height:100%;opacity:.35;outline:none;-webkit-transition:opacity .2s ease,background-color .2s ease;-moz-transition:opacity .2s ease,background-color .2s ease;transition:opacity .2s ease,background-color .2s ease;width:100%}.notyf__dismiss-btn:after,.notyf__dismiss-btn:before{background:#fff;border-radius:3px;content:"";height:12px;left:-webkit-calc(50% - 1px);left:-moz-calc(50% - 1px);left:calc(50% - 1px);position:absolute;top:-webkit-calc(50% - 5px);top:-moz-calc(50% - 5px);top:calc(50% - 5px);width:2px}.notyf__dismiss-btn:after{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);transform:rotate(-45deg)}.notyf__dismiss-btn:before{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.notyf__dismiss-btn:hover{background-color:rgba(0,0,0,.15);opacity:.7}.notyf__dismiss-btn:active{opacity:.8}.notyf__message{-webkit-animation:notyf-fadeinup .3s forwards;-moz-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.25s;-moz-animation-delay:.25s;animation-delay:.25s;line-height:1.5em;opacity:0;position:relative;vertical-align:middle}@media only screen and (max-width:480px){.notyf{padding:0}.notyf__ripple{-webkit-animation-duration:.5s;-moz-animation-duration:.5s;animation-duration:.5s;height:600px;width:600px}.notyf__toast{border-radius:0;-webkit-box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);max-width:none;width:100%}.notyf__dismiss{width:56px}} \ No newline at end of file diff --git a/src/Notyf/Prime/Resources/public/flasher-notyf.min.js b/src/Notyf/Prime/Resources/public/flasher-notyf.min.js new file mode 100644 index 00000000..6d8dd4df --- /dev/null +++ b/src/Notyf/Prime/Resources/public/flasher-notyf.min.js @@ -0,0 +1 @@ +!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):(t="undefined"!=typeof globalThis?globalThis:t||self).notyf=i(t.flasher)}(this,(function(t){"use strict";class i{success(t,i,e){this.flash("success",t,i,e)}error(t,i,e){this.flash("error",t,i,e)}info(t,i,e){this.flash("info",t,i,e)}warning(t,i,e){this.flash("warning",t,i,e)}flash(t,i,e,n){if("object"==typeof t?(t=(n=t).type,i=n.message,e=n.title):"object"==typeof i?(i=(n=i).message,e=n.title):"object"==typeof e&&(e=(n=e).title),void 0===i)throw new Error("message option is required");const o={type:t,message:i,title:e||t,options:n||{},metadata:{plugin:""}};this.renderOptions(n||{}),this.renderEnvelopes([o])}}var e,n=function(){return n=Object.assign||function(t){for(var i,e=1,n=arguments.length;e{var i;const e=Object.assign(Object.assign({},t),t.options);null===(i=this.notyf)||void 0===i||i.open(e)})),this.notyf.view.container.dataset.turboCache="false",this.notyf.view.a11yContainer.dataset.turboCache="false"}renderOptions(t){const i=Object.assign({duration:t.duration||5e3},t);i.types=i.types||[],i.types.push({type:"info",className:"notyf__toast--info",background:"#5784E5",icon:{className:"notyf__icon--info",tagName:"i"}}),i.types.push({type:"warning",className:"notyf__toast--warning",background:"#E3A008",icon:{className:"notyf__icon--warning",tagName:"i"}}),this.notyf=this.notyf||new p(i)}};return t.addPlugin("notyf",f),f})); diff --git a/src/Notyf/Prime/composer.json b/src/Notyf/Prime/composer.json index 01ab2052..ab218560 100644 --- a/src/Notyf/Prime/composer.json +++ b/src/Notyf/Prime/composer.json @@ -1,51 +1,46 @@ { "name": "php-flasher/flasher-notyf", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Notyf\\Prime\\": "" }, "files": [ + "functions.php", "helpers.php" ] }, diff --git a/src/Notyf/Prime/functions.php b/src/Notyf/Prime/functions.php new file mode 100644 index 00000000..82ff2093 --- /dev/null +++ b/src/Notyf/Prime/functions.php @@ -0,0 +1,42 @@ + $options additional options for the Notyf notification + * @param string|null $title the title of the notification + * + * @return Envelope|NotyfInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of NotyfInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Notyf factory: $notyf = notyf(); + * 2. With arguments - Create and return a Notyf notification: + * notyf('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); + */ + function notyf(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|NotyfInterface + { + $factory = FlasherContainer::create('flasher.notyf'); + + if (0 === \func_num_args()) { + return $factory; + } + + return $factory->flash($type, $message, $options, $title); + } +} diff --git a/src/Notyf/Prime/helpers.php b/src/Notyf/Prime/helpers.php index cd293801..90a93319 100644 --- a/src/Notyf/Prime/helpers.php +++ b/src/Notyf/Prime/helpers.php @@ -1,32 +1,41 @@ - */ +declare(strict_types=1); -use Flasher\Notyf\Prime\NotyfFactory; +use Flasher\Notyf\Prime\NotyfInterface; use Flasher\Prime\Container\FlasherContainer; use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; +use Flasher\Prime\Notification\Type; if (!function_exists('notyf')) { /** - * @param string $message - * @param string $type - * @param array $options + * Creates a Notyf notification or returns the Notyf factory. * - * @return Envelope|NotyfFactory + * This function simplifies the process of creating Notyf notifications. + * When called with no arguments, it returns an instance of NotyfInterface. + * When called with arguments, it creates a Notyf notification and returns an Envelope. + * + * @param string|null $message the message content of the notification + * @param string $type The type of the notification (e.g., success, error, warning, info). + * @param array $options additional options for the Notyf notification + * @param string|null $title the title of the notification + * + * @return Envelope|NotyfInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of NotyfInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Notyf factory: $notyf = notyf(); + * 2. With arguments - Create and return a Notyf notification: + * notyf('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); */ - function notyf($message = null, $type = NotificationInterface::SUCCESS, array $options = array()) + function notyf(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|NotyfInterface { - /** @var NotyfFactory $factory */ $factory = FlasherContainer::create('flasher.notyf'); if (0 === func_num_args()) { return $factory; } - return $factory->addFlash($type, $message, $options); + return $factory->flash($type, $message, $options, $title); } } diff --git a/src/Notyf/Symfony/.github/FUNDING.yml b/src/Notyf/Symfony/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Notyf/Symfony/.github/FUNDING.yml +++ b/src/Notyf/Symfony/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Notyf/Symfony/.github/workflows/auto_closer.yaml b/src/Notyf/Symfony/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Notyf/Symfony/.github/workflows/auto_closer.yaml +++ b/src/Notyf/Symfony/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Notyf/Symfony/FlasherNotyfBundle.php b/src/Notyf/Symfony/FlasherNotyfBundle.php new file mode 100644 index 00000000..d03edf9d --- /dev/null +++ b/src/Notyf/Symfony/FlasherNotyfBundle.php @@ -0,0 +1,17 @@ + - */ - -namespace Flasher\Notyf\Symfony; - -use Flasher\Notyf\Prime\NotyfPlugin; -use Flasher\Symfony\Support\Bundle; - -class FlasherNotyfSymfonyBundle extends Bundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - /** - * {@inheritDoc} - */ - public function createPlugin() - { - return new NotyfPlugin(); - } -} diff --git a/src/Notyf/Symfony/LICENSE b/src/Notyf/Symfony/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Notyf/Symfony/LICENSE +++ b/src/Notyf/Symfony/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Notyf/Symfony/README.md b/src/Notyf/Symfony/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Notyf/Symfony/README.md +++ b/src/Notyf/Symfony/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Notyf/Symfony/Resources/config/config.yaml b/src/Notyf/Symfony/Resources/config/config.yaml deleted file mode 100644 index c288b7a6..00000000 --- a/src/Notyf/Symfony/Resources/config/config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -flasher_notyf: - scripts: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-notyf@1.3.2/dist/flasher-notyf.min.js' - local: - - '/vendor/flasher/flasher-notyf.min.js' - styles: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-notyf@1.3.2/dist/flasher-notyf.min.css' - local: - - '/vendor/flasher/flasher-notyf.min.css' diff --git a/src/Notyf/Symfony/composer.json b/src/Notyf/Symfony/composer.json index 2daeb978..5f688db2 100644 --- a/src/Notyf/Symfony/composer.json +++ b/src/Notyf/Symfony/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-notyf-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "symfony-bundle", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-notyf": "^1.15.14", - "php-flasher/flasher-symfony": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-notyf": "^2.0", + "php-flasher/flasher-symfony": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Notyf\\Symfony\\": "" diff --git a/src/Pnotify/Laravel/.github/FUNDING.yml b/src/Pnotify/Laravel/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/src/Pnotify/Laravel/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Pnotify/Laravel/.github/workflows/auto_closer.yaml b/src/Pnotify/Laravel/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/src/Pnotify/Laravel/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/src/Pnotify/Laravel/Facade/Pnotify.php b/src/Pnotify/Laravel/Facade/Pnotify.php deleted file mode 100644 index 190db301..00000000 --- a/src/Pnotify/Laravel/Facade/Pnotify.php +++ /dev/null @@ -1,74 +0,0 @@ - - */ - -namespace Flasher\Pnotify\Laravel\Facade; - -use Flasher\Pnotify\Prime\PnotifyBuilder; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; -use Flasher\Prime\Stamp\StampInterface; -use Illuminate\Support\Facades\Facade; - -/** - * @method static PnotifyBuilder addSuccess(string $message, array $options = array()) - * @method static PnotifyBuilder addError(string $message, array $options = array()) - * @method static PnotifyBuilder addWarning(string $message, array $options = array()) - * @method static PnotifyBuilder addInfo(string $message, array $options = array()) - * @method static PnotifyBuilder addFlash(NotificationInterface|string $type, string $message = null, array $options = array()) - * @method static PnotifyBuilder flash(StampInterface[] $stamps = array()) - * @method static PnotifyBuilder type(string $type, string $message = null, array $options = array()) - * @method static PnotifyBuilder message(string $message) - * @method static PnotifyBuilder options(array $options, bool $merge = true) - * @method static PnotifyBuilder option(string $name, string $value) - * @method static PnotifyBuilder success(string $message = null, array $options = array()) - * @method static PnotifyBuilder error(string $message = null, array $options = array()) - * @method static PnotifyBuilder info(string $message = null, array $options = array()) - * @method static PnotifyBuilder warning(string $message = null, array $options = array()) - * @method static PnotifyBuilder priority(int $priority) - * @method static PnotifyBuilder hops(int $amount) - * @method static PnotifyBuilder keep() - * @method static PnotifyBuilder delay(int $delay) - * @method static PnotifyBuilder now() - * @method static PnotifyBuilder with(StampInterface[] $stamps = array()) - * @method static PnotifyBuilder withStamp(StampInterface $stamp) - * @method static PnotifyBuilder handler(string $handler) - * @method static Envelope getEnvelope() - * @method static PnotifyBuilder title(bool|string $title) - * @method static PnotifyBuilder titleEscape(bool $titleEscape = true) - * @method static PnotifyBuilder text(string $text) - * @method static PnotifyBuilder textEscape(bool $textEscape = true) - * @method static PnotifyBuilder styling(string $styling) - * @method static PnotifyBuilder addClass(string $addClass) - * @method static PnotifyBuilder cornerClass(string $cornerClass) - * @method static PnotifyBuilder autoDisplay(bool $autoDisplay = true) - * @method static PnotifyBuilder width(int $width) - * @method static PnotifyBuilder minHeight(int $minHeight) - * @method static PnotifyBuilder icon(bool $icon = true) - * @method static PnotifyBuilder animation(string $animation) - * @method static PnotifyBuilder animateSpeed(string $animateSpeed) - * @method static PnotifyBuilder shadow(bool $shadow = true) - * @method static PnotifyBuilder hide(bool $hide = true) - * @method static PnotifyBuilder timer(int $timer) - * @method static PnotifyBuilder mouseReset(bool $mouseReset = true) - * @method static PnotifyBuilder remove(bool $remove = true) - * @method static PnotifyBuilder insertBrs(bool $insertBrs = true) - * @method static PnotifyBuilder destroy(bool $destroy = true) - * @method static PnotifyBuilder desktop(string $desktop, mixed $value) - * @method static PnotifyBuilder buttons(string $buttons, mixed $value) - * @method static PnotifyBuilder nonblock(string $nonblock, mixed $value) - * @method static PnotifyBuilder mobile(string $mobile, mixed $value) - * @method static PnotifyBuilder animate(string $animate, mixed $value) - * @method static PnotifyBuilder confirm(string $confirm, mixed $value) - * @method static PnotifyBuilder history(string $history, mixed $value) - */ -class Pnotify extends Facade -{ - protected static function getFacadeAccessor() - { - return 'flasher.pnotify'; - } -} diff --git a/src/Pnotify/Laravel/FlasherPnotifyServiceProvider.php b/src/Pnotify/Laravel/FlasherPnotifyServiceProvider.php deleted file mode 100644 index e76b5855..00000000 --- a/src/Pnotify/Laravel/FlasherPnotifyServiceProvider.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Flasher\Pnotify\Laravel; - -use Flasher\Laravel\Support\ServiceProvider; -use Flasher\Pnotify\Prime\PnotifyPlugin; - -final class FlasherPnotifyServiceProvider extends ServiceProvider -{ - /** - * {@inheritDoc} - */ - public function createPlugin() - { - return new PnotifyPlugin(); - } -} diff --git a/src/Pnotify/Laravel/LICENSE b/src/Pnotify/Laravel/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/src/Pnotify/Laravel/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/src/Pnotify/Laravel/README.md b/src/Pnotify/Laravel/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/src/Pnotify/Laravel/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/src/Pnotify/Laravel/Resources/config.php b/src/Pnotify/Laravel/Resources/config.php deleted file mode 100644 index 630a7aca..00000000 --- a/src/Pnotify/Laravel/Resources/config.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -return array( - 'scripts' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-pnotify@1.3.2/dist/flasher-pnotify.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-pnotify.min.js', - ), - ), - 'styles' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-pnotify@1.3.2/dist/flasher-pnotify.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-pnotify.min.css', - ), - ), -); diff --git a/src/Pnotify/Laravel/composer.json b/src/Pnotify/Laravel/composer.json deleted file mode 100644 index 020a8fbd..00000000 --- a/src/Pnotify/Laravel/composer.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "php-flasher/flasher-pnotify-laravel", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "library", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-laravel": "^1.15.14", - "php-flasher/flasher-pnotify": "^1.15.14" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "autoload": { - "psr-4": { - "Flasher\\Pnotify\\Laravel\\": "" - } - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - }, - "extra": { - "laravel": { - "aliases": { - "Pnotify": "Flasher\\Pnotify\\Laravel\\Facade\\Pnotify" - }, - "providers": [ - "Flasher\\Pnotify\\Laravel\\FlasherPnotifyServiceProvider" - ] - } - } -} diff --git a/src/Pnotify/Prime/.github/FUNDING.yml b/src/Pnotify/Prime/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/src/Pnotify/Prime/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Pnotify/Prime/.github/workflows/auto_closer.yaml b/src/Pnotify/Prime/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/src/Pnotify/Prime/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/src/Pnotify/Prime/.phpstorm.meta.php b/src/Pnotify/Prime/.phpstorm.meta.php deleted file mode 100644 index 2ef2fcf5..00000000 --- a/src/Pnotify/Prime/.phpstorm.meta.php +++ /dev/null @@ -1,24 +0,0 @@ - \Flasher\Pnotify\Prime\PnotifyFactory::class -])); - -override(\Flasher\Prime\FlasherInterface::using(), map([ - 'pnotify' => \Flasher\Pnotify\Prime\PnotifyFactory::class -])); diff --git a/src/Pnotify/Prime/LICENSE b/src/Pnotify/Prime/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/src/Pnotify/Prime/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/src/Pnotify/Prime/PnotifyBuilder.php b/src/Pnotify/Prime/PnotifyBuilder.php deleted file mode 100644 index 4005a691..00000000 --- a/src/Pnotify/Prime/PnotifyBuilder.php +++ /dev/null @@ -1,434 +0,0 @@ - - */ - -namespace Flasher\Pnotify\Prime; - -use Flasher\Prime\Notification\NotificationBuilder; - -final class PnotifyBuilder extends NotificationBuilder -{ - public function warning($message = null, $title = null, array $options = array()) - { - return $this->type('notice', $message, $title, $options); - } - - /** - * The notice's title. - * - * @param bool|string $title - * - * @return static - */ - public function title($title) - { - $this->option('title', $title); - - return $this; - } - - /** - * Whether to escape the content of the title. (Not allow HTML.). - * - * @param bool $titleEscape - * - * @return static - */ - public function titleEscape($titleEscape = true) - { - $this->option('title_escape', $titleEscape); - - return $this; - } - - /** - * The notice's text. - * - * @param string $text - * - * @return static - */ - public function text($text) - { - $this->option('text', $text); - - return $this; - } - - public function message($message) - { - parent::message($message); - - return $this->text($message); - } - - /** - * Whether to escape the content of the text. (Not allow HTML.). - * - * @param bool $textEscape - * - * @return static - */ - public function textEscape($textEscape = true) - { - $this->option('text_escape', $textEscape); - - return $this; - } - - /** - * What styling classes to use. (Can be either "brighttheme", "bootstrap3", "fontawesome", or a custom style object. - * See the source in the end of pnotify.js for the properties in a style object.). - * - * @param string $styling - * - * @return static - */ - public function styling($styling) - { - $this->option('styling', $styling); - - return $this; - } - - /** - * Additional classes to be added to the notice. (For custom styling.). - * - * @param string $addClass - * - * @return static - */ - public function addClass($addClass) - { - $this->option('addclass', $addClass); - - return $this; - } - - /** - * Class to be added to the notice for corner styling. - * - * @param string $cornerClass - * - * @return static - */ - public function cornerClass($cornerClass) - { - $this->option('cornerclass', $cornerClass); - - return $this; - } - - /** - * Display the notice when it is created. Turn this off to add notifications to the history without displaying them. - * - * @param bool $autoDisplay - * - * @return static - */ - public function autoDisplay($autoDisplay = true) - { - $this->option('auto_display', $autoDisplay); - - return $this; - } - - /** - * Width of the notice. - * - * @param int $width - * - * @return static - */ - public function width($width) - { - $this->option('width', $width); - - return $this; - } - - /** - * Minimum height of the notice. It will expand to fit content. - * - * @param int $minHeight - * - * @return static - */ - public function minHeight($minHeight) - { - $this->option('minHeight', $minHeight); - - return $this; - } - - /** - * Set icon to true to use the default icon for the selected style/type, false for no icon, or a string for your own - * icon class. - * - * @param bool $icon - * - * @return static - */ - public function icon($icon = true) - { - $this->option('icon', $icon); - - return $this; - } - - /** - * The animation to use when displaying and hiding the notice. "none" and "fade" are supported through CSS. Others - * are supported through the Animate module and Animate.css. - * - * @param string $animation - * - * @return static - */ - public function animation($animation) - { - $this->option('animation', $animation); - - return $this; - } - - /** - * Speed at which the notice animates in and out. "slow", "normal", or "fast". Respectively, 400ms, 250ms, 100ms. - * - * @param string $animateSpeed - * - * @return static - */ - public function animateSpeed($animateSpeed) - { - $this->option('animate_speed', $animateSpeed); - - return $this; - } - - /** - * Display a drop shadow. - * - * @param bool $shadow - * - * @return static - */ - public function shadow($shadow = true) - { - $this->option('shadow', $shadow); - - return $this; - } - - /** - * After a delay, remove the notice. - * - * @param bool $hide - * - * @return static - */ - public function hide($hide = true) - { - $this->option('hide', $hide); - - return $this; - } - - /** - * Delay in milliseconds before the notice is removed. - * - * @param int $timer - * - * @return static - */ - public function timer($timer) - { - $this->option('delay', $timer); - - return $this; - } - - /** - * Reset the hide timer if the mouse moves over the notice. - * - * @param bool $mouseReset - * - * @return static - */ - public function mouseReset($mouseReset = true) - { - $this->option('mouse_reset', $mouseReset); - - return $this; - } - - /** - * Remove the notice's elements from the DOM after it is removed. - * - * @param bool $remove - * - * @return static - */ - public function remove($remove = true) - { - $this->option('remove', $remove); - - return $this; - } - - /** - * Change new lines to br tags. - * - * @param bool $insertBrs - * - * @return static - */ - public function insertBrs($insertBrs = true) - { - $this->option('insert_brs', $insertBrs); - - return $this; - } - - /** - * Whether to remove the notice from the global array when it is closed. - * - * @param bool $destroy - * - * @return static - */ - public function destroy($destroy = true) - { - $this->option('destroy', $destroy); - - return $this; - } - - /** - * Desktop Module. - * - * @param string $desktop - * @param mixed $value - * - * @return static - */ - public function desktop($desktop, $value) - { - $option = $this->getEnvelope()->getOption('desktop', array()); - $option[$desktop] = $value; // @phpstan-ignore-line - - $this->option('desktop', $option); - - return $this; - } - - /** - * Buttons Module. - * - * @param string $buttons - * @param mixed $value - * - * @return static - */ - public function buttons($buttons, $value) - { - $option = $this->getEnvelope()->getOption('buttons', array()); - $option[$buttons] = $value; // @phpstan-ignore-line - - $this->option('buttons', $option); - - return $this; - } - - /** - * NonBlock Module. - * - * @param string $nonblock - * @param mixed $value - * - * @return static - */ - public function nonblock($nonblock, $value) - { - $option = $this->getEnvelope()->getOption('nonblock', array()); - $option[$nonblock] = $value; // @phpstan-ignore-line - - $this->option('nonblock', $option); - - return $this; - } - - /** - * Mobile Module. - * - * @param string $mobile - * @param mixed $value - * - * @return static - */ - public function mobile($mobile, $value) - { - $option = $this->getEnvelope()->getOption('mobile', array()); - $option[$mobile] = $value; // @phpstan-ignore-line - - $this->option('mobile', $option); - - return $this; - } - - /** - * Animate Module. - * - * @param string $animate - * @param mixed $value - * - * @return static - */ - public function animate($animate, $value) - { - $option = $this->getEnvelope()->getOption('animate', array()); - $option[$animate] = $value; // @phpstan-ignore-line - - $this->option('animate', $option); - - return $this; - } - - /** - * Confirm Module. - * - * @param string $confirm - * @param mixed $value - * - * @return static - */ - public function confirm($confirm, $value) - { - $option = $this->getEnvelope()->getOption('confirm', array()); - $option[$confirm] = $value; // @phpstan-ignore-line - - $this->option('confirm', $option); - - return $this; - } - - /** - * History Module. - * - * @param string $history - * @param mixed $value - * - * @return static - */ - public function history($history, $value) - { - $option = $this->getEnvelope()->getOption('history', array()); - $option[$history] = $value; // @phpstan-ignore-line - - $this->option('history', $option); - - return $this; - } -} diff --git a/src/Pnotify/Prime/PnotifyFactory.php b/src/Pnotify/Prime/PnotifyFactory.php deleted file mode 100644 index f1158dcd..00000000 --- a/src/Pnotify/Prime/PnotifyFactory.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Flasher\Pnotify\Prime; - -use Flasher\Prime\Factory\NotificationFactory; -use Flasher\Prime\Notification\Notification; - -/** - * @mixin PnotifyBuilder - */ -final class PnotifyFactory extends NotificationFactory -{ - public function createNotificationBuilder() - { - return new PnotifyBuilder($this->getStorageManager(), new Notification(), 'pnotify'); - } -} diff --git a/src/Pnotify/Prime/PnotifyPlugin.php b/src/Pnotify/Prime/PnotifyPlugin.php deleted file mode 100644 index b13f2027..00000000 --- a/src/Pnotify/Prime/PnotifyPlugin.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ - -namespace Flasher\Pnotify\Prime; - -use Flasher\Prime\Plugin\Plugin; - -class PnotifyPlugin extends Plugin -{ - /** - * {@inheritdoc} - */ - public function getScripts() - { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-pnotify@1.3.2/dist/flasher-pnotify.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-pnotify.min.js', - ), - ); - } - - /** - * {@inheritdoc} - */ - public function getStyles() - { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-pnotify@1.3.2/dist/flasher-pnotify.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-pnotify.min.css', - ), - ); - } -} diff --git a/src/Pnotify/Prime/README.md b/src/Pnotify/Prime/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/src/Pnotify/Prime/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/src/Pnotify/Prime/Resources/assets/flasher-pnotify.min.css b/src/Pnotify/Prime/Resources/assets/flasher-pnotify.min.css deleted file mode 100644 index 41fb8247..00000000 --- a/src/Pnotify/Prime/Resources/assets/flasher-pnotify.min.css +++ /dev/null @@ -1,2 +0,0 @@ -body>.pnotify.pnotify-positioned{position:fixed;z-index:100040}body>.pnotify.pnotify-modal{z-index:100042}.pnotify{display:none;height:auto;opacity:0;transition:opacity .1s linear}.pnotify.pnotify-positioned{position:absolute;z-index:1}.pnotify.pnotify-modal{z-index:3}.pnotify.pnotify-in{display:block;opacity:1}.pnotify.pnotify-initial{display:block}.pnotify-hidden{visibility:hidden}.pnotify.pnotify-move{transition:left .4s ease,top .4s ease,right .4s ease,bottom .4s ease}.pnotify.pnotify-fade-slow{opacity:0;transition:opacity .4s linear}.pnotify.pnotify-fade-slow.pnotify.pnotify-move{transition:opacity .4s linear,left .4s ease,top .4s ease,right .4s ease,bottom .4s ease}.pnotify.pnotify-fade-normal{opacity:0;transition:opacity .25s linear}.pnotify.pnotify-fade-normal.pnotify.pnotify-move{transition:opacity .25s linear,left .4s ease,top .4s ease,right .4s ease,bottom .4s ease}.pnotify.pnotify-fade-fast{opacity:0;transition:opacity .1s linear}.pnotify.pnotify-fade-fast.pnotify.pnotify-move{transition:opacity .1s linear,left .4s ease,top .4s ease,right .4s ease,bottom .4s ease}.pnotify.pnotify-masking{display:block;-webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,.8),transparent 30px,transparent);mask-image:linear-gradient(180deg,rgba(0,0,0,.8),transparent 30px,transparent)}.pnotify.pnotify-masking.pnotify-stack-up{-webkit-mask-image:linear-gradient(0deg,rgba(0,0,0,.8),transparent 30px,transparent);mask-image:linear-gradient(0deg,rgba(0,0,0,.8),transparent 30px,transparent)}.pnotify.pnotify-masking.pnotify-stack-left{-webkit-mask-image:linear-gradient(270deg,rgba(0,0,0,.8),transparent 30px,transparent);mask-image:linear-gradient(270deg,rgba(0,0,0,.8),transparent 30px,transparent)}.pnotify.pnotify-masking.pnotify-stack-right{-webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,.8),transparent 30px,transparent);mask-image:linear-gradient(90deg,rgba(0,0,0,.8),transparent 30px,transparent)}.pnotify.pnotify-fade-in,.pnotify.pnotify-masking-in{opacity:1}.pnotify .pnotify-shadow{-webkit-box-shadow:0 6px 28px 0 rgba(0,0,0,.1);-moz-box-shadow:0 6px 28px 0 rgba(0,0,0,.1);box-shadow:0 6px 28px 0 rgba(0,0,0,.1)}.pnotify-container{background-position:0 0;height:100%;margin:0;padding:.8em;position:relative}.pnotify-container:after{clear:both;content:" ";display:block;height:0;visibility:hidden}.pnotify-closer,.pnotify-sticker{cursor:pointer;float:right;margin-left:.5em}[dir=rtl] .pnotify-closer,[dir=rtl] .pnotify-sticker{float:left;margin-left:0;margin-right:.5em}.pnotify-title{display:block;margin-bottom:.4em;margin-top:0;white-space:pre-line}.pnotify-text-with-max-height{overflow-y:auto;overscroll-behavior:contain;padding-bottom:.03em}.pnotify.pnotify-with-icon .pnotify-content{margin-left:24px}[dir=rtl] .pnotify.pnotify-with-icon .pnotify-content{margin-left:0;margin-right:24px}.pnotify-pre-line{white-space:pre-line}.pnotify-icon,.pnotify-icon span{display:block;float:left}[dir=rtl] .pnotify-icon,[dir=rtl] .pnotify-icon span{float:right}.pnotify-modal-overlay{align-items:flex-end;background-color:rgba(0,0,0,.6);display:flex;height:100%;justify-content:center;left:0;opacity:0;padding:0;position:absolute;top:0;transition:opacity .25s linear;width:100%;z-index:2}.pnotify-modal-overlay-up{align-items:flex-start}.pnotify-modal-overlay-left{align-items:center;justify-content:flex-start}.pnotify-modal-overlay-right{align-items:center;justify-content:flex-end}.pnotify-modal-overlay.pnotify-modal-overlay-in{opacity:1}.pnotify-modal-overlay-closes:after{color:#fff;content:"×";font-family:Arial;font-size:3rem;text-shadow:0 0 .4rem #fff}body>.pnotify-modal-overlay{position:fixed;z-index:100041} -[data-pnotify].brighttheme-elem{border-radius:0}[data-pnotify].brighttheme-elem,[data-pnotify].brighttheme-elem.pnotify-mode-light{--notice-background-color:#ffffa2;--notice-border-color:#ff0;--notice-text-color:#4f4f00;--notice-icon-filter:invert(25%) sepia(12%) saturate(7007%) hue-rotate(38deg) brightness(99%) contrast(101%);--info-background-color:#8fcedd;--info-border-color:#0286a5;--info-text-color:#012831;--info-icon-filter:invert(11%) sepia(37%) saturate(1946%) hue-rotate(155deg) brightness(95%) contrast(99%);--success-background-color:#aff29a;--success-border-color:#35db00;--success-text-color:#104300;--success-icon-filter:invert(17%) sepia(94%) saturate(1055%) hue-rotate(70deg) brightness(90%) contrast(103%);--error-background-color:#ffaba2;--error-border-color:#ff1800;--error-text-color:#4f0800;--error-icon-filter:invert(9%) sepia(27%) saturate(7347%) hue-rotate(359deg) brightness(96%) contrast(108%)}@media (prefers-color-scheme:dark){[data-pnotify].brighttheme-elem.pnotify-mode-no-preference{--notice-background-color:#4f4f00;--notice-border-color:#282814;--notice-text-color:#ffffa2;--notice-icon-filter:invert(92%) sepia(18%) saturate(781%) hue-rotate(6deg) brightness(106%) contrast(107%);--info-background-color:#012831;--info-border-color:#0c1618;--info-text-color:#8fcedd;--info-icon-filter:invert(85%) sepia(14%) saturate(933%) hue-rotate(153deg) brightness(92%) contrast(87%);--success-background-color:#104300;--success-border-color:#152111;--success-text-color:#aff29a;--success-icon-filter:invert(90%) sepia(9%) saturate(1647%) hue-rotate(52deg) brightness(103%) contrast(90%);--error-background-color:#4f0800;--error-border-color:#281614;--error-text-color:#ffaba2;--error-icon-filter:invert(70%) sepia(24%) saturate(717%) hue-rotate(315deg) brightness(103%) contrast(104%)}}[data-pnotify].brighttheme-elem.pnotify-mode-dark{--notice-background-color:#4f4f00;--notice-border-color:#282814;--notice-text-color:#ffffa2;--notice-icon-filter:invert(92%) sepia(18%) saturate(781%) hue-rotate(6deg) brightness(106%) contrast(107%);--info-background-color:#012831;--info-border-color:#0c1618;--info-text-color:#8fcedd;--info-icon-filter:invert(85%) sepia(14%) saturate(933%) hue-rotate(153deg) brightness(92%) contrast(87%);--success-background-color:#104300;--success-border-color:#152111;--success-text-color:#aff29a;--success-icon-filter:invert(90%) sepia(9%) saturate(1647%) hue-rotate(52deg) brightness(103%) contrast(90%);--error-background-color:#4f0800;--error-border-color:#281614;--error-text-color:#ffaba2;--error-icon-filter:invert(70%) sepia(24%) saturate(717%) hue-rotate(315deg) brightness(103%) contrast(104%)}[data-pnotify] .brighttheme-notice{--brighttheme-background-color:var(--notice-background-color);--brighttheme-border-color:var(--notice-border-color);--brighttheme-text-color:var(--notice-text-color);--brighttheme-icon-filter:var(--notice-icon-filter);--brighttheme-primary-button-background-color:var(--notice-border-color);--brighttheme-primary-button-text-color:var(--notice-text-color)}[data-pnotify] .brighttheme-info{--brighttheme-background-color:var(--info-background-color);--brighttheme-border-color:var(--info-border-color);--brighttheme-text-color:var(--info-text-color);--brighttheme-icon-filter:var(--info-icon-filter);--brighttheme-primary-button-background-color:var(--info-border-color);--brighttheme-primary-button-text-color:var(--info-text-color)}[data-pnotify] .brighttheme-success{--brighttheme-background-color:var(--success-background-color);--brighttheme-border-color:var(--success-border-color);--brighttheme-text-color:var(--success-text-color);--brighttheme-icon-filter:var(--success-icon-filter);--brighttheme-primary-button-background-color:var(--success-border-color);--brighttheme-primary-button-text-color:var(--success-text-color)}[data-pnotify] .brighttheme-error{--brighttheme-background-color:var(--error-background-color);--brighttheme-border-color:var(--error-border-color);--brighttheme-text-color:var(--error-text-color);--brighttheme-icon-filter:var(--error-icon-filter);--brighttheme-primary-button-background-color:var(--error-border-color);--brighttheme-primary-button-text-color:var(--error-text-color)}[data-pnotify] .brighttheme-container{background-color:var(--brighttheme-background-color);border:0 solid var(--brighttheme-border-color);color:var(--brighttheme-text-color);padding:1.3rem}[data-pnotify] .brighttheme-error{background-image:repeating-linear-gradient(135deg,transparent,transparent 35px,hsla(0,0%,100%,.3) 0,hsla(0,0%,100%,.3) 70px)}[data-pnotify].pnotify-with-icon .brighttheme-content{margin-left:calc(1.3rem + 16px)}[dir=rtl] [data-pnotify].pnotify-with-icon .brighttheme-content{margin-left:0;margin-right:calc(1.3rem + 16px)}[data-pnotify] .brighttheme-title{font-size:1.2rem;line-height:1.4rem;margin-bottom:0;margin-top:-.1rem}[data-pnotify] .brighttheme-text{font-size:1rem;line-height:1.2rem;margin-top:0}[data-pnotify] .brighttheme-confirm,[data-pnotify] .brighttheme-title+.brighttheme-text{margin-top:1rem}[data-pnotify] .brighttheme-closer,[data-pnotify] .brighttheme-icon,[data-pnotify] .brighttheme-sticker{align-items:center;display:flex;justify-content:center}[data-pnotify] .brighttheme-icon,[data-pnotify] .brighttheme-icon>span,[data-pnotify] .brighttheme-icon>span:after{height:1.2rem;line-height:1.2rem;width:1.2rem}[data-pnotify] .brighttheme-icon-closer,[data-pnotify] .brighttheme-icon-closer:after,[data-pnotify] .brighttheme-icon-sticker,[data-pnotify] .brighttheme-icon-sticker:after{height:1rem;line-height:1rem;width:1rem}[data-pnotify] .brighttheme-icon-notice:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTMsMTNIMTFWN0gxM00xMywxN0gxMVYxNUgxM00xMiwyQTEwLDEwIDAgMCwwIDIsMTJBMTAsMTAgMCAwLDAgMTIsMjJBMTAsMTAgMCAwLDAgMjIsMTJBMTAsMTAgMCAwLDAgMTIsMloiLz48L3N2Zz4=);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-icon-info:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTMsOUgxMVY3SDEzTTEzLDE3SDExVjExSDEzTTEyLDJBMTAsMTAgMCAwLDAgMiwxMkExMCwxMCAwIDAsMCAxMiwyMkExMCwxMCAwIDAsMCAyMiwxMkExMCwxMCAwIDAsMCAxMiwyWiIvPjwvc3ZnPg==);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-icon-success:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTIgMkM2LjUgMiAyIDYuNSAyIDEyUzYuNSAyMiAxMiAyMiAyMiAxNy41IDIyIDEyIDE3LjUgMiAxMiAyTTEwIDE3TDUgMTJMNi40MSAxMC41OUwxMCAxNC4xN0wxNy41OSA2LjU4TDE5IDhMMTAgMTdaIi8+PC9zdmc+);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-icon-error:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTMsMTRIMTFWMTBIMTNNMTMsMThIMTFWMTZIMTNNMSwyMUgyM0wxMiwyTDEsMjFaIi8+PC9zdmc+);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-icon-closer:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTksNi40MUwxNy41OSw1TDEyLDEwLjU5TDYuNDEsNUw1LDYuNDFMMTAuNTksMTJMNSwxNy41OUw2LjQxLDE5TDEyLDEzLjQxTDE3LjU5LDE5TDE5LDE3LjU5TDEzLjQxLDEyTDE5LDYuNDFaIi8+PC9zdmc+);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-icon-sticker:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTYsMTJWNEgxN1YySDdWNEg4VjEyTDYsMTRWMTZIMTEuMlYyMkgxMi44VjE2SDE4VjE0TDE2LDEyWiIvPjwvc3ZnPg==);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-icon-sticker.brighttheme-icon-stuck:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMiw1LjI3TDMuMjgsNEwyMCwyMC43MkwxOC43MywyMkwxMi44LDE2LjA3VjIySDExLjJWMTZINlYxNEw4LDEyVjExLjI3TDIsNS4yN00xNiwxMkwxOCwxNFYxNkgxNy44Mkw4LDYuMThWNEg3VjJIMTdWNEgxNlYxMloiLz48L3N2Zz4=);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-prompt-bar{margin-bottom:1rem}[data-pnotify] .brighttheme-action-bar,[data-pnotify] .brighttheme-prompt-bar{box-sizing:border-box;width:100%}[data-pnotify] .brighttheme-btn{background:transparent;border:none;color:var(--brighttheme-text-color);cursor:pointer;font-weight:700;padding:.4rem 1rem;text-transform:uppercase}[data-pnotify] .brighttheme-btn-primary{background-color:var(--brighttheme-primary-button-background-color);color:var(--brighttheme-primary-button-text-color)}[data-pnotify] .brighttheme-countdown{background-color:var(--brighttheme-background-color)}[data-pnotify] .brighttheme-countdown-bar{background-color:var(--brighttheme-border-color)}[data-pnotify] .brighttheme-paginate{display:inline-flex;flex-direction:column}[data-pnotify] .brighttheme-paginate-btn{background:transparent;border:0;height:1em;line-height:.5em;padding:0;width:1em}[data-pnotify] .brighttheme-paginate-previous{margin-right:0}[data-pnotify] .brighttheme-paginate-next{margin-left:0}[data-pnotify] .brighttheme-paginate-btn:disabled:after,[data-pnotify] .brighttheme-paginate-btn[aria-disabled=true]:after{opacity:.5}[data-pnotify] .brighttheme-paginate-previous:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xMS42NyAzLjg3TDkuOSAyLjEgMCAxMmw5LjkgOS45IDEuNzctMS43N0wzLjU0IDEyeiIvPjwvc3ZnPg==);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-paginate-next:after{content:url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik01Ljg4IDQuMTJMMTMuNzYgMTJsLTcuODggNy44OEw4IDIybDEwLTEwTDggMnoiLz48L3N2Zz4=);filter:var(--brighttheme-icon-filter)}[data-pnotify] .brighttheme-paginate-count-of{opacity:.8} \ No newline at end of file diff --git a/src/Pnotify/Prime/Resources/assets/flasher-pnotify.min.js b/src/Pnotify/Prime/Resources/assets/flasher-pnotify.min.js deleted file mode 100644 index a22d644f..00000000 --- a/src/Pnotify/Prime/Resources/assets/flasher-pnotify.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):((t="undefined"!=typeof globalThis?globalThis:t||self).flasher=t.flasher||{},t.flasher.pnotify=e(t.flasher))}(this,(function(t){"use strict";var e=function(){return e=Object.assign||function(t){for(var e,n=1,i=arguments.length;nt.length)&&(e=t.length);for(var n=0,i=new Array(e);n0&&void 0!==arguments[0]?arguments[0]:null;i(this,t),this.a=e,this.e=this.n=null}return r(t,[{key:"m",value:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;this.e||(this.e=E(e.nodeName),this.t=e,this.h(t)),this.i(n)}},{key:"h",value:function(t){this.e.innerHTML=t,this.n=Array.from(this.e.childNodes)}},{key:"i",value:function(t){for(var e=0;eg.get(T)?(b.add(M),w(O)):(x.add(T),d--):(c(C,s),d--)}for(;d--;){var E=t[d];y.has(E.key)||c(E,s)}for(;h;)w(v[h-1]);return v}function ft(t,e){for(var n={},i={},o={$$scope:1},r=t.length;r--;){var s=t[r],a=e[r];if(a){for(var c in s)c in a||(i[c]=1);for(var l in a)o[l]||(n[l]=a[l],o[l]=1);t[r]=a}else for(var u in s)o[u]=1}for(var f in i)f in n||(n[f]=void 0);return n}function dt(t){return"object"===e(t)&&null!==t?t:{}}function ht(t){t&&t.c()}function pt(t,e,n){var i=t.$$,o=i.fragment,r=i.on_mount,s=i.on_destroy,a=i.after_update;o&&o.m(e,n),X((function(){var e=r.map(k).filter(w);s?s.push.apply(s,v(e)):b(e),t.$$.on_mount=[]})),a.forEach(X)}function mt(t,e){var n=t.$$;null!==n.fragment&&(b(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function vt(t,e){-1===t.$$.dirty[0]&&(B.push(t),Q(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<1&&void 0!==arguments[1]?arguments[1]:{},i=n.start,o=void 0===i?"oldest":i,r=n.dir,s=void 0===r?"newer":r,a=n.skipModuleHandled,c=void 0!==a&&a;if("head"===o||"newest"===o&&"top"===this.push||"oldest"===o&&"bottom"===this.push)e=this._noticeHead.next;else if("tail"===o||"newest"===o&&"bottom"===this.push||"oldest"===o&&"top"===this.push)e=this._noticeTail.prev;else{if(!this._noticeMap.has(o))throw new Error("Invalid start param.");e=this._noticeMap.get(o)}for(;e.notice;){var l=e.notice;if("prev"===s||"top"===this.push&&"newer"===s||"bottom"===this.push&&"older"===s)e=e.prev;else{if(!("next"===s||"top"===this.push&&"older"===s||"bottom"===this.push&&"newer"===s))throw new Error("Invalid dir param.");e=e.next}if(!(c&&l.getModuleHandled()||!1!==t(l)))break}}},{key:"close",value:function(t){this.forEach((function(e){return e.close(t,!1,!1)}))}},{key:"open",value:function(t){this.forEach((function(e){return e.open(t)}))}},{key:"openLast",value:function(){this.forEach((function(t){if(-1===["opening","open","waiting"].indexOf(t.getState()))return t.open(),!1}),{start:"newest",dir:"older"})}},{key:"swap",value:function(t,e){var n=this,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2],o=arguments.length>3&&void 0!==arguments[3]&&arguments[3];return-1===["open","opening","closing"].indexOf(t.getState())?Promise.reject():(this._swapping=e,t.close(i,!1,o).then((function(){return e.open(i)})).finally((function(){n._swapping=!1})))}},{key:"on",value:function(t,e){var n=this;return t in this._callbacks||(this._callbacks[t]=[]),this._callbacks[t].push(e),function(){n._callbacks[t].splice(n._callbacks[t].indexOf(e),1)}}},{key:"fire",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e.stack=this,t in this._callbacks&&this._callbacks[t].forEach((function(t){return t(e)}))}},{key:"position",value:function(){var t=this;this.positioned&&this._length>0?(this.fire("beforePosition"),this._resetPositionData(),this.forEach((function(e){t._positionNotice(e)}),{start:"head",dir:"next",skipModuleHandled:!0}),this.fire("afterPosition")):(delete this._nextpos1,delete this._nextpos2)}},{key:"queuePosition",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:10;this._posTimer&&clearTimeout(this._posTimer),this._posTimer=setTimeout((function(){return t.position()}),e)}},{key:"_resetPositionData",value:function(){this._nextpos1=this.firstpos1,this._nextpos2=this.firstpos2,this._addpos2=0}},{key:"_positionNotice",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t===this._masking;if(this.positioned){var n=t.refs.elem;if(n&&(n.classList.contains("pnotify-in")||n.classList.contains("pnotify-initial")||e)){var i=[this.firstpos1,this.firstpos2,this._nextpos1,this._nextpos2,this._addpos2],o=i[0],r=i[1],s=i[2],a=i[3],c=i[4];n.getBoundingClientRect(),!this._animation||e||this._collapsingModalState?t._setMoveClass(""):t._setMoveClass("pnotify-move");var l,u=this.context===document.body?window.innerHeight:this.context.scrollHeight,f=this.context===document.body?window.innerWidth:this.context.scrollWidth;if(this.dir1){var d;switch(l={down:"top",up:"bottom",left:"right",right:"left"}[this.dir1],this.dir1){case"down":d=n.offsetTop;break;case"up":d=u-n.scrollHeight-n.offsetTop;break;case"left":d=f-n.scrollWidth-n.offsetLeft;break;case"right":d=n.offsetLeft}null==o&&(s=o=d)}if(this.dir1&&this.dir2){var h,p={down:"top",up:"bottom",left:"right",right:"left"}[this.dir2];switch(this.dir2){case"down":h=n.offsetTop;break;case"up":h=u-n.scrollHeight-n.offsetTop;break;case"left":h=f-n.scrollWidth-n.offsetLeft;break;case"right":h=n.offsetLeft}if(null==r&&(a=r=h),!e){var m=s+n.offsetHeight+this.spacing1,v=s+n.offsetWidth+this.spacing1;(("down"===this.dir1||"up"===this.dir1)&&m>u||("left"===this.dir1||"right"===this.dir1)&&v>f)&&(s=o,a+=c+this.spacing2,c=0)}switch(null!=a&&(n.style[p]="".concat(a,"px"),this._animation||n.style[p]),this.dir2){case"down":case"up":n.offsetHeight+(parseFloat(n.style.marginTop,10)||0)+(parseFloat(n.style.marginBottom,10)||0)>c&&(c=n.offsetHeight);break;case"left":case"right":n.offsetWidth+(parseFloat(n.style.marginLeft,10)||0)+(parseFloat(n.style.marginRight,10)||0)>c&&(c=n.offsetWidth)}}else if(this.dir1){var y,g;switch(this.dir1){case"down":case"up":g=["left","right"],y=this.context.scrollWidth/2-n.offsetWidth/2;break;case"left":case"right":g=["top","bottom"],y=u/2-n.offsetHeight/2}n.style[g[0]]="".concat(y,"px"),n.style[g[1]]="auto",this._animation||n.style[g[0]]}if(this.dir1)switch(null!=s&&(n.style[l]="".concat(s,"px"),this._animation||n.style[l]),this.dir1){case"down":case"up":s+=n.offsetHeight+this.spacing1;break;case"left":case"right":s+=n.offsetWidth+this.spacing1}else{var $=f/2-n.offsetWidth/2,_=u/2-n.offsetHeight/2;n.style.left="".concat($,"px"),n.style.top="".concat(_,"px"),this._animation||n.style.left}e||(this.firstpos1=o,this.firstpos2=r,this._nextpos1=s,this._nextpos2=a,this._addpos2=c)}}}},{key:"_addNotice",value:function(t){var e=this;this.fire("beforeAddNotice",{notice:t});var n=function(){if(e.fire("beforeOpenNotice",{notice:t}),t.getModuleHandled())e.fire("afterOpenNotice",{notice:t});else{if(e._openNotices++,("ish"!==e.modal||!e._overlayOpen)&&e.maxOpen!==1/0&&e._openNotices>e.maxOpen&&"close"===e.maxStrategy){var n=e._openNotices-e.maxOpen;e.forEach((function(t){if(-1!==["opening","open"].indexOf(t.getState()))return t.close(!1,!1,e.maxClosureCausesWait),t===e._leader&&e._setLeader(null),!!--n}))}!0===e.modal&&e._insertOverlay(),"ish"!==e.modal||e._leader&&-1!==["opening","open","closing"].indexOf(e._leader.getState())||e._setLeader(t),"ish"===e.modal&&e._overlayOpen&&t._preventTimerClose(!0),e.fire("afterOpenNotice",{notice:t})}},i={notice:t,prev:null,next:null,beforeOpenOff:t.on("pnotify:beforeOpen",n),afterCloseOff:t.on("pnotify:afterClose",(function(){if(e.fire("beforeCloseNotice",{notice:t}),t.getModuleHandled())e.fire("afterCloseNotice",{notice:t});else{if(e._openNotices--,"ish"===e.modal&&t===e._leader&&(e._setLeader(null),e._masking&&e._setMasking(null)),!e._swapping&&e.maxOpen!==1/0&&e._openNotices=e.maxOpen))return n=!0,!1};"wait"===e.maxStrategy?(e.forEach(i,{start:t,dir:"next"}),n||e.forEach(i,{start:t,dir:"prev"})):"close"===e.maxStrategy&&e.maxClosureCausesWait&&(e.forEach(i,{start:t,dir:"older"}),n||e.forEach(i,{start:t,dir:"newer"}))}e._openNotices<=0?(e._openNotices=0,e._resetPositionData(),e._overlayOpen&&!e._swapping&&e._removeOverlay()):e._collapsingModalState||e.queuePosition(0),e.fire("afterCloseNotice",{notice:t})}}))};if("top"===this.push?(i.next=this._noticeHead.next,i.prev=this._noticeHead,i.next.prev=i,i.prev.next=i):(i.prev=this._noticeTail.prev,i.next=this._noticeTail,i.prev.next=i,i.next.prev=i),this._noticeMap.set(t,i),this._length++,this._listener||(this._listener=function(){return e.position()},this.context.addEventListener("pnotify:position",this._listener)),-1!==["open","opening","closing"].indexOf(t.getState()))n();else if("ish"===this.modal&&this.modalishFlash&&this._shouldNoticeWait(t))var o=t.on("pnotify:mount",(function(){o(),t._setMasking(!0,!1,(function(){t._setMasking(!1)})),e._resetPositionData(),e._positionNotice(e._leader),window.requestAnimationFrame((function(){e._positionNotice(t,!0)}))}));this.fire("afterAddNotice",{notice:t})}},{key:"_removeNotice",value:function(t){if(this._noticeMap.has(t)){this.fire("beforeRemoveNotice",{notice:t});var e=this._noticeMap.get(t);this._leader===t&&this._setLeader(null),this._masking===t&&this._setMasking(null),e.prev.next=e.next,e.next.prev=e.prev,e.prev=null,e.next=null,e.beforeOpenOff(),e.beforeOpenOff=null,e.afterCloseOff(),e.afterCloseOff=null,this._noticeMap.delete(t),this._length--,!this._length&&this._listener&&(this.context.removeEventListener("pnotify:position",this._listener),this._listener=null),!this._length&&this._overlayOpen&&this._removeOverlay(),-1!==["open","opening","closing"].indexOf(t.getState())&&this._handleNoticeClosed(t),this.fire("afterRemoveNotice",{notice:t})}}},{key:"_setLeader",value:function(t){var e=this;if(this.fire("beforeSetLeader",{leader:t}),this._leaderOff&&(this._leaderOff(),this._leaderOff=null),this._leader=t,this._leader){var n,i=function(){var t=null;e._overlayOpen&&(e._collapsingModalState=!0,e.forEach((function(n){n._preventTimerClose(!1),n!==e._leader&&-1!==["opening","open"].indexOf(n.getState())&&(t||(t=n),n.close(n===t,!1,!0))}),{start:e._leader,dir:"next",skipModuleHandled:!0}),e._removeOverlay()),o&&(clearTimeout(o),o=null),e.forEach((function(n){if(n!==e._leader)return"waiting"===n.getState()||n===t?(e._setMasking(n,!!t),!1):void 0}),{start:e._leader,dir:"next",skipModuleHandled:!0})},o=null,r=function(){o&&(clearTimeout(o),o=null),o=setTimeout((function(){o=null,e._setMasking(null)}),750)};this._leaderOff=(n=[this._leader.on("mouseenter",i),this._leader.on("focusin",i),this._leader.on("mouseleave",r),this._leader.on("focusout",r)],function(){return n.map((function(t){return t()}))}),this.fire("afterSetLeader",{leader:t})}else this.fire("afterSetLeader",{leader:t})}},{key:"_setMasking",value:function(t,e){var n=this;if(this._masking){if(this._masking===t)return;this._masking._setMasking(!1,e)}if(this._maskingOff&&(this._maskingOff(),this._maskingOff=null),this._masking=t,this._masking){this._resetPositionData(),this._leader&&this._positionNotice(this._leader),this._masking._setMasking(!0,e),window.requestAnimationFrame((function(){n._masking&&n._positionNotice(n._masking)}));var i,o=function(){"ish"===n.modal&&(n._insertOverlay(),n._setMasking(null,!0),n.forEach((function(t){t._preventTimerClose(!0),"waiting"===t.getState()&&t.open()}),{start:n._leader,dir:"next",skipModuleHandled:!0}))};this._maskingOff=(i=[this._masking.on("mouseenter",o),this._masking.on("focusin",o)],function(){return i.map((function(t){return t()}))})}}},{key:"_shouldNoticeWait",value:function(t){return this._swapping!==t&&!("ish"===this.modal&&this._overlayOpen)&&this.maxOpen!==1/0&&this._openNotices>=this.maxOpen&&"wait"===this.maxStrategy}},{key:"_insertOverlay",value:function(){var t=this;this._overlay||(this._overlay=document.createElement("div"),this._overlay.classList.add("pnotify-modal-overlay"),this.dir1&&this._overlay.classList.add("pnotify-modal-overlay-".concat(this.dir1)),this.overlayClose&&this._overlay.classList.add("pnotify-modal-overlay-closes"),this.context!==document.body&&(this._overlay.style.height="".concat(this.context.scrollHeight,"px"),this._overlay.style.width="".concat(this.context.scrollWidth,"px")),this._overlay.addEventListener("click",(function(e){if(t.overlayClose){if(t.fire("overlayClose",{clickEvent:e}),e.defaultPrevented)return;t._leader&&t._setLeader(null),t.forEach((function(e){-1===["closed","closing","waiting"].indexOf(e.getState())&&(e.hide||t.overlayClosesPinned?e.close():e.hide||"ish"!==t.modal||(t._leader?e.close(!1,!1,!0):t._setLeader(e)))}),{skipModuleHandled:!0}),t._overlayOpen&&t._removeOverlay()}}))),this._overlay.parentNode!==this.context&&(this.fire("beforeAddOverlay"),this._overlay.classList.remove("pnotify-modal-overlay-in"),this._overlay=this.context.insertBefore(this._overlay,this.context.firstChild),this._overlayOpen=!0,this._overlayInserted=!0,window.requestAnimationFrame((function(){t._overlay.classList.add("pnotify-modal-overlay-in"),t.fire("afterAddOverlay")}))),this._collapsingModalState=!1}},{key:"_removeOverlay",value:function(){var t=this;this._overlay.parentNode&&(this.fire("beforeRemoveOverlay"),this._overlay.classList.remove("pnotify-modal-overlay-in"),this._overlayOpen=!1,setTimeout((function(){t._overlayInserted=!1,t._overlay.parentNode&&(t._overlay.parentNode.removeChild(t._overlay),t.fire("afterRemoveOverlay"))}),250),setTimeout((function(){t._collapsingModalState=!1}),400))}},{key:"notices",get:function(){var t=[];return this.forEach((function(e){return t.push(e)})),t}},{key:"length",get:function(){return this._length}},{key:"leader",get:function(){return this._leader}}]),t}(),$t=function(){for(var t=arguments.length,e=new Array(t),n=0;n1&&void 0!==arguments[1]?arguments[1]:[]));function n(e){F(t,e)}return function(t){for(var i=[],o=0;o1&&void 0!==arguments[1]?arguments[1]:{});"init"===t&&Array.from(a).forEach((function(t){var n=m(t,2),i=n[0];return n[1],"init"in i&&i.init(e)}));var n=f.elem||u&&u.context||document.body;if(!n)return o("pnotify:".concat(t),e),!0;var r=new Event("pnotify:".concat(t),{bubbles:"init"===t||"mount"===t,cancelable:t.startsWith("before")});return r.detail=e,n.dispatchEvent(r),!r.defaultPrevented}function Vt(){var t=u&&u.context||document.body;if(!t)throw new Error("No context to insert this notice into.");if(!f.elem)throw new Error("Trying to insert notice before element is available.");f.elem.parentNode!==t&&t.appendChild(f.elem)}function Xt(){f.elem&&f.elem.parentNode.removeChild(f.elem)}h=function(){Qt("mount"),B&&ue().catch((function(){}))},I().$$.on_mount.push(h),function(t){I().$$.before_update.push(t)}((function(){Qt("update"),"closed"!==Ct&&"waiting"!==Ct&&at!==qt&&(at?qt||ge():ye()),"closed"!==Ct&&"closing"!==Ct&&u&&!u._collapsingModalState&&u.queuePosition(),qt=at}));var Yt,Zt,te,ee,ne,ie,oe,re,se,ae,ce,le=e.open,ue=void 0===le?function(t){if("opening"===Ct)return Ft;if("open"===Ct)return at&&ge(),Promise.resolve();if(!At&&u&&u._shouldNoticeWait(i))return Ct="waiting",Promise.reject();if(!Qt("beforeOpen",{immediate:t}))return Promise.reject();var e,o;Ct="opening",n(28,Wt=!1),n(24,St="pnotify-initial pnotify-hidden");var r=new Promise((function(t,n){e=t,o=n}));Ft=r;var s=function(){at&&ge(),Ct="open",Qt("afterOpen",{immediate:t}),Ft=null,e()};return Rt?(s(),Promise.resolve()):(Vt(),window.requestAnimationFrame((function(){if("opening"!==Ct)return o(),void(Ft=null);u&&(n(0,u._animation=!1,u),"top"===u.push&&u._resetPositionData(),u._positionNotice(i),u.queuePosition(0),n(0,u._animation=!0,u)),pe(s,t)})),r)}:le,fe=e.close,de=void 0===fe?function(t,e,o){if("closing"===Ct)return Bt;if("closed"===Ct)return Promise.resolve();var r,s=function(){Qt("beforeDestroy")&&(u&&u._removeNotice(i),i.$destroy(),Qt("afterDestroy"))};if("waiting"===Ct)return o||(Ct="closed",Ot&&!o&&s()),Promise.resolve();if(!Qt("beforeClose",{immediate:t,timerHide:e,waitAfterward:o}))return Promise.reject();Ct="closing",jt=!!e,Mt&&"prevented"!==Mt&&clearTimeout&&clearTimeout(Mt),Mt=null;var a=new Promise((function(t,e){r=t}));return Bt=a,ve((function(){n(26,Pt=!1),jt=!1,Ct=o?"waiting":"closed",Qt("afterClose",{immediate:t,timerHide:e,waitAfterward:o}),Bt=null,r(),o||(Ot?s():bt&&Xt())}),t),a}:fe,he=e.animateIn,pe=void 0===he?function(t,e){Ht="in";var i=function e(n){if(!(n&&f.elem&&n.target!==f.elem||(f.elem&&f.elem.removeEventListener("transitionend",e),Tt&&clearTimeout(Tt),"in"!==Ht))){var i=Rt;if(!i&&f.elem){var o=f.elem.getBoundingClientRect();for(var r in o)if(o[r]>0){i=!0;break}}i?(t&&t.call(),Ht=!1):Tt=setTimeout(e,40)}};if("fade"!==et||e){var o=et;n(2,et="none"),n(24,St="pnotify-in ".concat("fade"===o?"pnotify-fade-in":"")),V().then((function(){n(2,et=o),i()}))}else f.elem&&f.elem.addEventListener("transitionend",i),n(24,St="pnotify-in"),V().then((function(){n(24,St="pnotify-in pnotify-fade-in"),Tt=setTimeout(i,650)}))}:he,me=e.animateOut,ve=void 0===me?function(t,e){Ht="out";var i=function e(i){if(!(i&&f.elem&&i.target!==f.elem||(f.elem&&f.elem.removeEventListener("transitionend",e),Et&&clearTimeout(Et),"out"!==Ht))){var o=Rt;if(!o&&f.elem){var r=f.elem.getBoundingClientRect();for(var s in r)if(r[s]>0){o=!0;break}}f.elem&&f.elem.style.opacity&&"0"!==f.elem.style.opacity&&o?Et=setTimeout(e,40):(n(24,St=""),t&&t.call(),Ht=!1)}};"fade"!==et||e?(n(24,St=""),V().then((function(){i()}))):(f.elem&&f.elem.addEventListener("transitionend",i),n(24,St="pnotify-in"),Et=setTimeout(i,650))}:me;function ye(){Mt&&"prevented"!==Mt&&(clearTimeout(Mt),Mt=null),Et&&clearTimeout(Et),"closing"===Ct&&(Ct="open",Ht=!1,n(24,St="fade"===et?"pnotify-in pnotify-fade-in":"pnotify-in"))}function ge(){"prevented"!==Mt&&(ye(),lt!==1/0&&(Mt=setTimeout((function(){return de(!1,!0)}),isNaN(lt)?0:lt)))}return t.$$set=function(t){"modules"in t&&n(46,a=t.modules),"stack"in t&&n(0,u=t.stack),"type"in t&&n(4,y=t.type),"title"in t&&n(5,$=t.title),"titleTrusted"in t&&n(6,k=t.titleTrusted),"text"in t&&n(7,b=t.text),"textTrusted"in t&&n(8,O=t.textTrusted),"styling"in t&&n(47,M=t.styling),"icons"in t&&n(48,E=t.icons),"mode"in t&&n(9,S=t.mode),"addClass"in t&&n(10,P=t.addClass),"addModalClass"in t&&n(11,A=t.addModalClass),"addModelessClass"in t&&n(12,W=t.addModelessClass),"autoOpen"in t&&n(49,B=t.autoOpen),"width"in t&&n(50,G=t.width),"minHeight"in t&&n(51,K=t.minHeight),"maxTextHeight"in t&&n(52,X=t.maxTextHeight),"icon"in t&&n(13,Z=t.icon),"animation"in t&&n(2,et=t.animation),"animateSpeed"in t&&n(14,it=t.animateSpeed),"shadow"in t&&n(15,rt=t.shadow),"hide"in t&&n(3,at=t.hide),"delay"in t&&n(53,lt=t.delay),"mouseReset"in t&&n(54,ft=t.mouseReset),"closer"in t&&n(16,ht=t.closer),"closerHover"in t&&n(17,mt=t.closerHover),"sticker"in t&&n(18,yt=t.sticker),"stickerHover"in t&&n(19,$t=t.stickerHover),"labels"in t&&n(20,kt=t.labels),"remove"in t&&n(55,bt=t.remove),"destroy"in t&&n(56,Ot=t.destroy),"open"in t&&n(59,ue=t.open),"close"in t&&n(23,de=t.close),"animateIn"in t&&n(60,pe=t.animateIn),"animateOut"in t&&n(61,ve=t.animateOut)},t.$$.update=function(){524288&t.$$.dirty[1]&&n(31,Yt="string"==typeof G?"width: ".concat(G,";"):""),1048576&t.$$.dirty[1]&&n(32,Zt="string"==typeof K?"min-height: ".concat(K,";"):""),2097152&t.$$.dirty[1]&&n(33,te="string"==typeof X?"max-height: ".concat(X,";"):""),32&t.$$.dirty[0]&&n(34,ee=$ instanceof HTMLElement),128&t.$$.dirty[0]&&n(35,ne=b instanceof HTMLElement),1&t.$$.dirty[0]|1792&t.$$.dirty[3]&&Gt!==u&&(Gt&&(Gt._removeNotice(i),n(30,zt=!1),Jt(),Kt()),u&&(u._addNotice(i),n(102,Jt=u.on("beforeAddOverlay",(function(){n(30,zt=!0),Qt("enterModal")}))),n(103,Kt=u.on("afterRemoveOverlay",(function(){n(30,zt=!1),Qt("leaveModal")})))),n(101,Gt=u)),1073748992&t.$$.dirty[0]&&n(36,ie=P.match(/\bnonblock\b/)||A.match(/\bnonblock\b/)&&zt||W.match(/\bnonblock\b/)&&!zt),1&t.$$.dirty[0]&&n(37,oe=u&&u.dir1?"pnotify-stack-".concat(u.dir1):""),32768&t.$$.dirty[1]&&n(38,re=Array.from(a).filter((function(t){var e=m(t,2),n=e[0];return e[1],"PrependContainer"===n.position}))),32768&t.$$.dirty[1]&&n(39,se=Array.from(a).filter((function(t){var e=m(t,2),n=e[0];return e[1],"PrependContent"===n.position}))),32768&t.$$.dirty[1]&&n(40,ae=Array.from(a).filter((function(t){var e=m(t,2),n=e[0];return e[1],"AppendContent"===n.position}))),32768&t.$$.dirty[1]&&n(41,ce=Array.from(a).filter((function(t){var e=m(t,2),n=e[0];return e[1],"AppendContainer"===n.position}))),34&t.$$.dirty[0]|8&t.$$.dirty[1]&&ee&&f.titleContainer&&f.titleContainer.appendChild($),130&t.$$.dirty[0]|16&t.$$.dirty[1]&&ne&&f.textContainer&&f.textContainer.appendChild(b)},[u,f,et,at,y,$,k,b,O,S,P,A,W,Z,it,rt,ht,mt,yt,$t,kt,function(t){return"string"==typeof M?"".concat(M,"-").concat(t):t in M?M[t]:"".concat(M.prefix,"-").concat(t)},function(t){return"string"==typeof E?"".concat(E,"-icon-").concat(t):t in E?E[t]:"".concat(E.prefix,"-icon-").concat(t)},de,St,Nt,Pt,Lt,Wt,Dt,zt,Yt,Zt,te,ee,ne,ie,oe,re,se,ae,ce,i,r,function(t){if(n(26,Pt=!0),ft&&"closing"===Ct){if(!jt)return;ye()}at&&ft&&ye()},function(t){n(26,Pt=!1),at&&ft&&"out"!==Ht&&-1!==["open","opening"].indexOf(Ct)&&ge()},a,M,E,B,G,K,X,lt,ft,bt,Ot,function(){return Ct},function(){return Mt},ue,pe,ve,ye,ge,function(t){t?(ye(),Mt="prevented"):"prevented"===Mt&&(Mt=null,"open"===Ct&&at&&ge())},function(){return i.$on.apply(i,arguments)},function(){return i.$set.apply(i,arguments)},function(t,e){o(t,e)},function(t){for(var e=0;e<(arguments.length<=1?0:arguments.length-1);e++){var i=e+1<1||arguments.length<=e+1?void 0:arguments[e+1];-1===Lt[t].indexOf(i)&&Lt[t].push(i)}n(27,Lt)},function(t){for(var e=0;e<(arguments.length<=1?0:arguments.length-1);e++){var i=e+1<1||arguments.length<=e+1?void 0:arguments[e+1],o=Lt[t].indexOf(i);-1!==o&&Lt[t].splice(o,1)}n(27,Lt)},function(t){for(var e=0;e<(arguments.length<=1?0:arguments.length-1);e++){var n=e+1<1||arguments.length<=e+1?void 0:arguments[e+1];if(-1===Lt[t].indexOf(n))return!1}return!0},function(){return At},function(t){return At=t},function(){return Rt},function(t){return Rt=t},function(t){return Ht=t},function(){return St},function(t){return n(24,St=t)},function(){return Nt},function(t){return n(25,Nt=t)},function(t,e,i){if(It&&clearTimeout(It),Wt!==t)if(t)n(28,Wt=!0),n(29,Dt=!!e),Vt(),V().then((function(){window.requestAnimationFrame((function(){if(Wt)if(e&&i)i();else{n(29,Dt=!0);var t=function t(){f.elem&&f.elem.removeEventListener("transitionend",t),It&&clearTimeout(It),Dt&&i&&i()};f.elem&&f.elem.addEventListener("transitionend",t),It=setTimeout(t,650)}}))}));else if(e)n(28,Wt=!1),n(29,Dt=!1),bt&&-1===["open","opening","closing"].indexOf(Ct)&&Xt(),i&&i();else{var o=function t(){f.elem&&f.elem.removeEventListener("transitionend",t),It&&clearTimeout(It),Dt||(n(28,Wt=!1),bt&&-1===["open","opening","closing"].indexOf(Ct)&&Xt(),i&&i())};n(29,Dt=!1),f.elem&&f.elem.addEventListener("transitionend",o),f.elem&&f.elem.style.opacity,It=setTimeout(o,650)}},function(){return de(!1)},function(){return n(3,at=!at)},function(t){z[t?"unshift":"push"]((function(){f.iconContainer=t,n(1,f)}))},function(t){z[t?"unshift":"push"]((function(){f.titleContainer=t,n(1,f)}))},function(t){z[t?"unshift":"push"]((function(){f.textContainer=t,n(1,f)}))},function(t){z[t?"unshift":"push"]((function(){f.content=t,n(1,f)}))},function(t){z[t?"unshift":"push"]((function(){f.container=t,n(1,f)}))},function(t){z[t?"unshift":"push"]((function(){f.elem=t,n(1,f)}))}]}window&&document.body?Gt():document.addEventListener("DOMContentLoaded",Gt);var Kt=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&u(t,e)}(s,t);var e,n,o=(e=s,n=f(),function(){var t,i=l(e);if(n){var o=l(this).constructor;t=Reflect.construct(i,arguments,o)}else t=i.apply(this,arguments);return p(this,t)});function s(t){var e;return i(this,s),function(t,e,n,i,o,r){var s=arguments.length>6&&void 0!==arguments[6]?arguments[6]:[-1],a=R;D(t);var c=e.props||{},l=t.$$={fragment:null,ctx:null,props:r,update:$,not_equal:o,bound:x(),on_mount:[],on_destroy:[],before_update:[],after_update:[],context:new Map(a?a.$$.context:[]),callbacks:x(),dirty:s,skip_bound:!1},u=!1;if(l.ctx=n?n(t,c,(function(e,n){var i=!(arguments.length<=2)&&arguments.length-2?arguments.length<=2?void 0:arguments[2]:n;return l.ctx&&o(l.ctx[e],l.ctx[e]=i)&&(!l.skip_bound&&l.bound[e]&&l.bound[e](i),u&&vt(t,e)),n})):[],l.update(),u=!0,b(l.before_update),l.fragment=!!i&&i(l.ctx),e.target){if(e.hydrate){var f=L(e.target);l.fragment&&l.fragment.l(f),f.forEach(T)}else l.fragment&&l.fragment.c();e.intro&&st(t.$$.fragment),pt(t,e.target,e.anchor),tt()}D(a)}(h(e=o.call(this)),t,Jt,It,O,{modules:46,stack:0,refs:1,type:4,title:5,titleTrusted:6,text:7,textTrusted:8,styling:47,icons:48,mode:9,addClass:10,addModalClass:11,addModelessClass:12,autoOpen:49,width:50,minHeight:51,maxTextHeight:52,icon:13,animation:2,animateSpeed:14,shadow:15,hide:3,delay:53,mouseReset:54,closer:16,closerHover:17,sticker:18,stickerHover:19,labels:20,remove:55,destroy:56,getState:57,getTimer:58,getStyle:21,getIcon:22,open:59,close:23,animateIn:60,animateOut:61,cancelClose:62,queueClose:63,_preventTimerClose:64,on:65,update:66,fire:67,addModuleClass:68,removeModuleClass:69,hasModuleClass:70,getModuleHandled:71,setModuleHandled:72,getModuleOpen:73,setModuleOpen:74,setAnimating:75,getAnimatingClass:76,setAnimatingClass:77,_getMoveClass:78,_setMoveClass:79,_setMasking:80},[-1,-1,-1,-1]),e}return r(s,[{key:"modules",get:function(){return this.$$.ctx[46]},set:function(t){this.$set({modules:t}),tt()}},{key:"stack",get:function(){return this.$$.ctx[0]},set:function(t){this.$set({stack:t}),tt()}},{key:"refs",get:function(){return this.$$.ctx[1]}},{key:"type",get:function(){return this.$$.ctx[4]},set:function(t){this.$set({type:t}),tt()}},{key:"title",get:function(){return this.$$.ctx[5]},set:function(t){this.$set({title:t}),tt()}},{key:"titleTrusted",get:function(){return this.$$.ctx[6]},set:function(t){this.$set({titleTrusted:t}),tt()}},{key:"text",get:function(){return this.$$.ctx[7]},set:function(t){this.$set({text:t}),tt()}},{key:"textTrusted",get:function(){return this.$$.ctx[8]},set:function(t){this.$set({textTrusted:t}),tt()}},{key:"styling",get:function(){return this.$$.ctx[47]},set:function(t){this.$set({styling:t}),tt()}},{key:"icons",get:function(){return this.$$.ctx[48]},set:function(t){this.$set({icons:t}),tt()}},{key:"mode",get:function(){return this.$$.ctx[9]},set:function(t){this.$set({mode:t}),tt()}},{key:"addClass",get:function(){return this.$$.ctx[10]},set:function(t){this.$set({addClass:t}),tt()}},{key:"addModalClass",get:function(){return this.$$.ctx[11]},set:function(t){this.$set({addModalClass:t}),tt()}},{key:"addModelessClass",get:function(){return this.$$.ctx[12]},set:function(t){this.$set({addModelessClass:t}),tt()}},{key:"autoOpen",get:function(){return this.$$.ctx[49]},set:function(t){this.$set({autoOpen:t}),tt()}},{key:"width",get:function(){return this.$$.ctx[50]},set:function(t){this.$set({width:t}),tt()}},{key:"minHeight",get:function(){return this.$$.ctx[51]},set:function(t){this.$set({minHeight:t}),tt()}},{key:"maxTextHeight",get:function(){return this.$$.ctx[52]},set:function(t){this.$set({maxTextHeight:t}),tt()}},{key:"icon",get:function(){return this.$$.ctx[13]},set:function(t){this.$set({icon:t}),tt()}},{key:"animation",get:function(){return this.$$.ctx[2]},set:function(t){this.$set({animation:t}),tt()}},{key:"animateSpeed",get:function(){return this.$$.ctx[14]},set:function(t){this.$set({animateSpeed:t}),tt()}},{key:"shadow",get:function(){return this.$$.ctx[15]},set:function(t){this.$set({shadow:t}),tt()}},{key:"hide",get:function(){return this.$$.ctx[3]},set:function(t){this.$set({hide:t}),tt()}},{key:"delay",get:function(){return this.$$.ctx[53]},set:function(t){this.$set({delay:t}),tt()}},{key:"mouseReset",get:function(){return this.$$.ctx[54]},set:function(t){this.$set({mouseReset:t}),tt()}},{key:"closer",get:function(){return this.$$.ctx[16]},set:function(t){this.$set({closer:t}),tt()}},{key:"closerHover",get:function(){return this.$$.ctx[17]},set:function(t){this.$set({closerHover:t}),tt()}},{key:"sticker",get:function(){return this.$$.ctx[18]},set:function(t){this.$set({sticker:t}),tt()}},{key:"stickerHover",get:function(){return this.$$.ctx[19]},set:function(t){this.$set({stickerHover:t}),tt()}},{key:"labels",get:function(){return this.$$.ctx[20]},set:function(t){this.$set({labels:t}),tt()}},{key:"remove",get:function(){return this.$$.ctx[55]},set:function(t){this.$set({remove:t}),tt()}},{key:"destroy",get:function(){return this.$$.ctx[56]},set:function(t){this.$set({destroy:t}),tt()}},{key:"getState",get:function(){return this.$$.ctx[57]}},{key:"getTimer",get:function(){return this.$$.ctx[58]}},{key:"getStyle",get:function(){return this.$$.ctx[21]}},{key:"getIcon",get:function(){return this.$$.ctx[22]}},{key:"open",get:function(){return this.$$.ctx[59]},set:function(t){this.$set({open:t}),tt()}},{key:"close",get:function(){return this.$$.ctx[23]},set:function(t){this.$set({close:t}),tt()}},{key:"animateIn",get:function(){return this.$$.ctx[60]},set:function(t){this.$set({animateIn:t}),tt()}},{key:"animateOut",get:function(){return this.$$.ctx[61]},set:function(t){this.$set({animateOut:t}),tt()}},{key:"cancelClose",get:function(){return this.$$.ctx[62]}},{key:"queueClose",get:function(){return this.$$.ctx[63]}},{key:"_preventTimerClose",get:function(){return this.$$.ctx[64]}},{key:"on",get:function(){return this.$$.ctx[65]}},{key:"update",get:function(){return this.$$.ctx[66]}},{key:"fire",get:function(){return this.$$.ctx[67]}},{key:"addModuleClass",get:function(){return this.$$.ctx[68]}},{key:"removeModuleClass",get:function(){return this.$$.ctx[69]}},{key:"hasModuleClass",get:function(){return this.$$.ctx[70]}},{key:"getModuleHandled",get:function(){return this.$$.ctx[71]}},{key:"setModuleHandled",get:function(){return this.$$.ctx[72]}},{key:"getModuleOpen",get:function(){return this.$$.ctx[73]}},{key:"setModuleOpen",get:function(){return this.$$.ctx[74]}},{key:"setAnimating",get:function(){return this.$$.ctx[75]}},{key:"getAnimatingClass",get:function(){return this.$$.ctx[76]}},{key:"setAnimatingClass",get:function(){return this.$$.ctx[77]}},{key:"_getMoveClass",get:function(){return this.$$.ctx[78]}},{key:"_setMoveClass",get:function(){return this.$$.ctx[79]}},{key:"_setMasking",get:function(){return this.$$.ctx[80]}}]),s}(yt);t.Stack=gt,t.alert=function(t){return $t(qt(t))},t.default=Kt,t.defaultModules=zt,t.defaultStack=Bt,t.defaults=Ut,t.error=function(t){return $t(qt(t,"error"))},t.info=function(t){return $t(qt(t,"info"))},t.notice=function(t){return $t(qt(t,"notice"))},t.success=function(t){return $t(qt(t,"success"))},Object.defineProperty(t,"__esModule",{value:!0})}(e)}(0,i.exports);var o=i.exports,r=function(){function t(){}return t.prototype.success=function(t,e,n){this.flash("success",t,e,n)},t.prototype.info=function(t,e,n){this.flash("info",t,e,n)},t.prototype.warning=function(t,e,n){this.flash("warning",t,e,n)},t.prototype.error=function(t,e,n){this.flash("error",t,e,n)},t.prototype.flash=function(t,e,n,i){var o=this.createNotification(t,e,n,i);this.renderOptions({}),this.render({notification:o})},t.prototype.createNotification=function(t,e,n,i){if("object"==typeof t?(t=(i=t).type,e=i.message,n=i.title):"object"==typeof e?(e=(i=e).message,n=i.title):"object"==typeof n&&(n=(i=n).title),void 0===e)throw new Error("message option is required");return{type:t||"info",message:e,title:n,options:i}},t.prototype.render=function(t){var n=t.notification;n.type=n.type||"info";var i,r=e({text:n.title},n.options);switch(r=e(e({},r),{text:(null==r?void 0:r.text)||n.message}),n.type){case"success":i=o.success(r);break;case"alert":i=o.alert(r);break;case"info":i=o.info(r);break;case"error":i=o.error(r);break;default:i=o.notice(r)}i.refs.container&&(i.refs.container.dataset.turboCache="false",i.refs.container.classList.add("fl-no-cache"))},t.prototype.updateDefaultOptions=function(t,e){Object.entries(e).forEach((function(e){var n=e[0],i=e[1];t[n]=i}))},t.prototype.renderOptions=function(t){this.updateDefaultOptions(o.defaults,e({delay:t.delay||5e3},t))},t}(),s=new r;return t.addFactory("pnotify",s),s})); diff --git a/src/Pnotify/Prime/composer.json b/src/Pnotify/Prime/composer.json deleted file mode 100644 index 6fdb429e..00000000 --- a/src/Pnotify/Prime/composer.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "php-flasher/flasher-pnotify", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "library", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "autoload": { - "psr-4": { - "Flasher\\Pnotify\\Prime\\": "" - }, - "files": [ - "helpers.php" - ] - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/src/Pnotify/Prime/helpers.php b/src/Pnotify/Prime/helpers.php deleted file mode 100644 index c69a8fb1..00000000 --- a/src/Pnotify/Prime/helpers.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ - -use Flasher\Pnotify\Prime\PnotifyFactory; -use Flasher\Prime\Container\FlasherContainer; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; - -if (!function_exists('pnotify')) { - /** - * @param string $message - * @param string $type - * @param array $options - * - * @return Envelope|PnotifyFactory - */ - function pnotify($message = null, $type = NotificationInterface::SUCCESS, array $options = array()) - { - /** @var PnotifyFactory $factory */ - $factory = FlasherContainer::create('flasher.pnotify'); - - if (0 === func_num_args()) { - return $factory; - } - - return $factory->addFlash($type, $message, $options); - } -} diff --git a/src/Pnotify/Symfony/.github/FUNDING.yml b/src/Pnotify/Symfony/.github/FUNDING.yml deleted file mode 100644 index c3863630..00000000 --- a/src/Pnotify/Symfony/.github/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher -custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Pnotify/Symfony/.github/workflows/auto_closer.yaml b/src/Pnotify/Symfony/.github/workflows/auto_closer.yaml deleted file mode 100644 index f807ac59..00000000 --- a/src/Pnotify/Symfony/.github/workflows/auto_closer.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Auto Closer PR - -on: - pull_request_target: - types: [opened] - -jobs: - run: - runs-on: ubuntu-latest - steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. - - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. - - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. - - We'll check it, review it and give you feed back right way. - - Thank you. diff --git a/src/Pnotify/Symfony/FlasherPnotifySymfonyBundle.php b/src/Pnotify/Symfony/FlasherPnotifySymfonyBundle.php deleted file mode 100644 index 8b74d9d5..00000000 --- a/src/Pnotify/Symfony/FlasherPnotifySymfonyBundle.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Flasher\Pnotify\Symfony; - -use Flasher\Pnotify\Prime\PnotifyPlugin; -use Flasher\Symfony\Support\Bundle; - -class FlasherPnotifySymfonyBundle extends Bundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - /** - * {@inheritDoc} - */ - public function createPlugin() - { - return new PnotifyPlugin(); - } -} diff --git a/src/Pnotify/Symfony/LICENSE b/src/Pnotify/Symfony/LICENSE deleted file mode 100644 index 8e94bc16..00000000 --- a/src/Pnotify/Symfony/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 PHPFlasher - -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/src/Pnotify/Symfony/README.md b/src/Pnotify/Symfony/README.md deleted file mode 100644 index 70a05eb4..00000000 --- a/src/Pnotify/Symfony/README.md +++ /dev/null @@ -1,74 +0,0 @@ -

- - - PHPFlasher Logo - -

- -## About PHPFlasher - -PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects. -Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users. - -With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page. -This improves user engagement and enhances the overall user experience on your website or application. - -Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects. -So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice. - - -## Official Documentation - -Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io). - -## Contributors and sponsors - -Join our team of contributors and make a lasting impact on our project! - -We are always looking for passionate individuals who want to contribute their skills and ideas. -Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration. - -Shining stars of our community: - - - - - - - - - - - - - - - - - - - - -
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
Ash Allen
Ash Allen

🎨
Tony Murray
Tony Murray

💻
Stéphane P
Stéphane P

📖
Lucas Maciel
Lucas Maciel

🎨
Antoni Siek
Antoni Siek

💻
- - - - - - -## Contact - -PHPFlasher is being actively developed by yoeunes. -You can reach out with questions, bug reports, or feature requests on any of the following: - -- [Github Issues](https://github.com/php-flasher/php-flasher/issues) -- [Github](https://github.com/yoeunes) -- [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) - -## License - -PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). - -

Made with ❤️ by Younes KHOUBZA

diff --git a/src/Pnotify/Symfony/Resources/config/config.yaml b/src/Pnotify/Symfony/Resources/config/config.yaml deleted file mode 100644 index af18cd06..00000000 --- a/src/Pnotify/Symfony/Resources/config/config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -flasher_pnotify: - scripts: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-pnotify@1.3.2/dist/flasher-pnotify.min.js' - local: - - '/vendor/flasher/flasher-pnotify.min.js' - - styles: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-pnotify@1.3.2/dist/flasher-pnotify.min.css' - local: - - '/vendor/flasher/flasher-pnotify.min.css' diff --git a/src/Pnotify/Symfony/composer.json b/src/Pnotify/Symfony/composer.json deleted file mode 100644 index fd01955e..00000000 --- a/src/Pnotify/Symfony/composer.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "php-flasher/flasher-pnotify-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", - "type": "symfony-bundle", - "keywords": [ - "php-flasher", - "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" - ], - "authors": [ - { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", - "role": "Developer" - } - ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-pnotify": "^1.15.14", - "php-flasher/flasher-symfony": "^1.15.14" - }, - "minimum-stability": "stable", - "prefer-stable": true, - "autoload": { - "psr-4": { - "Flasher\\Pnotify\\Symfony\\": "" - } - }, - "config": { - "preferred-install": "dist", - "sort-packages": true - } -} diff --git a/src/Prime/.github/FUNDING.yml b/src/Prime/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Prime/.github/FUNDING.yml +++ b/src/Prime/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Prime/.github/workflows/auto_closer.yaml b/src/Prime/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Prime/.github/workflows/auto_closer.yaml +++ b/src/Prime/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Prime/.phpstorm.meta.php b/src/Prime/.phpstorm.meta.php index ac837db8..d60d3ef2 100644 --- a/src/Prime/.phpstorm.meta.php +++ b/src/Prime/.phpstorm.meta.php @@ -20,5 +20,4 @@ expectedArguments(\Flasher\Prime\Notification\NotificationBuilderInterface::addF expectedArguments(\Flasher\Prime\Notification\NotificationInterface::setType(), 0, argumentsSet('types')); expectedReturnValues(\Flasher\Prime\Notification\NotificationInterface::getType(), argumentsSet('types')); - -expectedArguments(\Flasher\Prime\Notification\NotificationBuilderInterface::handler(), 0, 'flasher', 'toastr', 'noty', 'notyf', 'pnotify', 'sweetalert'); +expectedArguments(\Flasher\Prime\Notification\NotificationBuilderInterface::handler(), 0, 'flasher', 'toastr', 'noty', 'notyf', 'sweetalert'); diff --git a/src/Prime/Asset/AssetManager.php b/src/Prime/Asset/AssetManager.php new file mode 100644 index 00000000..f699c845 --- /dev/null +++ b/src/Prime/Asset/AssetManager.php @@ -0,0 +1,88 @@ + + */ + private array $entries = []; + + public function __construct(private readonly string $publicDir, private readonly string $manifestPath) + { + } + + public function getPath(string $path): string + { + $entriesData = $this->getEntriesData(); + + return $entriesData[$path] ?? $entriesData[ltrim($path, \DIRECTORY_SEPARATOR)] ?? $path; + } + + public function getPaths(array $paths): array + { + return array_map(fn (string $path) => $this->getPath($path), $paths); + } + + public function createManifest(array $files): void + { + foreach ($files as $file) { + if (!file_exists($file)) { + continue; + } + + $relativePath = \DIRECTORY_SEPARATOR.ltrim(str_replace($this->publicDir, '', $file), \DIRECTORY_SEPARATOR); + $relativePath = str_replace(\DIRECTORY_SEPARATOR, '/', $relativePath); + + $hash = $this->computeHash($file); + $hashedFilename = $relativePath.'?id='.$hash; + + $this->entries[$relativePath] = $hashedFilename; + } + + if (false === file_put_contents($this->manifestPath, json_encode($this->entries, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES))) { + throw new \RuntimeException(sprintf('Failed to write manifest file to "%s"', $this->manifestPath)); + } + } + + /** + * Loads and returns the entries from the manifest file. + * + * @return array the manifest entries + */ + private function getEntriesData(): array + { + if ([] !== $this->entries) { + return $this->entries; + } + + if (!file_exists($this->manifestPath)) { + return []; + } + + $content = file_get_contents($this->manifestPath); + $entries = json_decode($content ?: '', true); + + if (!\is_array($entries)) { + throw new \InvalidArgumentException(sprintf('There was a problem JSON decoding the "%s" file.', $this->manifestPath)); + } + + return $this->entries = $entries; + } + + private function computeHash(string $path): string + { + $contents = file_get_contents($path); + + if (false === $contents) { + return ''; + } + + $normalizedContents = str_replace(["\r\n", "\r"], "\n", $contents); + + return md5($normalizedContents); + } +} diff --git a/src/Prime/Asset/AssetManagerInterface.php b/src/Prime/Asset/AssetManagerInterface.php new file mode 100644 index 00000000..0afd9cf4 --- /dev/null +++ b/src/Prime/Asset/AssetManagerInterface.php @@ -0,0 +1,31 @@ + - */ - -namespace Flasher\Prime\Aware; - -use Flasher\Prime\FlasherInterface; - -interface FlasherAwareInterface -{ - /** - * @return void - */ - public function setFlasher(FlasherInterface $flasher); -} diff --git a/src/Prime/Aware/FlasherAwareTrait.php b/src/Prime/Aware/FlasherAwareTrait.php deleted file mode 100644 index 090a2743..00000000 --- a/src/Prime/Aware/FlasherAwareTrait.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ - -namespace Flasher\Prime\Aware; - -use Flasher\Prime\FlasherInterface; - -trait FlasherAwareTrait -{ - /** - * @var FlasherInterface - */ - protected $flasher; - - public function setFlasher(FlasherInterface $flasher) - { - $this->flasher = $flasher; - } -} diff --git a/src/Prime/Config/Config.php b/src/Prime/Config/Config.php deleted file mode 100644 index 3a91cf62..00000000 --- a/src/Prime/Config/Config.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ - -namespace Flasher\Prime\Config; - -/** - * @phpstan-import-type ConfigType from ConfigInterface - */ -final class Config implements ConfigInterface -{ - /** - * @phpstan-var array{}|ConfigType - */ - private $config; - - /** - * @phpstan-param array{}|ConfigType $config - */ - public function __construct(array $config = array()) - { - $this->config = $config; - } - - /** - * {@inheritdoc} - */ - public function get($key, $default = null) - { - $data = $this->config; - - foreach (explode('.', $key) as $segment) { - if (!isset($data[$segment])) { // @phpstan-ignore-line - return $default; - } - - $data = $data[$segment]; - } - - return $data; - } -} diff --git a/src/Prime/Config/ConfigInterface.php b/src/Prime/Config/ConfigInterface.php deleted file mode 100644 index 16deed44..00000000 --- a/src/Prime/Config/ConfigInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace Flasher\Prime\Config; - -/** - * @phpstan-type ConfigType array{ - * default: string, - * root_script: string, - * options: array, - * themes: array, - * }>, - * auto_render: bool, - * auto_translate: bool, - * filter_criteria: array, - * flash_bag: array{ - * enabled: bool, - * mapping: array, - * }, - * presets: array, - * }>, - * } - */ -interface ConfigInterface -{ - /** - * Returns an attribute. - * - * @param string $key - * @param mixed $default the default value if not found - * - * @return mixed - */ - public function get($key, $default = null); -} diff --git a/src/Prime/Container/ContainerInterface.php b/src/Prime/Container/ContainerInterface.php deleted file mode 100644 index 4d27a1b2..00000000 --- a/src/Prime/Container/ContainerInterface.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ - -namespace Flasher\Prime\Container; - -interface ContainerInterface -{ - /** - * @param string $id - * - * @return mixed - */ - public function get($id); -} diff --git a/src/Prime/Container/FlasherContainer.php b/src/Prime/Container/FlasherContainer.php index e612c8d8..7a84d6f9 100644 --- a/src/Prime/Container/FlasherContainer.php +++ b/src/Prime/Container/FlasherContainer.php @@ -1,57 +1,110 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Container; +use Flasher\Prime\Factory\NotificationFactoryInterface; +use Flasher\Prime\FlasherInterface; +use Psr\Container\ContainerInterface; + /** + * Manages and provides access to Flasher service instances using a PSR-11 compatible container. + * Allows initializing the internal container using a direct instance, a Closure, or a callable + * that returns a ContainerInterface instance. + * * @internal */ final class FlasherContainer { - /** - * @var self|null - */ - private static $instance = null; + private static ?self $instance = null; - /** - * @var ContainerInterface - */ - private static $container; - - private function __construct(ContainerInterface $container) + private function __construct(private readonly ContainerInterface|\Closure $container) { - self::$container = $container; } /** - * @param string $id + * Initializes the container with a direct ContainerInterface or a Closure/callable that resolves to one. * - * @return mixed - * - * @throws \LogicException + * @param ContainerInterface|\Closure $container a ContainerInterface instance or a resolver that returns one */ - public static function create($id) + public static function from(ContainerInterface|\Closure $container): void { - if (null === self::$instance) { - throw new \LogicException('Container is not initialized yet. Container::init() must be called with a real container.'); - } - - return self::$container->get($id); + self::$instance ??= new self($container); } /** - * @return void + * Resets the container instance, effectively clearing it. */ - public static function init(ContainerInterface $container) + public static function reset(): void { - if (null !== self::$instance) { - return; + self::$instance = null; + } + + /** + * Creates and returns an instance of a service identified by $id. + * Throws an exception if the service is not found or does not implement the required interfaces. + * + * @param string $id the service identifier + * + * @return FlasherInterface|NotificationFactoryInterface the service instance + */ + public static function create(string $id): FlasherInterface|NotificationFactoryInterface + { + if (!self::has($id)) { + throw new \InvalidArgumentException(sprintf('The container does not have the requested service "%s".', $id)); } - self::$instance = new self($container); + $factory = self::getContainer()->get($id); + + if (!$factory instanceof FlasherInterface && !$factory instanceof NotificationFactoryInterface) { + throw new \InvalidArgumentException(sprintf('Expected an instance of "%s" or "%s", got "%s".', FlasherInterface::class, NotificationFactoryInterface::class, get_debug_type($factory))); + } + + return $factory; + } + + /** + * Checks if the container has a service identified by $id. + * + * @param string $id the service identifier + * + * @return bool true if the service exists, false otherwise + */ + public static function has(string $id): bool + { + return self::getContainer()->has($id); + } + + /** + * Retrieves the container, resolving it if necessary. + * + * @return ContainerInterface the container instance + */ + public static function getContainer(): ContainerInterface + { + $container = self::getInstance()->container; + + $resolved = $container instanceof \Closure || \is_callable($container) ? $container() : $container; + + if (!$resolved instanceof ContainerInterface) { + throw new \InvalidArgumentException(sprintf('Expected an instance of "%s", got "%s".', ContainerInterface::class, get_debug_type($resolved))); + } + + return $resolved; + } + + /** + * Retrieves the singleton instance of FlasherContainer, throws if not initialized. + * + * @return self the singleton instance + */ + private static function getInstance(): self + { + if (!self::$instance instanceof self) { + throw new \LogicException('FlasherContainer has not been initialized. Please initialize it by calling FlasherContainer::from(ContainerInterface $container).'); + } + + return self::$instance; } } diff --git a/src/Prime/EventDispatcher/Event/FilterEvent.php b/src/Prime/EventDispatcher/Event/FilterEvent.php index 2d4bfc6b..7b7b5fcf 100644 --- a/src/Prime/EventDispatcher/Event/FilterEvent.php +++ b/src/Prime/EventDispatcher/Event/FilterEvent.php @@ -1,52 +1,57 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; -use Flasher\Prime\Filter\Filter; use Flasher\Prime\Notification\Envelope; +use Flasher\Prime\Storage\Filter\Filter; +use Flasher\Prime\Storage\Filter\FilterInterface; final class FilterEvent { - /** - * @var Filter - */ - private $filter; - /** * @param Envelope[] $envelopes * @param array $criteria */ - public function __construct(array $envelopes, array $criteria) + public function __construct( + private FilterInterface $filter, + private array $envelopes, + private readonly array $criteria, + ) { + } + + public function getFilter(): FilterInterface { - $this->filter = new Filter($envelopes, $criteria); + return $this->filter; + } + + public function setFilter(Filter $filter): void + { + $this->filter = $filter; } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { - return $this->filter->getResult(); + return $this->envelopes; } /** - * @return Filter + * @param Envelope[] $envelopes */ - public function getFilter() + public function setEnvelopes(array $envelopes): void { - return $this->filter; + $this->envelopes = $envelopes; } /** - * @return void + * @return array */ - public function setFilter(Filter $filter) + public function getCriteria(): array { - $this->filter = $filter; + return $this->criteria; } } diff --git a/src/Prime/EventDispatcher/Event/NotificationEvents.php b/src/Prime/EventDispatcher/Event/NotificationEvents.php new file mode 100644 index 00000000..cae2501d --- /dev/null +++ b/src/Prime/EventDispatcher/Event/NotificationEvents.php @@ -0,0 +1,33 @@ +addNotification($notification); + } + } + + public function addNotification(NotificationInterface $notification): void + { + $this->notifications[] = $notification; + } + + /** + * @return NotificationInterface[] + */ + public function getNotifications(): array + { + return $this->notifications; + } +} diff --git a/src/Prime/EventDispatcher/Event/PersistEvent.php b/src/Prime/EventDispatcher/Event/PersistEvent.php index 4322d9c2..80f5418a 100644 --- a/src/Prime/EventDispatcher/Event/PersistEvent.php +++ b/src/Prime/EventDispatcher/Event/PersistEvent.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; @@ -11,33 +8,25 @@ use Flasher\Prime\Notification\Envelope; final class PersistEvent { - /** - * @var Envelope[] - */ - private $envelopes; - /** * @param Envelope[] $envelopes */ - public function __construct(array $envelopes) + public function __construct(private array $envelopes) { - $this->envelopes = $envelopes; } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { return $this->envelopes; } /** * @param Envelope[] $envelopes - * - * @return void */ - public function setEnvelopes(array $envelopes) + public function setEnvelopes(array $envelopes): void { $this->envelopes = $envelopes; } diff --git a/src/Prime/EventDispatcher/Event/PostPersistEvent.php b/src/Prime/EventDispatcher/Event/PostPersistEvent.php index c9286b61..13ebd2e3 100644 --- a/src/Prime/EventDispatcher/Event/PostPersistEvent.php +++ b/src/Prime/EventDispatcher/Event/PostPersistEvent.php @@ -1,33 +1,24 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; use Flasher\Prime\Notification\Envelope; -final class PostPersistEvent +final readonly class PostPersistEvent { - /** - * @var Envelope[] - */ - private $envelopes; - /** * @param Envelope[] $envelopes */ - public function __construct(array $envelopes) + public function __construct(private array $envelopes) { - $this->envelopes = $envelopes; } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { return $this->envelopes; } diff --git a/src/Prime/EventDispatcher/Event/PostRemoveEvent.php b/src/Prime/EventDispatcher/Event/PostRemoveEvent.php index 3f1f1b08..1c86038a 100644 --- a/src/Prime/EventDispatcher/Event/PostRemoveEvent.php +++ b/src/Prime/EventDispatcher/Event/PostRemoveEvent.php @@ -1,40 +1,27 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; use Flasher\Prime\Notification\Envelope; -final class PostRemoveEvent +final readonly class PostRemoveEvent { - /** - * @var Envelope[] - */ - private $envelopesToRemove; - - /** - * @var Envelope[] - */ - private $envelopesToKeep; - /** * @param Envelope[] $envelopesToRemove * @param Envelope[] $envelopesToKeep */ - public function __construct(array $envelopesToRemove = array(), array $envelopesToKeep = array()) - { - $this->envelopesToRemove = $envelopesToRemove; - $this->envelopesToKeep = $envelopesToKeep; + public function __construct( + private array $envelopesToRemove = [], + private array $envelopesToKeep = [], + ) { } /** * @return Envelope[] */ - public function getEnvelopesToRemove() + public function getEnvelopesToRemove(): array { return $this->envelopesToRemove; } @@ -42,7 +29,7 @@ final class PostRemoveEvent /** * @return Envelope[] */ - public function getEnvelopesToKeep() + public function getEnvelopesToKeep(): array { return $this->envelopesToKeep; } diff --git a/src/Prime/EventDispatcher/Event/PostUpdateEvent.php b/src/Prime/EventDispatcher/Event/PostUpdateEvent.php index 7186d579..79c5931a 100644 --- a/src/Prime/EventDispatcher/Event/PostUpdateEvent.php +++ b/src/Prime/EventDispatcher/Event/PostUpdateEvent.php @@ -1,33 +1,24 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; use Flasher\Prime\Notification\Envelope; -final class PostUpdateEvent +final readonly class PostUpdateEvent { - /** - * @var Envelope[] - */ - private $envelopes; - /** * @param Envelope[] $envelopes */ - public function __construct(array $envelopes) + public function __construct(private array $envelopes) { - $this->envelopes = $envelopes; } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { return $this->envelopes; } diff --git a/src/Prime/EventDispatcher/Event/PresentationEvent.php b/src/Prime/EventDispatcher/Event/PresentationEvent.php index 12c175f9..90aa0138 100644 --- a/src/Prime/EventDispatcher/Event/PresentationEvent.php +++ b/src/Prime/EventDispatcher/Event/PresentationEvent.php @@ -1,48 +1,35 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; use Flasher\Prime\Notification\Envelope; -final class PresentationEvent +final readonly class PresentationEvent { /** - * @var Envelope[] + * @param Envelope[] $envelopes + * @param array $context */ - private $envelopes; - - /** - * @var mixed[] - */ - private $context; - - /** - * @param Envelope[] $envelopes - * @param mixed[] $context - */ - public function __construct(array $envelopes, array $context) - { - $this->envelopes = $envelopes; - $this->context = $context; + public function __construct( + private array $envelopes, + private array $context, + ) { } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { return $this->envelopes; } /** - * @return mixed[] + * @return array */ - public function getContext() + public function getContext(): array { return $this->context; } diff --git a/src/Prime/EventDispatcher/Event/RemoveEvent.php b/src/Prime/EventDispatcher/Event/RemoveEvent.php index 1235c87e..d02d5973 100644 --- a/src/Prime/EventDispatcher/Event/RemoveEvent.php +++ b/src/Prime/EventDispatcher/Event/RemoveEvent.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; @@ -14,35 +11,27 @@ final class RemoveEvent /** * @var Envelope[] */ - private $envelopesToRemove = array(); - - /** - * @var Envelope[] - */ - private $envelopesToKeep = array(); + private array $envelopesToKeep = []; /** * @param Envelope[] $envelopesToRemove */ - public function __construct(array $envelopesToRemove) + public function __construct(private array $envelopesToRemove) { - $this->envelopesToRemove = $envelopesToRemove; } /** * @return Envelope[] */ - public function getEnvelopesToRemove() + public function getEnvelopesToRemove(): array { return $this->envelopesToRemove; } /** * @param Envelope[] $envelopesToRemove - * - * @return void */ - public function setEnvelopesToRemove($envelopesToRemove) + public function setEnvelopesToRemove(array $envelopesToRemove): void { $this->envelopesToRemove = $envelopesToRemove; } @@ -50,17 +39,15 @@ final class RemoveEvent /** * @return Envelope[] */ - public function getEnvelopesToKeep() + public function getEnvelopesToKeep(): array { return $this->envelopesToKeep; } /** * @param Envelope[] $envelopesToKeep - * - * @return void */ - public function setEnvelopesToKeep($envelopesToKeep) + public function setEnvelopesToKeep(array $envelopesToKeep): void { $this->envelopesToKeep = $envelopesToKeep; } diff --git a/src/Prime/EventDispatcher/Event/ResponseEvent.php b/src/Prime/EventDispatcher/Event/ResponseEvent.php index 802d4a4f..6e2887bb 100644 --- a/src/Prime/EventDispatcher/Event/ResponseEvent.php +++ b/src/Prime/EventDispatcher/Event/ResponseEvent.php @@ -1,56 +1,28 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; final class ResponseEvent { - /** - * @var mixed - */ - private $response; - - /** - * @var string - */ - private $presenter; - - /** - * @param mixed $response - * @param string $presenter - */ - public function __construct($response, $presenter) - { - $this->response = $response; - $this->presenter = $presenter; + public function __construct( + private mixed $response, + private readonly string $presenter, + ) { } - /** - * @return mixed - */ - public function getResponse() + public function getResponse(): mixed { return $this->response; } - /** - * @param mixed $response - * - * @return void - */ - public function setResponse($response) + public function setResponse(mixed $response): void { $this->response = $response; } - /** - * @return string - */ - public function getPresenter() + public function getPresenter(): string { return $this->presenter; } diff --git a/src/Prime/EventDispatcher/Event/StoppableEventInterface.php b/src/Prime/EventDispatcher/Event/StoppableEventInterface.php index 529b11e8..fb93d7a2 100644 --- a/src/Prime/EventDispatcher/Event/StoppableEventInterface.php +++ b/src/Prime/EventDispatcher/Event/StoppableEventInterface.php @@ -1,16 +1,10 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; interface StoppableEventInterface { - /** - * @return bool - */ - public function isPropagationStopped(); + public function isPropagationStopped(): bool; } diff --git a/src/Prime/EventDispatcher/Event/UpdateEvent.php b/src/Prime/EventDispatcher/Event/UpdateEvent.php index b9fa0a3b..27b78765 100644 --- a/src/Prime/EventDispatcher/Event/UpdateEvent.php +++ b/src/Prime/EventDispatcher/Event/UpdateEvent.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\Event; @@ -11,33 +8,25 @@ use Flasher\Prime\Notification\Envelope; final class UpdateEvent { - /** - * @var Envelope[] - */ - private $envelopes; - /** * @param Envelope[] $envelopes */ - public function __construct(array $envelopes) + public function __construct(private array $envelopes) { - $this->envelopes = $envelopes; } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { return $this->envelopes; } /** * @param Envelope[] $envelopes - * - * @return void */ - public function setEnvelopes(array $envelopes) + public function setEnvelopes(array $envelopes): void { $this->envelopes = $envelopes; } diff --git a/src/Prime/EventDispatcher/EventDispatcher.php b/src/Prime/EventDispatcher/EventDispatcher.php index cb22096b..11b9da96 100644 --- a/src/Prime/EventDispatcher/EventDispatcher.php +++ b/src/Prime/EventDispatcher/EventDispatcher.php @@ -1,89 +1,60 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher; use Flasher\Prime\EventDispatcher\Event\StoppableEventInterface; use Flasher\Prime\EventDispatcher\EventListener\AddToStorageListener; -use Flasher\Prime\EventDispatcher\EventListener\EventSubscriberInterface; -use Flasher\Prime\EventDispatcher\EventListener\RemoveListener; -use Flasher\Prime\EventDispatcher\EventListener\StampsListener; +use Flasher\Prime\EventDispatcher\EventListener\AttachDefaultStampsListener; +use Flasher\Prime\EventDispatcher\EventListener\EnvelopeRemovalListener; +use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface; final class EventDispatcher implements EventDispatcherInterface { /** - * @var array + * @var array */ - private $listeners = array(); + private array $listeners = []; public function __construct() { - $this->addSubscriber(new RemoveListener()); - $this->addSubscriber(new StampsListener()); - $this->addSubscriber(new AddToStorageListener()); + $this->addListener(new EnvelopeRemovalListener()); + $this->addListener(new AttachDefaultStampsListener()); + $this->addListener(new AddToStorageListener()); } - /** - * {@inheritdoc} - */ - public function dispatch($event) + public function dispatch(object $event): object { - $listeners = $this->getListeners(\get_class($event)); + $listeners = $this->getListeners($event::class); - $this->callListeners($listeners, $event); // @phpstan-ignore-line - - return $event; - } - - /** - * {@inheritdoc} - */ - public function addListener($eventName, $listener) - { - $this->listeners[$eventName][] = $listener; // @phpstan-ignore-line - } - - /** - * {@inheritdoc} - */ - public function addSubscriber(EventSubscriberInterface $subscriber) - { - foreach ((array) $subscriber->getSubscribedEvents() as $eventName) { - $this->addListener($eventName, array($subscriber, '__invoke')); // @phpstan-ignore-line - } - } - - /** - * @param string $eventName - * - * @return array - */ - public function getListeners($eventName) - { - if (\array_key_exists($eventName, $this->listeners)) { - return $this->listeners[$eventName]; // @phpstan-ignore-line - } - - return array(); - } - - /** - * @param callable[] $listeners - * @param object $event - * - * @return void - */ - private function callListeners(array $listeners, $event) - { foreach ($listeners as $listener) { if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) { break; } - \call_user_func($listener, $event); + + if (!\is_callable($listener)) { + throw new \InvalidArgumentException(sprintf('Listener "%s" is not callable. Listeners must implement __invoke method.', $listener::class)); + } + + $listener($event); + } + + return $event; + } + + public function addListener(EventListenerInterface $listener): void + { + foreach ((array) $listener->getSubscribedEvents() as $eventName) { + $this->listeners[$eventName][] = $listener; } } + + /** + * @return EventListenerInterface[] + */ + public function getListeners(string $eventName): array + { + return $this->listeners[$eventName] ?? []; + } } diff --git a/src/Prime/EventDispatcher/EventDispatcherInterface.php b/src/Prime/EventDispatcher/EventDispatcherInterface.php index 3d9815d2..bcba6cf3 100644 --- a/src/Prime/EventDispatcher/EventDispatcherInterface.php +++ b/src/Prime/EventDispatcher/EventDispatcherInterface.php @@ -1,33 +1,26 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher; -use Flasher\Prime\EventDispatcher\EventListener\EventSubscriberInterface; +use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface; interface EventDispatcherInterface { /** - * @param object $event + * @phpstan-template T of object * - * @return object + * @phpstan-param T $event + * + * @phpstan-return T */ - public function dispatch($event); + public function dispatch(object $event): object; + + public function addListener(EventListenerInterface $listener): void; /** - * @param string $eventName - * @param callable $listener - * - * @return void + * @return EventListenerInterface[] */ - public function addListener($eventName, $listener); - - /** - * @return void - */ - public function addSubscriber(EventSubscriberInterface $subscriber); + public function getListeners(string $eventName): array; } diff --git a/src/Prime/EventDispatcher/EventListener/AddToStorageListener.php b/src/Prime/EventDispatcher/EventListener/AddToStorageListener.php index c5ad027f..14f66f99 100644 --- a/src/Prime/EventDispatcher/EventListener/AddToStorageListener.php +++ b/src/Prime/EventDispatcher/EventListener/AddToStorageListener.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\EventListener; @@ -12,47 +9,36 @@ use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Stamp\UnlessStamp; use Flasher\Prime\Stamp\WhenStamp; -final class AddToStorageListener implements EventSubscriberInterface +final readonly class AddToStorageListener implements EventListenerInterface { - /** - * @return void - */ - public function __invoke(PersistEvent $event) + public function __invoke(PersistEvent $event): void { - $envelopesToKeep = array(); + $envelopes = array_filter($event->getEnvelopes(), $this->isEligibleForStorage(...)); - foreach ($event->getEnvelopes() as $envelope) { - if ($this->shouldKeep($envelope)) { - $envelopesToKeep[] = $envelope; - } - } - - $event->setEnvelopes($envelopesToKeep); + $event->setEnvelopes($envelopes); } - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() + public function getSubscribedEvents(): string { - return 'Flasher\Prime\EventDispatcher\Event\PersistEvent'; + return PersistEvent::class; } - /** - * @return bool - */ - private function shouldKeep(Envelope $envelope) + private function isEligibleForStorage(Envelope $envelope): bool { - $stamp = $envelope->get('Flasher\Prime\Stamp\WhenStamp'); - if ($stamp instanceof WhenStamp && false === $stamp->getCondition()) { - return false; - } + return $this->whenCondition($envelope) && $this->unlessCondition($envelope); + } - $stamp = $envelope->get('Flasher\Prime\Stamp\UnlessStamp'); - if ($stamp instanceof UnlessStamp && true === $stamp->getCondition()) { - return false; - } + private function whenCondition(Envelope $envelope): bool + { + $whenStamp = $envelope->get(WhenStamp::class); - return true; + return !($whenStamp instanceof WhenStamp && !$whenStamp->getCondition()); + } + + private function unlessCondition(Envelope $envelope): bool + { + $unlessStamp = $envelope->get(UnlessStamp::class); + + return !($unlessStamp instanceof UnlessStamp && $unlessStamp->getCondition()); } } diff --git a/src/Prime/EventDispatcher/EventListener/ApplyPresetListener.php b/src/Prime/EventDispatcher/EventListener/ApplyPresetListener.php new file mode 100644 index 00000000..e8655efd --- /dev/null +++ b/src/Prime/EventDispatcher/EventListener/ApplyPresetListener.php @@ -0,0 +1,106 @@ +, + * } + */ +final readonly class ApplyPresetListener implements EventListenerInterface +{ + /** + * @phpstan-param array $presets + */ + public function __construct(private array $presets) + { + } + + /** + * @throws PresetNotFoundException + */ + public function __invoke(PersistEvent $event): void + { + foreach ($event->getEnvelopes() as $envelope) { + $this->applyPreset($envelope); + } + } + + public function getSubscribedEvents(): string + { + return PersistEvent::class; + } + + /** + * Applies preset settings to an envelope if applicable. + * + * @throws PresetNotFoundException if the preset is not found + */ + private function applyPreset(Envelope $envelope): void + { + $presetStamp = $envelope->get(PresetStamp::class); + if (!$presetStamp instanceof PresetStamp) { + return; + } + + $alias = $presetStamp->getPreset(); + if (!isset($this->presets[$alias])) { + throw PresetNotFoundException::create($alias, array_keys($this->presets)); + } + + $preset = $this->getPreset($alias); + $this->updateEnvelope($envelope, $preset); + } + + /** + * Retrieves preset data or default values if not set. + * + * @param string $alias the preset key + * + * @phpstan-return PresetType The preset data. + */ + private function getPreset(string $alias): array + { + return [ + 'type' => '', + 'title' => '', + 'message' => '', + 'options' => [], + ...$this->presets[$alias], + ]; + } + + /** + * Updates the envelope with the provided preset data. + * + * @param Envelope $envelope the envelope to be updated + * + * @phpstan-param PresetType $preset The preset data to apply. + */ + private function updateEnvelope(Envelope $envelope, array $preset): void + { + if ('' === $envelope->getType()) { + $envelope->setType($preset['type']); + } + + if ('' === $envelope->getTitle()) { + $envelope->setTitle($preset['title']); + } + + if ('' === $envelope->getMessage()) { + $envelope->setMessage($preset['message']); + } + + $envelope->setOptions([...$preset['options'], ...$envelope->getOptions()]); + } +} diff --git a/src/Prime/EventDispatcher/EventListener/AttachDefaultStampsListener.php b/src/Prime/EventDispatcher/EventListener/AttachDefaultStampsListener.php new file mode 100644 index 00000000..9f1ecef0 --- /dev/null +++ b/src/Prime/EventDispatcher/EventListener/AttachDefaultStampsListener.php @@ -0,0 +1,44 @@ +getEnvelopes() as $envelope) { + $this->attachStamps($envelope); + } + } + + public function getSubscribedEvents(): string|array + { + return [ + PersistEvent::class, + UpdateEvent::class, + ]; + } + + private function attachStamps(Envelope $envelope): void + { + $envelope->withStamp(new CreatedAtStamp(), false); + $envelope->withStamp(new IdStamp(), false); + $envelope->withStamp(new DelayStamp(0), false); + $envelope->withStamp(new HopsStamp(1), false); + $envelope->withStamp(new PriorityStamp(0), false); + } +} diff --git a/src/Prime/EventDispatcher/EventListener/EnvelopeRemovalListener.php b/src/Prime/EventDispatcher/EventListener/EnvelopeRemovalListener.php new file mode 100644 index 00000000..030b8de7 --- /dev/null +++ b/src/Prime/EventDispatcher/EventListener/EnvelopeRemovalListener.php @@ -0,0 +1,50 @@ +categorizeEnvelopes($event->getEnvelopesToRemove()); + + $event->setEnvelopesToKeep($envelopesToKeep); + $event->setEnvelopesToRemove($envelopesToRemove); + } + + public function getSubscribedEvents(): string + { + return RemoveEvent::class; + } + + /** + * @param Envelope[] $envelopes + * + * @return array + */ + private function categorizeEnvelopes(array $envelopes): array + { + $envelopesToKeep = []; + $envelopesToRemove = []; + + foreach ($envelopes as $envelope) { + $hopsStamp = $envelope->get(HopsStamp::class); + + if ($hopsStamp instanceof HopsStamp && 1 < $hopsStamp->getAmount()) { + $envelope->withStamp(new HopsStamp($hopsStamp->getAmount() - 1)); + $envelopesToKeep[] = $envelope; + continue; + } + + $envelopesToRemove[] = $envelope; + } + + return [$envelopesToKeep, $envelopesToRemove]; + } +} diff --git a/src/Prime/EventDispatcher/EventListener/EventListenerInterface.php b/src/Prime/EventDispatcher/EventListener/EventListenerInterface.php new file mode 100644 index 00000000..bc2aec75 --- /dev/null +++ b/src/Prime/EventDispatcher/EventListener/EventListenerInterface.php @@ -0,0 +1,23 @@ + - */ - -namespace Flasher\Prime\EventDispatcher\EventListener; - -interface EventSubscriberInterface -{ - /** - * @return string|string[] - */ - public static function getSubscribedEvents(); -} diff --git a/src/Prime/EventDispatcher/EventListener/NotificationLoggerListener.php b/src/Prime/EventDispatcher/EventListener/NotificationLoggerListener.php new file mode 100644 index 00000000..2690abcf --- /dev/null +++ b/src/Prime/EventDispatcher/EventListener/NotificationLoggerListener.php @@ -0,0 +1,38 @@ +events = new NotificationEvents(); + } + + public function reset(): void + { + $this->events = new NotificationEvents(); + } + + public function __invoke(PresentationEvent $event): void + { + $this->events->add(...$event->getEnvelopes()); + } + + public function getEvents(): NotificationEvents + { + return $this->events; + } + + public function getSubscribedEvents(): string|array + { + return PresentationEvent::class; + } +} diff --git a/src/Prime/EventDispatcher/EventListener/PresetListener.php b/src/Prime/EventDispatcher/EventListener/PresetListener.php deleted file mode 100644 index 2e76ea3d..00000000 --- a/src/Prime/EventDispatcher/EventListener/PresetListener.php +++ /dev/null @@ -1,97 +0,0 @@ - - */ - -namespace Flasher\Prime\EventDispatcher\EventListener; - -use Flasher\Prime\EventDispatcher\Event\PersistEvent; -use Flasher\Prime\Exception\PresetNotFoundException; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\PresetStamp; - -/** - * @phpstan-type PresetType array, - * }> - */ -final class PresetListener implements EventSubscriberInterface -{ - /** - * @phpstan-var PresetType - */ - private $presets = array(); - - /** - * @phpstan-param PresetType $presets - */ - public function __construct(array $presets) - { - $this->presets = $presets; - } - - /** - * @return void - * - * @throws PresetNotFoundException - */ - public function __invoke(PersistEvent $event) - { - foreach ($event->getEnvelopes() as $envelope) { - $this->attachPresets($envelope); - } - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() - { - return 'Flasher\Prime\EventDispatcher\Event\PersistEvent'; - } - - /** - * @return void - * - * @throws PresetNotFoundException - */ - private function attachPresets(Envelope $envelope) - { - $presetStamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); - if (!$presetStamp instanceof PresetStamp) { - return; - } - - if (!isset($this->presets[$presetStamp->getPreset()])) { - throw new PresetNotFoundException($presetStamp->getPreset(), array_keys($this->presets)); - } - - $preset = $this->presets[$presetStamp->getPreset()]; - $preset = array_merge(array( - 'type' => 'info', - 'title' => null, - 'message' => null, - 'options' => array(), - ), $preset); - - if (null === $envelope->getType()) { - $envelope->setType($preset['type']); - } - - if (null === $envelope->getTitle()) { - $envelope->setTitle($preset['title']); - } - - if (null === $envelope->getMessage()) { - $envelope->setMessage($preset['message']); - } - - $options = array_merge($preset['options'], $envelope->getOptions()); - $envelope->setOptions($options); - } -} diff --git a/src/Prime/EventDispatcher/EventListener/RemoveListener.php b/src/Prime/EventDispatcher/EventListener/RemoveListener.php deleted file mode 100644 index 6851b76e..00000000 --- a/src/Prime/EventDispatcher/EventListener/RemoveListener.php +++ /dev/null @@ -1,46 +0,0 @@ - - */ - -namespace Flasher\Prime\EventDispatcher\EventListener; - -use Flasher\Prime\EventDispatcher\Event\RemoveEvent; -use Flasher\Prime\Stamp\HopsStamp; - -final class RemoveListener implements EventSubscriberInterface -{ - /** - * @return void - */ - public function __invoke(RemoveEvent $event) - { - $envelopesToKeep = $event->getEnvelopesToKeep(); - $envelopesToRemove = array(); - - foreach ($event->getEnvelopesToRemove() as $envelope) { - $hopsStamp = $envelope->get('Flasher\Prime\Stamp\HopsStamp'); - if (!$hopsStamp instanceof HopsStamp || 1 === $hopsStamp->getAmount()) { - $envelopesToRemove[] = $envelope; - - continue; - } - - $envelope->with(new HopsStamp($hopsStamp->getAmount() - 1)); - $envelopesToKeep[] = $envelope; - } - - $event->setEnvelopesToKeep($envelopesToKeep); - $event->setEnvelopesToRemove($envelopesToRemove); - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() - { - return 'Flasher\Prime\EventDispatcher\Event\RemoveEvent'; - } -} diff --git a/src/Prime/EventDispatcher/EventListener/StampsListener.php b/src/Prime/EventDispatcher/EventListener/StampsListener.php deleted file mode 100644 index 288166c6..00000000 --- a/src/Prime/EventDispatcher/EventListener/StampsListener.php +++ /dev/null @@ -1,69 +0,0 @@ - - */ - -namespace Flasher\Prime\EventDispatcher\EventListener; - -use Flasher\Prime\EventDispatcher\Event\PersistEvent; -use Flasher\Prime\EventDispatcher\Event\UpdateEvent; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\CreatedAtStamp; -use Flasher\Prime\Stamp\DelayStamp; -use Flasher\Prime\Stamp\HopsStamp; -use Flasher\Prime\Stamp\PriorityStamp; -use Flasher\Prime\Stamp\UuidStamp; - -final class StampsListener implements EventSubscriberInterface -{ - /** - * @param PersistEvent|UpdateEvent $event - * - * @return void - */ - public function __invoke($event) - { - foreach ($event->getEnvelopes() as $envelope) { - $this->attachStamps($envelope); - } - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() - { - return array( - 'Flasher\Prime\EventDispatcher\Event\PersistEvent', - 'Flasher\Prime\EventDispatcher\Event\UpdateEvent', - ); - } - - /** - * @return void - */ - private function attachStamps(Envelope $envelope) - { - if (null === $envelope->get('Flasher\Prime\Stamp\CreatedAtStamp')) { - $envelope->withStamp(new CreatedAtStamp()); - } - - if (null === $envelope->get('Flasher\Prime\Stamp\UuidStamp')) { - $envelope->withStamp(new UuidStamp(spl_object_hash($envelope))); - } - - if (null === $envelope->get('Flasher\Prime\Stamp\DelayStamp')) { - $envelope->withStamp(new DelayStamp(0)); - } - - if (null === $envelope->get('Flasher\Prime\Stamp\HopsStamp')) { - $envelope->withStamp(new HopsStamp(1)); - } - - if (null === $envelope->get('Flasher\Prime\Stamp\PriorityStamp')) { - $envelope->withStamp(new PriorityStamp(0)); - } - } -} diff --git a/src/Prime/EventDispatcher/EventListener/TranslationListener.php b/src/Prime/EventDispatcher/EventListener/TranslationListener.php index b704ecd3..c1e109dd 100644 --- a/src/Prime/EventDispatcher/EventListener/TranslationListener.php +++ b/src/Prime/EventDispatcher/EventListener/TranslationListener.php @@ -1,89 +1,94 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\EventDispatcher\EventListener; use Flasher\Prime\EventDispatcher\Event\PresentationEvent; +use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Stamp\PresetStamp; use Flasher\Prime\Stamp\TranslationStamp; use Flasher\Prime\Translation\EchoTranslator; use Flasher\Prime\Translation\Language; use Flasher\Prime\Translation\TranslatorInterface; -final class TranslationListener implements EventSubscriberInterface +/** + * Listener responsible for applying translations to envelopes during presentation events based on TranslationStamps and locale settings. + */ +final readonly class TranslationListener implements EventListenerInterface { - /** - * @var TranslatorInterface - */ - private $translator; + private TranslatorInterface $translator; - /** - * @var bool - */ - private $autoTranslate; - - /** - * @param bool $autoTranslate - */ - public function __construct(TranslatorInterface $translator = null, $autoTranslate = true) + public function __construct(?TranslatorInterface $translator = null) { $this->translator = $translator ?: new EchoTranslator(); - $this->autoTranslate = $autoTranslate; } - /** - * @return void - */ - public function __invoke(PresentationEvent $event) + public function __invoke(PresentationEvent $event): void { foreach ($event->getEnvelopes() as $envelope) { - $stamp = $envelope->get('Flasher\Prime\Stamp\TranslationStamp'); - if (!$stamp instanceof TranslationStamp && !$this->autoTranslate) { - continue; - } + $this->translateEnvelope($envelope); + } + } - $locale = $stamp instanceof TranslationStamp && $stamp->getLocale() - ? $stamp->getLocale() - : $this->translator->getLocale(); + public function getSubscribedEvents(): string + { + return PresentationEvent::class; + } - $parameters = $stamp instanceof TranslationStamp && $stamp->getParameters() - ? $stamp->getParameters() - : array(); + private function translateEnvelope(Envelope $envelope): void + { + $stamp = $envelope->get(TranslationStamp::class); + if (!$stamp instanceof TranslationStamp) { + return; + } - $preset = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); - if ($preset instanceof PresetStamp) { - foreach ($preset->getParameters() as $key => $value) { - $parameters[$key] = $this->translator->translate($value, $parameters, $locale); // @phpstan-ignore-line - } - } + $locale = $stamp->getLocale() ?: $this->translator->getLocale(); + $parameters = $stamp->getParameters() ?: $this->getParameters($envelope, $locale); - $title = $envelope->getTitle() ?: $envelope->getType(); - if (null !== $title) { - $title = $this->translator->translate($title, $parameters, $locale); - $envelope->setTitle($title); - } + $this->applyTranslations($envelope, $locale, $parameters); - $message = $envelope->getMessage(); - if (null !== $message) { - $message = $this->translator->translate($message, $parameters, $locale); - $envelope->setMessage($message); - } - - if (Language::isRTL($locale)) { - $envelope->setOption('rtl', true); - } + if (Language::isRTL($locale)) { + $envelope->setOption('rtl', true); } } /** - * {@inheritdoc} + * @return array */ - public static function getSubscribedEvents() + private function getParameters(Envelope $envelope, string $locale): array { - return 'Flasher\Prime\EventDispatcher\Event\PresentationEvent'; + $preset = $envelope->get(PresetStamp::class); + if (!$preset instanceof PresetStamp) { + return []; + } + + $parameters = []; + + foreach ($preset->getParameters() as $key => $value) { + if (!\is_string($value)) { + throw new \InvalidArgumentException(sprintf('Value must be "string", got "%s".', get_debug_type($value))); + } + + $parameters[$key] = $this->translator->translate($value, $parameters, $locale); + } + + return $parameters; + } + + /** + * @param array $parameters + */ + private function applyTranslations(Envelope $envelope, string $locale, array $parameters): void + { + $title = $envelope->getTitle() ?: $envelope->getType(); + if ('' !== $title) { + $envelope->setTitle($this->translator->translate($title, $parameters, $locale)); + } + + $message = $envelope->getMessage(); + if ('' !== $message) { + $envelope->setMessage($this->translator->translate($message, $parameters, $locale)); + } } } diff --git a/src/Prime/Exception/CriteriaNotRegisteredException.php b/src/Prime/Exception/CriteriaNotRegisteredException.php new file mode 100644 index 00000000..57ada20a --- /dev/null +++ b/src/Prime/Exception/CriteriaNotRegisteredException.php @@ -0,0 +1,22 @@ + - */ +declare(strict_types=1); namespace Flasher\Prime\Exception; final class PresetNotFoundException extends \Exception { /** - * @param string $preset - * @param string[] $availablePresets + * @param string $preset the name of the preset that was not found + * @param string[] $availablePresets the list of available presets for reference */ - public function __construct($preset, array $availablePresets = array()) + public static function create(string $preset, array $availablePresets = []): self { $message = sprintf('Preset "%s" not found, did you forget to register it?', $preset); - if (array() !== $availablePresets) { - $message .= sprintf(' Available presets: %s', implode(', ', $availablePresets)); + + if ([] !== $availablePresets) { + $message .= sprintf(' Available presets: "%s"', implode('", "', $availablePresets)); } - parent::__construct($message); + return new self($message); } } diff --git a/src/Prime/Factory/NotificationFactory.php b/src/Prime/Factory/NotificationFactory.php index 370ba176..a07cde33 100644 --- a/src/Prime/Factory/NotificationFactory.php +++ b/src/Prime/Factory/NotificationFactory.php @@ -1,65 +1,35 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Factory; -use Flasher\Prime\Notification\Notification; use Flasher\Prime\Notification\NotificationBuilder; -use Flasher\Prime\Storage\StorageManager; +use Flasher\Prime\Notification\NotificationBuilderInterface; use Flasher\Prime\Storage\StorageManagerInterface; +use Flasher\Prime\Support\Traits\ForwardsCalls; +/** + * @mixin \Flasher\Prime\Notification\NotificationBuilderInterface + */ class NotificationFactory implements NotificationFactoryInterface { - /** - * @var StorageManagerInterface - */ - protected $storageManager; + use ForwardsCalls; - /** - * @var string|null - */ - protected $handler; - - /** - * @param string|null $handler - */ - public function __construct(StorageManagerInterface $storageManager = null, $handler = null) + public function __construct(protected StorageManagerInterface $storageManager, protected ?string $plugin = null) { - $this->storageManager = $storageManager ?: new StorageManager(); - $this->handler = $handler; + } + + public function createNotificationBuilder(): NotificationBuilderInterface + { + return new NotificationBuilder($this->plugin ?: 'flasher', $this->storageManager); } /** - * @param string $method * @param mixed[] $parameters - * - * @return mixed */ - public function __call($method, array $parameters) + public function __call(string $method, array $parameters): mixed { - /** @var callable $callback */ - $callback = array($this->createNotificationBuilder(), $method); - - return \call_user_func_array($callback, $parameters); - } - - /** - * {@inheritdoc} - */ - public function createNotificationBuilder() - { - return new NotificationBuilder($this->getStorageManager(), new Notification(), $this->handler); - } - - /** - * @return StorageManagerInterface - */ - public function getStorageManager() - { - return $this->storageManager; + return $this->forwardCallTo($this->createNotificationBuilder(), $method, $parameters); } } diff --git a/src/Prime/Factory/NotificationFactoryInterface.php b/src/Prime/Factory/NotificationFactoryInterface.php index 546b8003..cfd31c66 100644 --- a/src/Prime/Factory/NotificationFactoryInterface.php +++ b/src/Prime/Factory/NotificationFactoryInterface.php @@ -1,21 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Factory; use Flasher\Prime\Notification\NotificationBuilderInterface; /** - * @mixin NotificationBuilderInterface + * @mixin \Flasher\Prime\Notification\NotificationBuilderInterface */ interface NotificationFactoryInterface { - /** - * @return NotificationBuilderInterface - */ - public function createNotificationBuilder(); + public function createNotificationBuilder(): NotificationBuilderInterface; } diff --git a/src/Prime/Factory/NotificationFactoryLocator.php b/src/Prime/Factory/NotificationFactoryLocator.php new file mode 100644 index 00000000..7f82b8c1 --- /dev/null +++ b/src/Prime/Factory/NotificationFactoryLocator.php @@ -0,0 +1,39 @@ + + */ + private array $factories = []; + + public function get(string $id): NotificationFactoryInterface + { + if (!$this->has($id)) { + throw FactoryNotFoundException::create($id, array_keys($this->factories)); + } + + $factory = $this->factories[$id]; + + return \is_callable($factory) ? $factory() : $factory; + } + + public function has(string $id): bool + { + return \array_key_exists($id, $this->factories); + } + + /** + * Register a custom notification factory. + */ + public function addFactory(string $alias, callable|NotificationFactoryInterface $factory): void + { + $this->factories[$alias] = $factory; + } +} diff --git a/src/Prime/Factory/NotificationFactoryLocatorInterface.php b/src/Prime/Factory/NotificationFactoryLocatorInterface.php new file mode 100644 index 00000000..b7518f35 --- /dev/null +++ b/src/Prime/Factory/NotificationFactoryLocatorInterface.php @@ -0,0 +1,12 @@ + - */ - -namespace Flasher\Prime\Filter; - -use Flasher\Prime\Filter\Specification\CallbackSpecification; -use Flasher\Prime\Filter\Specification\DelaySpecification; -use Flasher\Prime\Filter\Specification\HopsSpecification; -use Flasher\Prime\Filter\Specification\PrioritySpecification; -use Flasher\Prime\Filter\Specification\StampsSpecification; -use Flasher\Prime\Stamp\StampInterface; - -final class CriteriaBuilder -{ - /** - * @var array> - */ - public $aliases = array( - 'context' => 'Flasher\Prime\Stamp\ContextStamp', - 'created_at' => 'Flasher\Prime\Stamp\CreatedAtStamp', - 'delay' => 'Flasher\Prime\Stamp\DelayStamp', - 'handler' => 'Flasher\Prime\Stamp\HandlerStamp', - 'hops' => 'Flasher\Prime\Stamp\HopsStamp', - 'preset' => 'Flasher\Prime\Stamp\PresetStamp', - 'priority' => 'Flasher\Prime\Stamp\PriorityStamp', - 'translation' => 'Flasher\Prime\Stamp\TranslationStamp', - 'unless' => 'Flasher\Prime\Stamp\UnlessStamp', - 'uuid' => 'Flasher\Prime\Stamp\UuidStamp', - 'view' => 'Flasher\Prime\Stamp\ViewStamp', - 'when' => 'Flasher\Prime\Stamp\WhenStamp', - ); - - /** - * @var Filter - */ - private $filter; - - /** - * @var array - */ - private $criteria; - - /** - * @param array $criteria - */ - public function __construct(Filter $filter, array $criteria) - { - $this->filter = $filter; - $this->criteria = $criteria; - } - - /** - * @return void - */ - public function build() - { - $this->buildPriority(); - $this->buildHops(); - $this->buildDelay(); - $this->buildLife(); - $this->buildOrder(); - $this->buildLimit(); - $this->buildStamps(); - $this->buildCallback(); - } - - /** - * @return void - */ - public function buildPriority() - { - if (!isset($this->criteria['priority'])) { - return; - } - - $criteria = $this->extractMinMax($this->criteria['priority']); - - $this->filter->addSpecification(new PrioritySpecification($criteria['min'], $criteria['max'])); - } - - /** - * @return void - */ - public function buildHops() - { - if (!isset($this->criteria['hops'])) { - return; - } - - $criteria = $this->extractMinMax($this->criteria['hops']); - - $this->filter->addSpecification(new HopsSpecification($criteria['min'], $criteria['max'])); - } - - /** - * @return void - */ - public function buildDelay() - { - if (!isset($this->criteria['delay'])) { - return; - } - - $criteria = $this->extractMinMax($this->criteria['delay']); - - $this->filter->addSpecification(new DelaySpecification($criteria['min'], $criteria['max'])); - } - - /** - * @return void - */ - public function buildLife() - { - if (!isset($this->criteria['life'])) { - return; - } - - $criteria = $this->extractMinMax($this->criteria['life']); - - $this->filter->addSpecification(new HopsSpecification($criteria['min'], $criteria['max'])); - } - - /** - * @return void - */ - public function buildOrder() - { - if (!isset($this->criteria['order_by'])) { - return; - } - - $orderings = array(); - - /** - * @var int|string $field - * @var string $direction - */ - foreach ((array) $this->criteria['order_by'] as $field => $direction) { - if (\is_int($field)) { - $field = $direction; - $direction = Filter::ASC; - } - - $direction = Filter::ASC === strtoupper($direction) ? Filter::ASC : Filter::DESC; - - if (\array_key_exists($field, $this->aliases)) { - $field = $this->aliases[$field]; - } - - $orderings[$field] = $direction; - } - - $this->filter->orderBy($orderings); - } - - /** - * @return void - */ - public function buildLimit() - { - if (!isset($this->criteria['limit'])) { - return; - } - - /** @var int $limit */ - $limit = $this->criteria['limit']; - $this->filter->setMaxResults((int) $limit); - } - - /** - * @return void - */ - public function buildStamps() - { - if (!isset($this->criteria['stamps'])) { - return; - } - - /** @var string $strategy */ - $strategy = isset($this->criteria['stamps_strategy']) ? $this->criteria['stamps_strategy'] : StampsSpecification::STRATEGY_OR; - - /** @var array> $stamps */ - $stamps = (array) $this->criteria['stamps']; - - /** - * @var string $key - * @var class-string $value - */ - foreach ($stamps as $key => $value) { - if (\array_key_exists($value, $this->aliases)) { - $stamps[$key] = $this->aliases[$value]; - } - } - - $this->filter->addSpecification(new StampsSpecification($stamps, $strategy)); - } - - /** - * @return void - */ - public function buildCallback() - { - if (!isset($this->criteria['filter'])) { - return; - } - - /** @var callable $callback */ - foreach ((array) $this->criteria['filter'] as $callback) { - $this->filter->addSpecification(new CallbackSpecification($this->filter, $callback)); - } - } - - /** - * @param mixed $criteria - * - * @return array{min: int, max: int} - */ - private function extractMinMax($criteria) - { - if (!\is_array($criteria)) { - $criteria = array('min' => $criteria); - } - - $min = isset($criteria['min']) ? $criteria['min'] : null; - $max = isset($criteria['max']) ? $criteria['max'] : null; - - return array('min' => $min, 'max' => $max); - } -} diff --git a/src/Prime/Filter/Filter.php b/src/Prime/Filter/Filter.php deleted file mode 100644 index f8b15813..00000000 --- a/src/Prime/Filter/Filter.php +++ /dev/null @@ -1,177 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter; - -use Flasher\Prime\Filter\Specification\AndSpecification; -use Flasher\Prime\Filter\Specification\SpecificationInterface; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\OrderableStampInterface; -use Flasher\Prime\Stamp\StampInterface; - -final class Filter -{ - const ASC = 'ASC'; - const DESC = 'DESC'; - - /** - * @var Envelope[] - */ - private $envelopes; - - /** - * @var array - */ - private $criteria; - - /** - * @var SpecificationInterface - */ - private $specification; - - /** - * @var array - */ - private $orderings = array(); - - /** - * @var int|null - */ - private $maxResults; - - /** - * @param Envelope[] $envelopes - * @param array $criteria - */ - public function __construct(array $envelopes, array $criteria) - { - $this->envelopes = $envelopes; - $this->criteria = $criteria; - } - - /** - * @return Envelope[] - */ - public function getResult() - { - $criteriaBuilder = new CriteriaBuilder($this, $this->criteria); - $criteriaBuilder->build(); - - $this->applySpecification(); - $this->applyOrdering(); - $this->applyLimit(); - - return array_values($this->envelopes); - } - - /** - * @return Envelope[] - */ - public function getEnvelopes() - { - return $this->envelopes; - } - - /** - * @return array - */ - public function getCriteria() - { - return $this->criteria; - } - - /** - * @return void - */ - public function addSpecification(SpecificationInterface $specification) - { - $this->specification = null !== $this->specification - ? new AndSpecification($this->specification, $specification) - : $specification; - } - - /** - * @param array $orderings - * - * @return void - */ - public function orderBy(array $orderings) - { - $this->orderings = $orderings; - } - - /** - * @param int $maxResults - * - * @return void - */ - public function setMaxResults($maxResults) - { - $this->maxResults = $maxResults; - } - - /** - * @return void - */ - private function applySpecification() - { - if (null === $this->specification) { - return; - } - - $specification = $this->specification; - $this->envelopes = array_filter($this->envelopes, function (Envelope $envelope) use ($specification) { - return $specification->isSatisfiedBy($envelope); - }); - } - - /** - * @return void - */ - private function applyOrdering() - { - if (array() === $this->orderings) { - return; - } - - $orderings = $this->orderings; - usort($this->envelopes, function (Envelope $first, Envelope $second) use ($orderings) { - /** - * @var class-string $field - * @var string $ordering - */ - foreach ($orderings as $field => $ordering) { - $stampA = $first->get($field); - $stampB = $second->get($field); - - if (!$stampA instanceof OrderableStampInterface || !$stampB instanceof OrderableStampInterface) { - return 0; - } - - if (Filter::ASC === $ordering) { - return $stampA->compare($stampB); - } - - return $stampB->compare($stampA); - } - - return 0; - }); - } - - /** - * @return void - */ - private function applyLimit() - { - if (null === $this->maxResults) { - return; - } - - $this->envelopes = \array_slice($this->envelopes, 0, $this->maxResults, true); - } -} diff --git a/src/Prime/Filter/Specification/AndSpecification.php b/src/Prime/Filter/Specification/AndSpecification.php deleted file mode 100644 index 634214cb..00000000 --- a/src/Prime/Filter/Specification/AndSpecification.php +++ /dev/null @@ -1,42 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Notification\Envelope; - -final class AndSpecification implements SpecificationInterface -{ - /** - * @var SpecificationInterface[] - */ - private $specifications; - - /** - * @param SpecificationInterface|SpecificationInterface[] $specifications - */ - public function __construct($specifications) - { - $specifications = \is_array($specifications) ? $specifications : \func_get_args(); - - $this->specifications = $specifications; - } - - /** - * {@inheritdoc} - */ - public function isSatisfiedBy(Envelope $envelope) - { - foreach ($this->specifications as $specification) { - if (!$specification->isSatisfiedBy($envelope)) { - return false; - } - } - - return true; - } -} diff --git a/src/Prime/Filter/Specification/CallbackSpecification.php b/src/Prime/Filter/Specification/CallbackSpecification.php deleted file mode 100644 index 1dfeea8e..00000000 --- a/src/Prime/Filter/Specification/CallbackSpecification.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Filter\Filter; -use Flasher\Prime\Notification\Envelope; - -final class CallbackSpecification implements SpecificationInterface -{ - /** - * @var Filter - */ - private $filter; - - /** - * @var callable - */ - private $callback; - - /** - * @param callable $callback - */ - public function __construct(Filter $filterBuilder, $callback) - { - $this->filter = $filterBuilder; - $this->callback = $callback; - } - - /** - * {@inheritdoc} - */ - public function isSatisfiedBy(Envelope $envelope) - { - return (bool) \call_user_func($this->callback, $envelope, $this->filter); - } -} diff --git a/src/Prime/Filter/Specification/DelaySpecification.php b/src/Prime/Filter/Specification/DelaySpecification.php deleted file mode 100644 index f258464c..00000000 --- a/src/Prime/Filter/Specification/DelaySpecification.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\DelayStamp; - -final class DelaySpecification implements SpecificationInterface -{ - /** - * @var int - */ - private $minDelay; - - /** - * @var int|null - */ - private $maxDelay; - - /** - * @param int $minDelay - * @param int|null $maxDelay - */ - public function __construct($minDelay, $maxDelay = null) - { - $this->minDelay = $minDelay; - $this->maxDelay = $maxDelay; - } - - /** - * {@inheritdoc} - */ - public function isSatisfiedBy(Envelope $envelope) - { - $stamp = $envelope->get('Flasher\Prime\Stamp\DelayStamp'); - - if (!$stamp instanceof DelayStamp) { - return false; - } - - if (null !== $this->maxDelay && $stamp->getDelay() > $this->maxDelay) { - return false; - } - - return $stamp->getDelay() >= $this->minDelay; - } -} diff --git a/src/Prime/Filter/Specification/HopsSpecification.php b/src/Prime/Filter/Specification/HopsSpecification.php deleted file mode 100644 index 49593609..00000000 --- a/src/Prime/Filter/Specification/HopsSpecification.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\HopsStamp; - -final class HopsSpecification implements SpecificationInterface -{ - /** - * @var int - */ - private $minAmount; - - /** - * @var int|null - */ - private $maxAmount; - - /** - * @param int $minAmount - * @param int|null $maxAmount - */ - public function __construct($minAmount, $maxAmount = null) - { - $this->minAmount = $minAmount; - $this->maxAmount = $maxAmount; - } - - /** - * {@inheritdoc} - */ - public function isSatisfiedBy(Envelope $envelope) - { - $stamp = $envelope->get('Flasher\Prime\Stamp\HopsStamp'); - - if (!$stamp instanceof HopsStamp) { - return false; - } - - if (null !== $this->maxAmount && $stamp->getAmount() > $this->maxAmount) { - return false; - } - - return $stamp->getAmount() >= $this->minAmount; - } -} diff --git a/src/Prime/Filter/Specification/PrioritySpecification.php b/src/Prime/Filter/Specification/PrioritySpecification.php deleted file mode 100644 index ffe202cf..00000000 --- a/src/Prime/Filter/Specification/PrioritySpecification.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\PriorityStamp; - -final class PrioritySpecification implements SpecificationInterface -{ - /** - * @var int - */ - private $minPriority; - - /** - * @var int|null - */ - private $maxPriority; - - /** - * @param int $minPriority - * @param int|null $maxPriority - */ - public function __construct($minPriority, $maxPriority = null) - { - $this->minPriority = $minPriority; - $this->maxPriority = $maxPriority; - } - - /** - * {@inheritdoc} - */ - public function isSatisfiedBy(Envelope $envelope) - { - $stamp = $envelope->get('Flasher\Prime\Stamp\PriorityStamp'); - - if (!$stamp instanceof PriorityStamp) { - return false; - } - - if (null !== $this->maxPriority && $stamp->getPriority() > $this->maxPriority) { - return false; - } - - return $stamp->getPriority() >= $this->minPriority; - } -} diff --git a/src/Prime/Filter/Specification/SpecificationInterface.php b/src/Prime/Filter/Specification/SpecificationInterface.php deleted file mode 100644 index 6bbbf2ae..00000000 --- a/src/Prime/Filter/Specification/SpecificationInterface.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Notification\Envelope; - -interface SpecificationInterface -{ - /** - * @return bool - */ - public function isSatisfiedBy(Envelope $envelope); -} diff --git a/src/Prime/Filter/Specification/StampsSpecification.php b/src/Prime/Filter/Specification/StampsSpecification.php deleted file mode 100644 index f890074f..00000000 --- a/src/Prime/Filter/Specification/StampsSpecification.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ - -namespace Flasher\Prime\Filter\Specification; - -use Flasher\Prime\Notification\Envelope; - -final class StampsSpecification implements SpecificationInterface -{ - const STRATEGY_AND = 'and'; - const STRATEGY_OR = 'or'; - - /** - * @var array|string[] - */ - private $stamps; - - /** - * @var string - */ - private $strategy; - - /** - * @param string|string[] $stamps - * @param string $strategy - */ - public function __construct($stamps, $strategy) - { - $this->stamps = (array) $stamps; - $this->strategy = $strategy; - } - - /** - * {@inheritdoc} - */ - public function isSatisfiedBy(Envelope $envelope) - { - $diff = array_diff($this->stamps, array_keys($envelope->all())); - - if (self::STRATEGY_AND === $this->strategy) { - return 0 === \count($diff); - } - - return \count($diff) < \count($this->stamps); - } -} diff --git a/src/Prime/Flasher.php b/src/Prime/Flasher.php index 56d2eca0..1111e933 100644 --- a/src/Prime/Flasher.php +++ b/src/Prime/Flasher.php @@ -1,118 +1,62 @@ - */ +declare(strict_types=1); namespace Flasher\Prime; use Flasher\Prime\Factory\NotificationFactory; use Flasher\Prime\Factory\NotificationFactoryInterface; -use Flasher\Prime\Notification\NotificationBuilderInterface; -use Flasher\Prime\Response\ResponseManager; +use Flasher\Prime\Factory\NotificationFactoryLocatorInterface; use Flasher\Prime\Response\ResponseManagerInterface; use Flasher\Prime\Storage\StorageManagerInterface; +use Flasher\Prime\Support\Traits\ForwardsCalls; -/** - * @mixin NotificationBuilderInterface - */ -final class Flasher implements FlasherInterface +final readonly class Flasher implements FlasherInterface { - /** - * @var string|null - */ - private $defaultHandler; + use ForwardsCalls; - /** - * @var ResponseManagerInterface - */ - private $responseManager; + public const VERSION = '2.0.0'; - /** - * @var StorageManagerInterface|null - */ - private $storageManager; + public function __construct( + private string $default, + private NotificationFactoryLocatorInterface $factoryLocator, + private ResponseManagerInterface $responseManager, + private StorageManagerInterface $storageManager, + ) { + } - /** - * @var array - */ - private $factories = array(); - - /** - * @param string $defaultHandler - */ - public function __construct($defaultHandler, ResponseManagerInterface $responseManager = null, StorageManagerInterface $storageManager = null) + public function use(?string $alias): NotificationFactoryInterface { - $this->defaultHandler = $defaultHandler ?: 'flasher'; - $this->responseManager = $responseManager ?: new ResponseManager(); - $this->storageManager = $storageManager; + $alias = trim($alias ?: $this->default); + + if ('' === $alias) { + throw new \InvalidArgumentException('Unable to resolve empty factory.'); + } + + if ('flasher' !== $alias && $this->factoryLocator->has($alias)) { + return $this->factoryLocator->get($alias); + } + + return new NotificationFactory($this->storageManager, $alias); + } + + public function create(?string $alias): NotificationFactoryInterface + { + return $this->use($alias); + } + + public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed + { + return $this->responseManager->render($presenter, $criteria, $context); } /** * Dynamically call the default factory instance. * - * @param string $method * @param mixed[] $parameters - * - * @return mixed */ - public function __call($method, array $parameters) + public function __call(string $method, array $parameters): mixed { - /** @var callable $callback */ - $callback = array($this->create(), $method); - - return \call_user_func_array($callback, $parameters); - } - - /** - * {@inheritdoc} - */ - public function create($alias = null) - { - $alias = trim($alias ?: $this->defaultHandler ?: ''); - - if (0 === strpos($alias, 'template.')) { - $alias = 'theme.'.substr($alias, \strlen('template.')); - @trigger_error('Since php-flasher/flasher v1.0, the "template." prefix is deprecated and will be removed in v2.0. Use "theme." instead.', \E_USER_DEPRECATED); - } - - if (empty($alias)) { - throw new \InvalidArgumentException('Unable to resolve empty factory.'); - } - - if (!isset($this->factories[$alias])) { - $this->addFactory($alias, new NotificationFactory($this->storageManager, $alias)); - } - - $factory = $this->factories[$alias]; - - return \is_callable($factory) ? $factory() : $factory; - } - - /** - * {@inheritdoc} - */ - public function using($alias) - { - return $this->create($alias); - } - - /** - * {@inheritdoc} - */ - public function render(array $criteria = array(), $presenter = 'html', array $context = array()) - { - return $this->responseManager->render($criteria, $presenter, $context); - } - - /** - * {@inheritdoc} - */ - public function addFactory($alias, $factory) - { - $this->factories[$alias] = $factory; - - return $this; + return $this->forwardCallTo($this->use(null), $method, $parameters); } } diff --git a/src/Prime/FlasherInterface.php b/src/Prime/FlasherInterface.php index 056a2c9c..9aa34985 100644 --- a/src/Prime/FlasherInterface.php +++ b/src/Prime/FlasherInterface.php @@ -1,60 +1,33 @@ - */ +declare(strict_types=1); namespace Flasher\Prime; use Flasher\Prime\Factory\NotificationFactoryInterface; -use Flasher\Prime\Notification\NotificationBuilderInterface; /** - * @mixin NotificationBuilderInterface + * @mixin \Flasher\Prime\Notification\NotificationBuilderInterface + * + * @method NotificationFactoryInterface create(string $alias) */ interface FlasherInterface { /** - * Get a driver instance. - * - * @param string|null $alias - * - * @return NotificationFactoryInterface + * Get a notification factory instance. * * @throws \InvalidArgumentException */ - public function create($alias = null); + public function use(string $alias): NotificationFactoryInterface; /** - * Get a driver instance. + * Renders the flash notifications based on the specified criteria, presenter, and context. * - * @param string|null $alias - * - * @return NotificationFactoryInterface - * - * @throws \InvalidArgumentException - */ - public function using($alias); - - /** - * Register a custom driver creator. - * - * @param string $alias - * @param callable|NotificationFactoryInterface $factory - * - * @return static - */ - public function addFactory($alias, $factory); - - /** - * @param array $criteria - * @param string $presenter - * @param array $context - * - * @return mixed + * @param array $criteria the criteria to filter the notifications + * @param string|"html"|"json" $presenter The presenter format for rendering the notifications (e.g., 'html', 'json'). + * @param array $context additional context or options for rendering * * @phpstan-return ($presenter is 'html' ? string : mixed) */ - public function render(array $criteria = array(), $presenter = 'html', array $context = array()); + public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed; } diff --git a/src/Prime/Http/Csp/ContentSecurityPolicyHandler.php b/src/Prime/Http/Csp/ContentSecurityPolicyHandler.php new file mode 100644 index 00000000..8c75a491 --- /dev/null +++ b/src/Prime/Http/Csp/ContentSecurityPolicyHandler.php @@ -0,0 +1,272 @@ +getHeaderNonces($request)) { + return $nonces; + } + + if ($response && $nonces = $this->getHeaderNonces($response)) { + return $nonces; + } + + $nonces = [ + 'csp_script_nonce' => $this->generateNonce(), + 'csp_style_nonce' => $this->generateNonce(), + ]; + + $response?->setHeader(self::SCRIPT_NONCE_HEADER, $nonces['csp_script_nonce']); + $response?->setHeader(self::STYLE_NONCE_HEADER, $nonces['csp_style_nonce']); + + return $nonces; + } + + public function disableCsp(): void + { + $this->cspDisabled = true; + } + + public function updateResponseHeaders(RequestInterface $request, ResponseInterface $response): array + { + if ($this->cspDisabled) { + $this->removeCspHeaders($response); + + return []; + } + + $nonces = $this->getNonces($request, $response); + $this->cleanHeaders($response); + $this->updateCspHeaders($response, $nonces); + + return $nonces; + } + + /** + * Returns nonces from headers if existing, otherwise null. + * + * @return array{csp_script_nonce: ?string, csp_style_nonce: ?string}|null + */ + private function getHeaderNonces(RequestInterface|ResponseInterface $object): ?array + { + if ($object->hasHeader(self::SCRIPT_NONCE_HEADER) && $object->hasHeader(self::STYLE_NONCE_HEADER)) { + return [ + 'csp_script_nonce' => $object->getHeader(self::SCRIPT_NONCE_HEADER), + 'csp_style_nonce' => $object->getHeader(self::STYLE_NONCE_HEADER), + ]; + } + + return null; + } + + private function cleanHeaders(ResponseInterface $response): void + { + $response->removeHeader(self::SCRIPT_NONCE_HEADER); + $response->removeHeader(self::STYLE_NONCE_HEADER); + } + + private function removeCspHeaders(ResponseInterface $response): void + { + $response->removeHeader('X-Content-Security-Policy'); + $response->removeHeader('Content-Security-Policy'); + $response->removeHeader('Content-Security-Policy-Report-Only'); + } + + /** + * Updates Content-Security-Policy headers in a response. + * + * @param array{csp_script_nonce?: ?string, csp_style_nonce?: ?string} $nonces + * + * @return array{csp_script_nonce?: ?string, csp_style_nonce?: ?string} + */ + private function updateCspHeaders(ResponseInterface $response, array $nonces = []): array + { + $nonces = array_replace([ + 'csp_script_nonce' => $this->generateNonce(), + 'csp_style_nonce' => $this->generateNonce(), + ], $nonces); + + $ruleIsSet = false; + + $headers = $this->getCspHeaders($response); + + $types = [ + 'script-src' => 'csp_script_nonce', + 'script-src-elem' => 'csp_script_nonce', + 'style-src' => 'csp_style_nonce', + 'style-src-elem' => 'csp_style_nonce', + ]; + + foreach ($headers as $header => $directives) { + foreach ($types as $type => $tokenName) { + if ($this->authorizesInline($directives, $type)) { + continue; + } + if (!isset($headers[$header][$type])) { + if (null === $fallback = $this->getDirectiveFallback($directives, $type)) { + continue; + } + + if (['\'none\''] === $fallback) { + // Fallback came from "default-src: 'none'" + // 'none' is invalid if it's not the only expression in the source list, so we leave it out + $fallback = []; + } + + $headers[$header][$type] = $fallback; + } + $ruleIsSet = true; + if (!\in_array('\'unsafe-inline\'', $headers[$header][$type], true)) { + $headers[$header][$type][] = '\'unsafe-inline\''; + } + $headers[$header][$type][] = sprintf('\'nonce-%s\'', $nonces[$tokenName]); + } + } + + if (!$ruleIsSet) { + return $nonces; + } + + foreach ($headers as $header => $directives) { + $response->setHeader($header, $this->generateCspHeader($directives)); + } + + return $nonces; + } + + /** + * Generates a valid Content-Security-Policy nonce. + */ + private function generateNonce(): string + { + return $this->nonceGenerator->generate(); + } + + /** + * Converts a directive set array into Content-Security-Policy header. + * + * @param array $directives + */ + private function generateCspHeader(array $directives): string + { + return array_reduce(array_keys($directives), fn ($res, $name) => ('' !== $res ? $res.'; ' : '').sprintf('%s %s', $name, implode(' ', $directives[$name])), ''); + } + + /** + * Converts a Content-Security-Policy header value into a directive set array. + * + * @return array + */ + private function parseDirectives(?string $header): array + { + $directives = []; + + foreach (explode(';', $header ?: '') as $directive) { + $parts = explode(' ', trim($directive)); + if (\count($parts) < 1) { // @phpstan-ignore-line + continue; + } + $name = array_shift($parts); + $directives[$name] = $parts; + } + + return $directives; + } + + /** + * Detects if the 'unsafe-inline' is prevented for a directive within the directive set. + * + * @param array $directivesSet + */ + private function authorizesInline(array $directivesSet, string $type): bool + { + if (isset($directivesSet[$type])) { + $directives = $directivesSet[$type]; + } elseif (null === $directives = $this->getDirectiveFallback($directivesSet, $type)) { + return false; + } + + return \in_array('\'unsafe-inline\'', $directives, true) && !$this->hasHashOrNonce($directives); + } + + /** + * @param string[] $directives + */ + private function hasHashOrNonce(array $directives): bool + { + foreach ($directives as $directive) { + if (!str_ends_with($directive, '\'')) { + continue; + } + if (str_starts_with($directive, '\'nonce-')) { + return true; + } + if (\in_array(substr($directive, 0, 8), ['\'sha256-', '\'sha384-', '\'sha512-'], true)) { + return true; + } + } + + return false; + } + + /** + * @param array $directiveSet + * + * @return string[]|null + */ + private function getDirectiveFallback(array $directiveSet, string $type): ?array + { + if (\in_array($type, ['script-src-elem', 'style-src-elem'], true) || !isset($directiveSet['default-src'])) { + // Let the browser fallback on it's own + return null; + } + + return $directiveSet['default-src']; + } + + /** + * Retrieves the Content-Security-Policy headers (either X-Content-Security-Policy or Content-Security-Policy) from + * a response. + * + * @return array{ + * Content-Security-Policy?: array, + * Content-Security-Policy-Report-Only?: array, + * X-Content-Security-Policy?: array, + * } + */ + private function getCspHeaders(ResponseInterface $response): array + { + $headers = []; + + if ($response->hasHeader('Content-Security-Policy')) { + $headers['Content-Security-Policy'] = $this->parseDirectives($response->getHeader('Content-Security-Policy')); + } + + if ($response->hasHeader('Content-Security-Policy-Report-Only')) { + $headers['Content-Security-Policy-Report-Only'] = $this->parseDirectives($response->getHeader('Content-Security-Policy-Report-Only')); + } + + if ($response->hasHeader('X-Content-Security-Policy')) { + $headers['X-Content-Security-Policy'] = $this->parseDirectives($response->getHeader('X-Content-Security-Policy')); + } + + return $headers; + } +} diff --git a/src/Prime/Http/Csp/ContentSecurityPolicyHandlerInterface.php b/src/Prime/Http/Csp/ContentSecurityPolicyHandlerInterface.php new file mode 100644 index 00000000..12c26b78 --- /dev/null +++ b/src/Prime/Http/Csp/ContentSecurityPolicyHandlerInterface.php @@ -0,0 +1,37 @@ + - */ +declare(strict_types=1); namespace Flasher\Prime\Http; use Flasher\Prime\FlasherInterface; -final class RequestExtension +final readonly class RequestExtension implements RequestExtensionInterface { - /** - * @var FlasherInterface - */ - private $flasher; - /** * @var array */ - private $mapping; + private array $mapping; /** * @param array $mapping */ - public function __construct(FlasherInterface $flasher, array $mapping = array()) + public function __construct(private FlasherInterface $flasher, array $mapping = []) { - $this->flasher = $flasher; $this->mapping = $this->flatMapping($mapping); } - /** - * @return ResponseInterface - */ - public function flash(RequestInterface $request, ResponseInterface $response) + public function flash(RequestInterface $request, ResponseInterface $response): ResponseInterface { if (!$request->hasSession()) { return $response; } - foreach ($this->mapping as $alias => $type) { - if (false === $request->hasType($alias)) { - continue; - } - - $messages = (array) $request->getType($alias); - - foreach ($messages as $message) { - $this->flasher->addFlash($type, $message); - } - - $request->forgetType($alias); - } + $this->processRequest($request); return $response; } @@ -61,9 +37,9 @@ final class RequestExtension * * @return array */ - private function flatMapping(array $mapping) + private function flatMapping(array $mapping): array { - $flatMapping = array(); + $flatMapping = []; foreach ($mapping as $type => $aliases) { foreach ($aliases as $alias) { @@ -73,4 +49,24 @@ final class RequestExtension return $flatMapping; } + + /** + * Process the request and flash messages. + */ + private function processRequest(RequestInterface $request): void + { + foreach ($this->mapping as $alias => $type) { + if (!$request->hasType($alias)) { + continue; + } + + $messages = (array) $request->getType($alias); + + foreach ($messages as $message) { + $this->flasher->flash($type, $message); + } + + $request->forgetType($alias); + } + } } diff --git a/src/Prime/Http/RequestExtensionInterface.php b/src/Prime/Http/RequestExtensionInterface.php new file mode 100644 index 00000000..73c2a697 --- /dev/null +++ b/src/Prime/Http/RequestExtensionInterface.php @@ -0,0 +1,10 @@ + - */ +declare(strict_types=1); namespace Flasher\Prime\Http; interface RequestInterface { - /** - * @return bool - */ - public function isXmlHttpRequest(); + public function isXmlHttpRequest(): bool; + + public function isHtmlRequestFormat(): bool; + + public function hasSession(): bool; + + public function isSessionStarted(): bool; + + public function hasType(string $type): bool; /** - * @return bool - */ - public function isHtmlRequestFormat(); - - /** - * @return bool - */ - public function hasSession(); - - /** - * @param string $type - * - * @return bool - */ - public function hasType($type); - - /** - * @param string $type - * * @return string|string[] */ - public function getType($type); + public function getType(string $type): string|array; - /** - * @param string $type - * - * @return void - */ - public function forgetType($type); + public function forgetType(string $type): void; + + public function hasHeader(string $key): bool; + + public function getHeader(string $key): ?string; } diff --git a/src/Prime/Http/ResponseExtension.php b/src/Prime/Http/ResponseExtension.php index 4092af4b..02de15e8 100644 --- a/src/Prime/Http/ResponseExtension.php +++ b/src/Prime/Http/ResponseExtension.php @@ -1,46 +1,32 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Http; use Flasher\Prime\FlasherInterface; +use Flasher\Prime\Http\Csp\ContentSecurityPolicyHandlerInterface; use Flasher\Prime\Response\Presenter\HtmlPresenter; -final class ResponseExtension +final readonly class ResponseExtension implements ResponseExtensionInterface { - /** - * @var FlasherInterface - */ - private $flasher; - - public function __construct(FlasherInterface $flasher) + public function __construct(private FlasherInterface $flasher, private ContentSecurityPolicyHandlerInterface $cspHandler) { - $this->flasher = $flasher; } - /** - * @return ResponseInterface - */ - public function render(RequestInterface $request, ResponseInterface $response) + public function render(RequestInterface $request, ResponseInterface $response): ResponseInterface { if (!$this->isRenderable($request, $response)) { return $response; } - $content = $response->getContent() ?: ''; - if (!\is_string($content)) { - return $response; - } + $content = $response->getContent(); - $placeHolders = array( - HtmlPresenter::FLASHER_FLASH_BAG_PLACE_HOLDER, + $placeHolders = [ + HtmlPresenter::FLASHER_REPLACE_ME, HtmlPresenter::HEAD_END_PLACE_HOLDER, HtmlPresenter::BODY_END_PLACE_HOLDER, - ); + ]; foreach ($placeHolders as $insertPlaceHolder) { $insertPosition = strripos($content, $insertPlaceHolder); @@ -53,31 +39,41 @@ final class ResponseExtension return $response; } - $alreadyRendered = HtmlPresenter::FLASHER_FLASH_BAG_PLACE_HOLDER === $insertPlaceHolder; - $htmlResponse = $this->flasher->render(array(), 'html', array('envelopes_only' => $alreadyRendered)); + $alreadyRendered = HtmlPresenter::FLASHER_REPLACE_ME === $insertPlaceHolder; + $nonces = $this->cspHandler->updateResponseHeaders($request, $response); + + $context = [ + 'envelopes_only' => $alreadyRendered, + 'csp_script_nonce' => $nonces['csp_script_nonce'] ?? null, + 'csp_style_nonce' => $nonces['csp_style_nonce'] ?? null, + ]; + + $htmlResponse = $this->flasher->render('html', [], $context); if (empty($htmlResponse)) { return $response; } - $htmlResponse = "\n".str_replace("\n", '', $htmlResponse)."\n"; - $offset = $alreadyRendered ? strlen(HtmlPresenter::FLASHER_FLASH_BAG_PLACE_HOLDER) : 0; + if ($alreadyRendered) { + $htmlResponse = sprintf('options.push(%s);', $htmlResponse); + } - $content = substr($content, 0, $insertPosition).$htmlResponse.substr($content, $insertPosition + $offset); + // $htmlResponse = "\n".str_replace("\n", '', (string) $htmlResponse)."\n"; + $htmlResponse .= "\n"; + + $content = substr($content, 0, $insertPosition).$htmlResponse.substr($content, $insertPosition); $response->setContent($content); return $response; } - /** - * @return bool - */ - private function isRenderable(RequestInterface $request, ResponseInterface $response) + private function isRenderable(RequestInterface $request, ResponseInterface $response): bool { return !$request->isXmlHttpRequest() && $request->isHtmlRequestFormat() - && !$response->isRedirection() && $response->isHtml() + && $response->isSuccessful() + && !$response->isRedirection() && !$response->isAttachment() && !$response->isJson(); } diff --git a/src/Prime/Http/ResponseExtensionInterface.php b/src/Prime/Http/ResponseExtensionInterface.php new file mode 100644 index 00000000..1841e0f9 --- /dev/null +++ b/src/Prime/Http/ResponseExtensionInterface.php @@ -0,0 +1,18 @@ + - */ +declare(strict_types=1); namespace Flasher\Prime\Http; interface ResponseInterface { - /** - * @return bool - */ - public function isRedirection(); + public function isRedirection(): bool; + + public function isJson(): bool; + + public function isHtml(): bool; + + public function isAttachment(): bool; + + public function isSuccessful(): bool; + + public function getContent(): string; + + public function setContent(string $content): void; + + public function hasHeader(string $key): bool; + + public function getHeader(string $key): ?string; /** - * @return bool + * @param string|string[]|null $values */ - public function isJson(); + public function setHeader(string $key, string|array|null $values): void; - /** - * @return bool - */ - public function isHtml(); - - /** - * @return bool - */ - public function isAttachment(); - - /** - * @return string - */ - public function getContent(); - - /** - * @param string $content - * - * @return void - */ - public function setContent($content); + public function removeHeader(string $key): void; } diff --git a/src/Prime/LICENSE b/src/Prime/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Prime/LICENSE +++ b/src/Prime/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Prime/Notification/Envelope.php b/src/Prime/Notification/Envelope.php index e0085464..21981a4b 100644 --- a/src/Prime/Notification/Envelope.php +++ b/src/Prime/Notification/Envelope.php @@ -1,134 +1,109 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Notification; use Flasher\Prime\Stamp\PresentableStampInterface; use Flasher\Prime\Stamp\StampInterface; +use Flasher\Prime\Support\Traits\ForwardsCalls; +/** + * Envelope class wraps a notification and manages associated stamps. + */ final class Envelope implements NotificationInterface { - /** - * @var NotificationInterface - */ - private $notification; + use ForwardsCalls; /** * @var array, StampInterface> */ - private $stamps = array(); + private array $stamps = []; /** - * @param StampInterface|StampInterface[] $stamps + * @param StampInterface[]|StampInterface $stamps stamps to be added to the envelope */ - public function __construct(NotificationInterface $notification, $stamps = array()) + public function __construct(private readonly NotificationInterface $notification, array|StampInterface $stamps = []) { - $this->notification = $notification; - $this->with(\is_array($stamps) ? $stamps : \array_slice(\func_get_args(), 1)); + $stamps = $stamps instanceof StampInterface ? [$stamps] : $stamps; + + $this->with(...$stamps); } /** - * Dynamically call methods on the notification. + * Wraps a notification in an Envelope and adds the given stamps. * - * @param string $method - * @param mixed[] $parameters - * - * @return mixed + * @param StampInterface|StampInterface[] $stamps stamps to be added to the envelope */ - public function __call($method, array $parameters) - { - /** @var callable $callback */ - $callback = array($this->getNotification(), $method); - - return \call_user_func_array($callback, $parameters); - } - - /** - * Makes sure the notification is in an Envelope and adds the given stamps. - * - * @param StampInterface|StampInterface[] $stamps - * - * @return static - */ - public static function wrap(NotificationInterface $notification, $stamps = array()) + public static function wrap(NotificationInterface $notification, array|StampInterface $stamps = []): self { $envelope = $notification instanceof self ? $notification : new self($notification); + $stamps = $stamps instanceof StampInterface ? [$stamps] : $stamps; - return $envelope->with(\is_array($stamps) ? $stamps : \array_slice(\func_get_args(), 1)); + $envelope->with(...$stamps); + + return $envelope; } /** - * @param StampInterface|StampInterface[] $stamps + * Adds multiple stamps to the envelope. * - * @return static + * @param StampInterface ...$stamps The stamps to add. */ - public function with($stamps) + public function with(StampInterface ...$stamps): void { - $stamps = \is_array($stamps) ? $stamps : \func_get_args(); - foreach ($stamps as $stamp) { $this->withStamp($stamp); } - - return $this; } /** - * @return static - */ - public function withStamp(StampInterface $stamp) - { - $this->stamps[\get_class($stamp)] = $stamp; - - return $this; - } - - /** - * @param StampInterface|StampInterface[] $stamps + * Adds or replaces a stamp in the envelope. * - * @return static + * @param StampInterface $stamp the stamp to add or replace + * @param bool $replace whether to replace an existing stamp of the same type */ - public function without($stamps) + public function withStamp(StampInterface $stamp, bool $replace = true): void { - $stamps = \is_array($stamps) ? $stamps : \func_get_args(); + if (!isset($this->stamps[$stamp::class]) || $replace) { + $this->stamps[$stamp::class] = $stamp; + } + } + /** + * Removes specified stamps from the envelope. + */ + public function without(StampInterface ...$stamps): void + { foreach ($stamps as $stamp) { $this->withoutStamp($stamp); } - - return $this; } /** - * @param class-string|StampInterface $type + * Removes a specific type of stamp from the envelope. * - * @return static + * @param class-string|StampInterface $type the type of stamp to remove */ - public function withoutStamp($type) + public function withoutStamp(string|StampInterface $type): void { - $type = $type instanceof StampInterface ? \get_class($type) : $type; + $type = $type instanceof StampInterface ? $type::class : $type; unset($this->stamps[$type]); - - return $this; } /** - * @param class-string $stampFqcn + * Retrieves a stamp by its type. * - * @return StampInterface|null + * @template T of StampInterface + * + * @phpstan-param class-string $type + * + * @phpstan-return T|null */ - public function get($stampFqcn) + public function get(string $type): ?StampInterface { - if (!isset($this->stamps[$stampFqcn])) { - return null; - } - - return $this->stamps[$stampFqcn]; + return $this->stamps[$type] ?? null; // @phpstan-ignore-line } /** @@ -136,124 +111,113 @@ final class Envelope implements NotificationInterface * * @return array, StampInterface> */ - public function all() + public function all(): array { return $this->stamps; } /** - * The original notification contained in the envelope. + * Gets the original notification contained in the envelope. * - * @return NotificationInterface + * @return NotificationInterface the wrapped notification */ - public function getNotification() + public function getNotification(): NotificationInterface { return $this->notification; } - /** - * {@inheritdoc} - */ - public function getType() - { - return $this->notification->getType(); - } - - /** - * {@inheritdoc} - */ - public function setType($type) - { - return $this->notification->setType($type); // @phpstan-ignore-line - } - - /** - * {@inheritdoc} - */ - public function getMessage() - { - return $this->notification->getMessage(); - } - - /** - * {@inheritdoc} - */ - public function setMessage($message) - { - return $this->notification->setMessage($message); // @phpstan-ignore-line - } - - /** - * {@inheritdoc} - */ - public function getTitle() + public function getTitle(): string { return $this->notification->getTitle(); } - /** - * {@inheritdoc} - */ - public function setTitle($title) + public function setTitle(string $title): void { - return $this->notification->setTitle($title); // @phpstan-ignore-line + $this->notification->setTitle($title); } - /** - * {@inheritdoc} - */ - public function getOptions() + public function getMessage(): string + { + return $this->notification->getMessage(); + } + + public function setMessage(string $message): void + { + $this->notification->setMessage($message); + } + + public function getType(): string + { + return $this->notification->getType(); + } + + public function setType(string $type): void + { + $this->notification->setType($type); + } + + public function getOptions(): array { return $this->notification->getOptions(); } - /** - * {@inheritdoc} - */ - public function setOptions(array $options) + public function setOptions(array $options): void { - return $this->notification->setOptions($options); // @phpstan-ignore-line + $this->notification->setOptions($options); } - /** - * {@inheritdoc} - */ - public function getOption($name, $default = null) + public function getOption(string $name, mixed $default = null): mixed { return $this->notification->getOption($name, $default); } - /** - * {@inheritdoc} - */ - public function setOption($name, $value) + public function setOption(string $name, mixed $value): void { - return $this->notification->setOption($name, $value); // @phpstan-ignore-line + $this->notification->setOption($name, $value); + } + + public function unsetOption(string $name): void + { + $this->notification->unsetOption($name); } /** - * {@inheritdoc} + * Converts the envelope and its contents to an array format. + * + * @return array{ + * title: string, + * message: string, + * type: string, + * options: array, + * metadata: array, + * } */ - public function unsetOption($name) + public function toArray(): array { - return $this->notification->unsetOption($name); // @phpstan-ignore-line - } + $stamps = []; - /** - * {@inheritdoc} - */ - public function toArray() - { - $array = array( - 'notification' => $this->notification->toArray(), - ); - - foreach ($this->all() as $stamp) { + foreach ($this->stamps as $stamp) { if ($stamp instanceof PresentableStampInterface) { - $array = array_merge($array, $stamp->toArray()); + $stamps[] = $stamp->toArray(); } } - return $array; + return [ + ...$this->notification->toArray(), + 'metadata' => array_merge(...$stamps), + ]; + } + + /** + * Dynamically call methods on the wrapped notification. + * + * @param string $method the method name to call + * @param mixed[] $parameters the parameters to pass to the method + * + * @return mixed the result of the method call + */ + public function __call(string $method, array $parameters): mixed + { + return $this->forwardCallTo($this->notification, $method, $parameters); } } diff --git a/src/Prime/Notification/Notification.php b/src/Prime/Notification/Notification.php index b55f6e6b..7a5fda1c 100644 --- a/src/Prime/Notification/Notification.php +++ b/src/Prime/Notification/Notification.php @@ -1,148 +1,155 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Notification; -class Notification implements NotificationInterface +final class Notification implements NotificationInterface { - /** - * @var string|null - */ - protected $message; + private string $title = ''; + + private string $message = ''; + + private string $type = ''; /** - * @var string|null + * @var array options for the notification */ - protected $type; + private array $options = []; /** - * @var array + * Gets the title of the notification. + * + * @return string the notification title */ - protected $options = array(); - - /** - * @var string|null - */ - private $title; - - /** - * {@inheritdoc} - */ - public function getType() - { - return $this->type; - } - - /** - * {@inheritdoc} - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getMessage() - { - return $this->message; - } - - /** - * {@inheritdoc} - */ - public function setMessage($message) - { - $this->message = $message; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getTitle() + public function getTitle(): string { return $this->title; } /** - * {@inheritdoc} + * Sets the title of the notification. + * + * @param string $title the title to set */ - public function setTitle($title) + public function setTitle(string $title): void { $this->title = $title; - - return $this; } /** - * {@inheritdoc} + * Gets the message of the notification. + * + * @return string the notification message */ - public function getOptions() + public function getMessage(): string + { + return $this->message; + } + + /** + * Sets the message of the notification. + * + * @param string $message the message to set + */ + public function setMessage(string $message): void + { + $this->message = $message; + } + + /** + * Gets the type of the notification. + * + * @return string the notification type + */ + public function getType(): string + { + return $this->type; + } + + /** + * Sets the type of the notification. + * + * @param string $type the type to set + */ + public function setType(string $type): void + { + $this->type = $type; + } + + /** + * Gets all options of the notification. + * + * @return array the notification options + */ + public function getOptions(): array { return $this->options; } /** - * {@inheritdoc} + * Sets or updates the options of the notification. + * + * @param array $options the options to set or update */ - public function setOptions(array $options) + public function setOptions(array $options): void { $this->options = array_replace($this->options, $options); - - return $this; } /** - * {@inheritdoc} + * Gets a specific option of the notification with a default fallback. + * + * @param string $name the name of the option + * @param mixed $default the default value to return if the option is not set + * + * @return mixed the option value or the default value */ - public function getOption($name, $default = null) + public function getOption(string $name, mixed $default = null): mixed { - if (!isset($this->options[$name])) { - return $default; - } - - return $this->options[$name]; + return \array_key_exists($name, $this->options) + ? $this->options[$name] + : $default; } /** - * {@inheritdoc} + * Sets a specific option for the notification. + * + * @param string $name the name of the option + * @param mixed $value the value of the option */ - public function setOption($name, $value) + public function setOption(string $name, mixed $value): void { $this->options[$name] = $value; - - return $this; } /** - * {@inheritdoc} + * Unsets a specific option of the notification. + * + * @param string $name the name of the option to unset */ - public function unsetOption($name) + public function unsetOption(string $name): void { unset($this->options[$name]); - - return $this; } /** - * {@inheritdoc} + * Converts the notification into an associative array. + * + * @return array{ + * title: string, + * message: string, + * type: string, + * options: array, + * } */ - public function toArray() + public function toArray(): array { - return array( - 'type' => $this->getType(), - 'message' => $this->getMessage(), - 'title' => $this->getTitle(), - 'options' => $this->getOptions(), - ); + return [ + 'title' => $this->title, + 'message' => $this->message, + 'type' => $this->type, + 'options' => $this->options, + ]; } } diff --git a/src/Prime/Notification/NotificationBuilder.php b/src/Prime/Notification/NotificationBuilder.php index 5a4d3acc..737fdcc3 100644 --- a/src/Prime/Notification/NotificationBuilder.php +++ b/src/Prime/Notification/NotificationBuilder.php @@ -1,647 +1,34 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Notification; -use Flasher\Prime\Stamp\ContextStamp; -use Flasher\Prime\Stamp\DelayStamp; -use Flasher\Prime\Stamp\HandlerStamp; -use Flasher\Prime\Stamp\HopsStamp; -use Flasher\Prime\Stamp\PresetStamp; -use Flasher\Prime\Stamp\PriorityStamp; -use Flasher\Prime\Stamp\StampInterface; -use Flasher\Prime\Stamp\TranslationStamp; -use Flasher\Prime\Stamp\UnlessStamp; -use Flasher\Prime\Stamp\WhenStamp; +use Flasher\Prime\Stamp\PluginStamp; use Flasher\Prime\Storage\StorageManagerInterface; -use Flasher\Prime\Translation\ResourceInterface; +use Flasher\Prime\Support\Traits\Macroable; -/** - * @SuppressWarnings(PHPMD.TooManyPublicMethods) - */ class NotificationBuilder implements NotificationBuilderInterface { - /** - * @var Envelope - */ - protected $envelope; + use Macroable; + use NotificationBuilderMethods; + use NotificationMethodAliases; + use NotificationStorageMethods; - /** - * @var StorageManagerInterface - */ - protected $storageManager; - - /** - * @var array - */ - protected static $macros = array(); - - /** - * @param string $handler - */ - public function __construct(StorageManagerInterface $storageManager, NotificationInterface $notification, $handler = null) + public function __construct(string|NotificationInterface $notification, StorageManagerInterface $storageManager) { + if (\is_string($notification)) { + $plugin = new PluginStamp($notification); + + $notification = Envelope::wrap(new Notification()); + $notification->withStamp($plugin); + } + + $envelope = Envelope::wrap($notification); + $envelope->withStamp(new PluginStamp('flasher'), false); + + $this->envelope = $envelope; + $this->storageManager = $storageManager; - $this->envelope = Envelope::wrap($notification); - - if (null !== $handler) { - $this->handler($handler); - } - } - - /** - * @param string $method - * @param mixed[] $parameters - * - * @return mixed - */ - public static function __callStatic($method, $parameters) - { - if (!static::hasMacro($method)) { - throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', \get_called_class(), $method)); - } - - $macro = static::$macros[$method]; - - if ($macro instanceof \Closure) { - /** @var callable $callback */ - $callback = \Closure::bind($macro, null, \get_called_class()); - - return \call_user_func_array($callback, $parameters); - } - - return \call_user_func_array($macro, $parameters); - } - - /** - * @param string $method - * @param mixed[] $parameters - * - * @return mixed - */ - public function __call($method, $parameters) - { - if (!static::hasMacro($method)) { - throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', \get_called_class(), $method)); - } - - $macro = static::$macros[$method]; - - if ($macro instanceof \Closure) { - /** @var callable $callback */ - $callback = $macro->bindTo($this, \get_called_class()); - - return \call_user_func_array($callback, $parameters); - } - - return \call_user_func_array($macro, $parameters); - } - - /** - * {@inheritdoc} - */ - public function addSuccess($message, $title = null, array $options = array()) - { - return $this->addFlash(NotificationInterface::SUCCESS, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function addError($message, $title = null, array $options = array()) - { - return $this->addFlash(NotificationInterface::ERROR, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function addWarning($message, $title = null, array $options = array()) - { - return $this->addFlash(NotificationInterface::WARNING, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function addInfo($message, $title = null, array $options = array()) - { - return $this->addFlash(NotificationInterface::INFO, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function addFlash($type, $message = null, $title = null, array $options = array()) - { - if ($type instanceof NotificationInterface) { - $this->envelope = Envelope::wrap($type); - $type = $this->envelope->getType(); - } - - $this->type($type, $message, $title, $options); // @phpstan-ignore-line - - return $this->push(); - } - - /** - * {@inheritdoc} - */ - public function push(array $stamps = array()) - { - if (array() !== $stamps) { - $this->with($stamps); - } - - $this->storageManager->add($this->getEnvelope()); - - return $this->getEnvelope(); - } - - /** - * {@inheritdoc} - */ - public function flash(array $stamps = array()) - { - @trigger_error('Since php-flasher/flasher v1.12: Using "flash()" method is deprecated and will be removed in v2.0. please use the "push()" method instead.', \E_USER_DEPRECATED); - - return $this->push($stamps); - } - - /** - * {@inheritdoc} - */ - public function type($type, $message = null, $title = null, array $options = array()) - { - $this->envelope->setType($type); - - if (null !== $message) { - $this->message($message); - } - - if (\is_array($title)) { - $options = $title; - $title = null; - @trigger_error('Since php-flasher/flasher v1.0: Passing an array for the "title" parameter is deprecated and will be removed in v2.0. You should pass a string instead.', \E_USER_DEPRECATED); - } - - if (null !== $title) { - $this->title($title); - } - - if (array() !== $options) { - $this->options($options, false); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function message($message) - { - $this->envelope->setMessage($message); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function title($title) - { - $this->envelope->setTitle($title); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function options(array $options, $merge = true) - { - if (true === $merge) { - $options = array_merge($this->envelope->getOptions(), $options); - } - - $this->envelope->setOptions($options); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function option($name, $value) - { - $this->envelope->setOption($name, $value); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function success($message = null, $title = null, array $options = array()) - { - @trigger_error('In php-flasher/flasher v2.0, the "success()" method will be an alias of "addSuccess()" method as it will immediately call the `->flash()` method. Use the "type(\'success\')" method instead to avoid this breaking change.', \E_USER_DEPRECATED); - - return $this->type(NotificationInterface::SUCCESS, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function error($message = null, $title = null, array $options = array()) - { - @trigger_error('In php-flasher/flasher v2.0, the "error()" method will be an alias of "addError()" method as it will immediately call the `->flash()` method. Use the "type(\'error\')" method instead to avoid this breaking change.', \E_USER_DEPRECATED); - - return $this->type(NotificationInterface::ERROR, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function info($message = null, $title = null, array $options = array()) - { - @trigger_error('In php-flasher/flasher v2.0, the "info()" method will be an alias of "addInfo()" method as it will immediately call the `->flash()` method. Use the "type(\'info\')" method instead to avoid this breaking change.', \E_USER_DEPRECATED); - - return $this->type(NotificationInterface::INFO, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function warning($message = null, $title = null, array $options = array()) - { - @trigger_error('In php-flasher/flasher v2.0, the "warning()" method will be an alias of "addWarning()" method as it will immediately call the `->flash()` method. Use the "type(\'warning\')" method instead to avoid this breaking change.', \E_USER_DEPRECATED); - - return $this->type(NotificationInterface::WARNING, $message, $title, $options); - } - - /** - * {@inheritdoc} - */ - public function when($condition) - { - if ($condition instanceof \Closure) { - $condition = \call_user_func($condition, $this->envelope); - } - - if (!\is_bool($condition)) { - throw new \InvalidArgumentException('The condition must be a boolean or a closure that returns a boolean.'); - } - - $stamp = $this->envelope->get('Flasher\Prime\Stamp\WhenStamp'); - if ($stamp instanceof WhenStamp) { - $condition = $stamp->getCondition() && $condition; - } - - $this->envelope->withStamp(new WhenStamp($condition)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function unless($condition) - { - if ($condition instanceof \Closure) { - $condition = \call_user_func($condition, $this->envelope); - } - - if (!\is_bool($condition)) { - throw new \InvalidArgumentException('The condition must be a boolean or a closure that returns a boolean.'); - } - - $stamp = $this->envelope->get('Flasher\Prime\Stamp\UnlessStamp'); - if ($stamp instanceof UnlessStamp) { - $condition = $stamp->getCondition() || $condition; - } - - $this->envelope->withStamp(new UnlessStamp($condition)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function priority($priority) - { - $this->envelope->withStamp(new PriorityStamp($priority)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function hops($amount) - { - $this->envelope->withStamp(new HopsStamp($amount)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function keep() - { - $hopsStamp = $this->envelope->get('Flasher\Prime\Stamp\HopsStamp'); - $amount = $hopsStamp instanceof HopsStamp ? $hopsStamp->getAmount() : 1; - - $this->envelope->withStamp(new HopsStamp($amount + 1)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function delay($delay) - { - $this->envelope->withStamp(new DelayStamp($delay)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function now() - { - return $this->delay(0); - } - - /** - * {@inheritdoc} - */ - public function translate($parameters = array(), $locale = null) - { - $order = TranslationStamp::parametersOrder($parameters, $locale); - $parameters = $order['parameters']; - $locale = $order['locale']; - - $this->envelope->withStamp(new TranslationStamp($parameters, $locale)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function addPreset($preset, $parameters = array()) - { - $this->preset($preset, $parameters); - - return $this->push(); - } - - /** - * {@inheritdoc} - */ - public function addOperation($operation, $resource = null) - { - $this->operation($operation, $resource); - - return $this->push(); - } - - /** - * {@inheritdoc} - */ - public function addCreated($resource = null) - { - return $this->addOperation('created', $resource); - } - - /** - * {@inheritdoc} - */ - public function addUpdated($resource = null) - { - return $this->addOperation('updated', $resource); - } - - /** - * {@inheritdoc} - */ - public function addSaved($resource = null) - { - return $this->addOperation('saved', $resource); - } - - /** - * {@inheritdoc} - */ - public function addDeleted($resource = null) - { - return $this->addOperation('deleted', $resource); - } - - /** - * {@inheritdoc} - */ - public function preset($preset, $parameters = array()) - { - @trigger_error('In php-flasher/flasher v2.0, the "preset()" method will be an alias of "addPreset()" method as will immediately call the `->flash()` method. Use the "addPreset()" method instead to avoid this breaking change.', \E_USER_WARNING); - - $flash = false; - - if (\is_bool($parameters)) { /** @phpstan-ignore-line */ - $flash = $parameters; - $parameters = array(); - @trigger_error('Since php-flasher/flasher v1.5: automatically flashing a preset is deprecated and will be removed in v2.0. You should use addPreset() or chain the preset call with flash() instead.', \E_USER_DEPRECATED); - } - - $this->envelope->withStamp(new PresetStamp($preset, $parameters)); - - if (false === $flash) { - return $this; - } - - return $this->push(); // @phpstan-ignore-line - } - - /** - * {@inheritdoc} - */ - public function operation($operation, $resource = null) - { - @trigger_error('In php-flasher/flasher v2.0, the "operation()" method will be an alias of "addOperation()" method as will immediately call the `->flash()` method. Use the "addOperation()" method instead to avoid this breaking change.', \E_USER_WARNING); - - if ($resource instanceof ResourceInterface) { - $type = $resource->getResourceType(); - $name = $resource->getResourceName(); - - $resource = sprintf( - '%s %s', - $type, - empty($name) ? '' : sprintf('"%s"', $name) - ); - } - - $parameters = array( - 'resource' => $resource ?: 'resource', - ); - - return $this->preset($operation, $parameters); - } - - /** - * {@inheritdoc} - */ - public function created($resource = null) - { - @trigger_error('In php-flasher/flasher v2.0, the "created()" method will be an alias of "addCreated()" method as will immediately call the `->flash()` method. Use the "addCreated()" method instead to avoid this breaking change.', \E_USER_WARNING); - - return $this->operation('created', $resource); - } - - /** - * {@inheritdoc} - */ - public function updated($resource = null) - { - @trigger_error('In php-flasher/flasher v2.0, the "updated()" method will be an alias of "addUpdated()" method as will immediately call the `->flash()` method. Use the "addUpdated()" method instead to avoid this breaking change.', \E_USER_WARNING); - - return $this->operation('updated', $resource); - } - - /** - * {@inheritdoc} - */ - public function saved($resource = null) - { - @trigger_error('In php-flasher/flasher v2.0, the "saved()" method will be an alias of "addSaved()" method as will immediately call the `->flash()` method. Use the "addSaved()" method instead to avoid this breaking change.', \E_USER_WARNING); - - return $this->operation('saved', $resource); - } - - /** - * {@inheritdoc} - */ - public function deleted($resource = null) - { - @trigger_error('In php-flasher/flasher v2.0, the "deleted()" method will be an alias of "addDeleted()" method as will immediately call the `->flash()` method. Use the "addDeleted()" method instead to avoid this breaking change.', \E_USER_WARNING); - - return $this->operation('deleted', $resource); - } - - /** - * {@inheritdoc} - */ - public function with($stamps = array()) - { - $this->envelope->with($stamps); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function withStamp(StampInterface $stamp) - { - $this->envelope->withStamp($stamp); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getEnvelope() - { - return $this->envelope; - } - - /** - * {@inheritdoc} - */ - public function handler($handler) - { - $stamp = $this->envelope->get('Flasher\Prime\Stamp\HandlerStamp'); - - if ($stamp instanceof HandlerStamp) { - throw new \LogicException('You cannot change the handler of a notification once it has been set.'); - } - - $this->envelope->withStamp(new HandlerStamp($handler)); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function context(array $context) - { - $this->envelope->withStamp(new ContextStamp($context)); - - return $this; - } - - /** - * @param string $name - * @param callable $macro - * - * @return void - */ - public static function macro($name, $macro) - { - static::$macros[$name] = $macro; - } - - /** - * @param object $mixin - * @param bool $replace - * - * @return void - */ - public static function mixin($mixin, $replace = true) - { - $reflection = new \ReflectionClass($mixin); - $methods = $reflection->getMethods( - \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED - ); - - foreach ($methods as $method) { - if ($replace || !static::hasMacro($method->name)) { - $method->setAccessible(true); - - /** @var callable $callable */ - $callable = $method->invoke($mixin); - static::macro($method->name, $callable); - } - } - } - - /** - * @param string $name - * - * @return bool - */ - public static function hasMacro($name) - { - return isset(static::$macros[$name]); - } - - /** - * {@inheritdoc} - */ - public function livewire(array $context = array()) - { - @trigger_error(sprintf('Since php-flasher/flasher v1.0: Using %s method is deprecated and will be removed in v2.0. please use the builder methods directly.', __METHOD__), \E_USER_DEPRECATED); - - return $this; } } diff --git a/src/Prime/Notification/NotificationBuilderInterface.php b/src/Prime/Notification/NotificationBuilderInterface.php index 76542729..e3879415 100644 --- a/src/Prime/Notification/NotificationBuilderInterface.php +++ b/src/Prime/Notification/NotificationBuilderInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Notification; @@ -12,343 +9,129 @@ use Flasher\Prime\Translation\ResourceInterface; interface NotificationBuilderInterface { - /** - * @param string $message - * @param array|string|null $title - * @param array $options - * - * @return Envelope - */ - public function addSuccess($message, $title = null, array $options = array()); + public function title(string $title): static; - /** - * @param string $message - * @param array|string|null $title - * @param array $options - * - * @return Envelope - */ - public function addError($message, $title = null, array $options = array()); + public function message(string $message): static; - /** - * @param string $message - * @param array|string|null $title - * @param array $options - * - * @return Envelope - */ - public function addWarning($message, $title = null, array $options = array()); - - /** - * @param string $message - * @param array|string|null $title - * @param array $options - * - * @return Envelope - */ - public function addInfo($message, $title = null, array $options = array()); - - /** - * @param NotificationInterface|string $type - * @param string|null $message - * @param array|string|null $title - * @param array $options - * - * @return Envelope - */ - public function addFlash($type, $message, $title = null, array $options = array()); - - /** - * @param string $type - * @param string|null $message - * @param array|string|null $title - * @param array $options - * - * @return static - */ - public function type($type, $message = null, $title = null, array $options = array()); - - /** - * @param string $message - * - * @return static - */ - public function message($message); - - /** - * @param string $title - * - * @return static - */ - public function title($title); + public function type(string $type): static; /** * @param array $options - * @param bool $merge - * - * @return static */ - public function options(array $options, $merge = true); + public function options(array $options, bool $merge = true): static; - /** - * @param string $name - * @param mixed $value - * - * @return static - */ - public function option($name, $value); + public function option(string $name, mixed $value): static; - /** - * @deprecated In php-flasher/flasher v2.0, the "success()" method will be an alias of "addSuccess()" method as it will immediately call the `->flash()` method. Use the "type('success')" method instead to avoid this breaking change. - * - * @param string|null $message - * @param array|string|null $title - * @param array $options - * - * @return static - */ - public function success($message = null, $title = null, array $options = array()); + public function priority(int $priority): static; - /** - * @deprecated In php-flasher/flasher v2.0, the "error()" method will be an alias of "addError()" method as it will immediately call the `->flash()` method. Use the "type('error')" method instead to avoid this breaking change. - * - * @param string|null $message - * @param array|string|null $title - * @param array $options - * - * @return static - */ - public function error($message = null, $title = null, array $options = array()); + public function keep(): static; - /** - * @deprecated In php-flasher/flasher v2.0, the "info()" method will be an alias of "addInfo()" method as it will immediately call the `->flash()` method. Use the "type('info')" method instead to avoid this breaking change. - * - * @param string|null $message - * @param array|string|null $title - * @param array $options - * - * @return static - */ - public function info($message = null, $title = null, array $options = array()); + public function hops(int $amount): static; - /** - * @deprecated In php-flasher/flasher v2.0, the "warning()" method will be an alias of "addWarning()" method as it will immediately call the `->flash()` method. Use the "type('warning')" method instead to avoid this breaking change. - * - * @param string|null $message - * @param array|string|null $title - * @param array $options - * - * @return static - */ - public function warning($message = null, $title = null, array $options = array()); - - /** - * @param bool|\Closure $condition - * - * @return static - */ - public function when($condition); - - /** - * @param bool|\Closure $condition - * - * @return static - */ - public function unless($condition); - - /** - * @param int $priority - * - * @return static - */ - public function priority($priority); - - /** - * @return static - */ - public function keep(); - - /** - * @param int $amount - * - * @return static - */ - public function hops($amount); - - /** - * @param string $handler - * - * @return static - */ - public function handler($handler); - - /** - * @param mixed[] $context - * - * @return static - */ - public function context(array $context); - - /** - * @return static - */ - public function withStamp(StampInterface $stamp); - - /** - * @param StampInterface|StampInterface[] $stamps - * - * @return static - */ - public function with($stamps = array()); - - /** - * @return static - */ - public function now(); - - /** - * @param int $delay - * - * @return static - */ - public function delay($delay); + public function delay(int $delay): static; /** * @param array $parameters - * @param string|null $locale - * - * @return static */ - public function translate($parameters = array(), $locale = null); + public function translate(array $parameters = [], ?string $locale = null): static; + + public function handler(string $handler): static; /** - * @param string $preset - * @param array $parameters - * - * @return Envelope - */ - public function addPreset($preset, $parameters = array()); - - /** - * @param string $operation - * @param ResourceInterface|string|null $resource - * - * @return Envelope - */ - public function addOperation($operation, $resource = null); - - /** - * @param ResourceInterface|string|null $resource - * - * @return Envelope - */ - public function addCreated($resource = null); - - /** - * @param ResourceInterface|string|null $resource - * - * @return Envelope - */ - public function addUpdated($resource = null); - - /** - * @param ResourceInterface|string|null $resource - * - * @return Envelope - */ - public function addSaved($resource = null); - - /** - * @param ResourceInterface|string|null $resource - * - * @return Envelope - */ - public function addDeleted($resource = null); - - /** - * @deprecated In php-flasher/flasher v2.0, the "preset()" method will be an alias of "addPreset()" method as will immediately call the `->flash()` method. Use the "addPreset()" method instead to avoid this breaking change. - * - * @param string $preset - * @param array $parameters - * - * @return static - */ - public function preset($preset, $parameters = array()); - - /** - * @deprecated In php-flasher/flasher v2.0, the "operation()" method will be an alias of "addOperation()" method as will immediately call the `->flash()` method. Use the "addOperation()" method instead to avoid this breaking change. - * - * @param string $operation - * @param ResourceInterface|string|null $resource - * - * @return static - */ - public function operation($operation, $resource = null); - - /** - * @deprecated In php-flasher/flasher v2.0, the "created()" method will be an alias of "addCreated()" method as will immediately call the `->flash()` method. Use the "addCreated()" method instead to avoid this breaking change. - * - * @param ResourceInterface|string|null $resource - * - * @return static - */ - public function created($resource = null); - - /** - * @deprecated In php-flasher/flasher v2.0, the "updated()" method will be an alias of "addUpdated()" method as will immediately call the `->flash()` method. Use the "addUpdated()" method instead to avoid this breaking change. - * - * @param ResourceInterface|string|null $resource - * - * @return static - */ - public function updated($resource = null); - - /** - * @deprecated In php-flasher/flasher v2.0, the "saved()" method will be an alias of "addSaved()" method as will immediately call the `->flash()` method. Use the "addSaved()" method instead to avoid this breaking change. - * - * @param ResourceInterface|string|null $resource - * - * @return static - */ - public function saved($resource = null); - - /** - * @deprecated In php-flasher/flasher v2.0, the "deleted()" method will be an alias of "addDeleted()" method as will immediately call the `->flash()` method. Use the "addDeleted()" method instead to avoid this breaking change. - * - * @param ResourceInterface|string|null $resource - * - * @return static - */ - public function deleted($resource = null); - - /** - * @param StampInterface[] $stamps - * - * @return Envelope - */ - public function push(array $stamps = array()); - - /** - * @deprecated Since php-flasher/flasher v1.12: Using "flash()" method is deprecated and will be removed in v2.0. please use the "push()" method instead. - * - * @param StampInterface[] $stamps - * - * @return Envelope - */ - public function flash(array $stamps = array()); - - /** - * @return Envelope - */ - public function getEnvelope(); - - /** - * @deprecated Since php-flasher/flasher v1.0: Using livewire() method is deprecated and will be removed in v2.0. please use the builder methods directly. - * @see https://php-flasher.io/docs/framework/livewire/ - * * @param array $context - * - * @return static */ - public function livewire(array $context = array()); + public function context(array $context): static; + + public function when(bool|\Closure $condition): static; + + public function unless(bool|\Closure $condition): static; + + /** + * @param StampInterface[]|StampInterface $stamps + */ + public function with(array|StampInterface $stamps): static; + + public function getEnvelope(): Envelope; + + /** + * @param array $options + */ + public function success(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function error(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function info(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function warning(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $parameters + */ + public function preset(string $preset, array $parameters = []): Envelope; + + public function operation(string $operation, string|ResourceInterface|null $resource = null): Envelope; + + public function created(string|ResourceInterface|null $resource = null): Envelope; + + public function updated(string|ResourceInterface|null $resource = null): Envelope; + + public function saved(string|ResourceInterface|null $resource = null): Envelope; + + public function deleted(string|ResourceInterface|null $resource = null): Envelope; + + public function push(): Envelope; + + /** + * @param array $options + */ + public function addSuccess(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function addError(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function addInfo(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function addWarning(string $message, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $options + */ + public function addFlash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope; + + /** + * @param array $parameters + */ + public function addPreset(string $preset, array $parameters = []): Envelope; + + public function addCreated(string|object|null $resource = null): Envelope; + + public function addUpdated(string|object|null $resource = null): Envelope; + + public function addSaved(string|object|null $resource = null): Envelope; + + public function addDeleted(string|object|null $resource = null): Envelope; + + public function addOperation(string $operation, string|object|null $resource = null): Envelope; } diff --git a/src/Prime/Notification/NotificationBuilderMethods.php b/src/Prime/Notification/NotificationBuilderMethods.php new file mode 100644 index 00000000..831e8a25 --- /dev/null +++ b/src/Prime/Notification/NotificationBuilderMethods.php @@ -0,0 +1,168 @@ +envelope->setTitle($title); + + return $this; + } + + public function message(string $message): static + { + $this->envelope->setMessage($message); + + return $this; + } + + public function type(string $type): static + { + $this->envelope->setType($type); + + return $this; + } + + public function options(array $options, bool $merge = true): static + { + if ($merge) { + $options = array_merge($this->envelope->getOptions(), $options); + } + + $this->envelope->setOptions($options); + + return $this; + } + + public function option(string $name, mixed $value): static + { + $this->envelope->setOption($name, $value); + + return $this; + } + + public function priority(int $priority): static + { + $this->envelope->withStamp(new PriorityStamp($priority)); + + return $this; + } + + public function keep(): static + { + $stamp = $this->envelope->get(HopsStamp::class); + $amount = $stamp?->getAmount() ?: 1; + + return $this->hops(1 + $amount); + } + + public function hops(int $amount): static + { + $this->envelope->withStamp(new HopsStamp($amount)); + + return $this; + } + + public function delay(int $delay): static + { + $this->envelope->withStamp(new DelayStamp($delay)); + + return $this; + } + + public function translate(array $parameters = [], ?string $locale = null): static + { + $this->envelope->withStamp(new TranslationStamp($parameters, $locale)); + + return $this; + } + + public function handler(string $handler): static + { + $this->envelope->withStamp(new PluginStamp($handler)); + + return $this; + } + + public function context(array $context): static + { + $this->envelope->withStamp(new ContextStamp($context)); + + return $this; + } + + public function when(bool|\Closure $condition): static + { + $condition = $this->validateCallableCondition($condition); + + $stamp = $this->envelope->get(WhenStamp::class); + if ($stamp instanceof WhenStamp) { + $condition = $stamp->getCondition() && $condition; + } + + $this->envelope->withStamp(new WhenStamp($condition)); + + return $this; + } + + public function unless(bool|\Closure $condition): static + { + $condition = $this->validateCallableCondition($condition); + + $stamp = $this->envelope->get(UnlessStamp::class); + if ($stamp instanceof UnlessStamp) { + $condition = $stamp->getCondition() || $condition; + } + + $this->envelope->withStamp(new UnlessStamp($condition)); + + return $this; + } + + public function with(array|StampInterface $stamps): static + { + if ($stamps instanceof StampInterface) { + $stamps = [$stamps]; + } + + $this->envelope->with(...$stamps); + + return $this; + } + + public function getEnvelope(): Envelope + { + return $this->envelope; + } + + protected function validateCallableCondition(bool|\Closure $condition): bool + { + if ($condition instanceof \Closure) { + $condition = $condition($this->envelope); + } + + if (!\is_bool($condition)) { + $type = \gettype($condition); + + throw new \InvalidArgumentException(sprintf('The condition must be a boolean or a closure that returns a boolean. Got: %s', $type)); + } + + return $condition; + } +} diff --git a/src/Prime/Notification/NotificationInterface.php b/src/Prime/Notification/NotificationInterface.php index 9ef9c72b..9fa1fa58 100644 --- a/src/Prime/Notification/NotificationInterface.php +++ b/src/Prime/Notification/NotificationInterface.php @@ -1,92 +1,46 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Notification; interface NotificationInterface { - const SUCCESS = 'success'; - const ERROR = 'error'; - const INFO = 'info'; - const WARNING = 'warning'; + public function getTitle(): string; - /** - * @return string|null - */ - public function getType(); + public function setTitle(string $title): void; - /** - * @param string|null $type - * - * @return static - */ - public function setType($type); + public function getMessage(): string; - /** - * @return string|null - */ - public function getMessage(); + public function setMessage(string $message): void; - /** - * @param string|null $message - * - * @return static - */ - public function setMessage($message); + public function getType(): string; - /** - * @return string|null - */ - public function getTitle(); - - /** - * @param string|null $title - * - * @return static - */ - public function setTitle($title); + public function setType(string $type): void; /** * @return array */ - public function getOptions(); + public function getOptions(): array; /** * @param array $options - * - * @return static */ - public function setOptions(array $options); + public function setOptions(array $options): void; + + public function getOption(string $name, mixed $default = null): mixed; + + public function setOption(string $name, mixed $value): void; + + public function unsetOption(string $name): void; /** - * @param string $name - * @param mixed $default - * - * @return mixed + * @return array{ + * title: string, + * message: string, + * type: string, + * options: array, + * } */ - public function getOption($name, $default = null); - - /** - * @param string $name - * @param mixed $value - * - * @return static - */ - public function setOption($name, $value); - - /** - * @param string $name - * - * @return static - */ - public function unsetOption($name); - - /** - * @return array - */ - public function toArray(); + public function toArray(): array; } diff --git a/src/Prime/Notification/NotificationMethodAliases.php b/src/Prime/Notification/NotificationMethodAliases.php new file mode 100644 index 00000000..7dedac44 --- /dev/null +++ b/src/Prime/Notification/NotificationMethodAliases.php @@ -0,0 +1,63 @@ +success($message, $options, $title); + } + + public function addError(string $message, array $options = [], ?string $title = null): Envelope + { + return $this->error($message, $options, $title); + } + + public function addInfo(string $message, array $options = [], ?string $title = null): Envelope + { + return $this->info($message, $options, $title); + } + + public function addWarning(string $message, array $options = [], ?string $title = null): Envelope + { + return $this->warning($message, $options, $title); + } + + public function addFlash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope + { + return $this->flash($type, $message, $options, $title); + } + + public function addPreset(string $preset, array $parameters = []): Envelope + { + return $this->preset($preset, $parameters); + } + + public function addCreated(string|object|null $resource = null): Envelope + { + return $this->created($resource); + } + + public function addUpdated(string|object|null $resource = null): Envelope + { + return $this->updated($resource); + } + + public function addSaved(string|object|null $resource = null): Envelope + { + return $this->saved($resource); + } + + public function addDeleted(string|object|null $resource = null): Envelope + { + return $this->deleted($resource); + } + + public function addOperation(string $operation, string|object|null $resource = null): Envelope + { + return $this->operation($operation, $resource); + } +} diff --git a/src/Prime/Notification/NotificationStorageMethods.php b/src/Prime/Notification/NotificationStorageMethods.php new file mode 100644 index 00000000..a3e38daa --- /dev/null +++ b/src/Prime/Notification/NotificationStorageMethods.php @@ -0,0 +1,111 @@ +flash(Type::SUCCESS, $message, $options, $title); + } + + public function error(string $message, array $options = [], ?string $title = null): Envelope + { + return $this->flash(Type::ERROR, $message, $options, $title); + } + + public function info(string $message, array $options = [], ?string $title = null): Envelope + { + return $this->flash(Type::INFO, $message, $options, $title); + } + + public function warning(string $message, array $options = [], ?string $title = null): Envelope + { + return $this->flash(Type::WARNING, $message, $options, $title); + } + + public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope + { + if (null !== $type) { + $this->type($type); + } + + if (null !== $message) { + $this->message($message); + } + + if ([] !== $options) { + $this->options($options); + } + + if (null !== $title) { + $this->title($title); + } + + return $this->push(); + } + + public function preset(string $preset, array $parameters = []): Envelope + { + $this->envelope->withStamp(new PresetStamp($preset, $parameters)); + + return $this->push(); + } + + public function created(string|object|null $resource = null): Envelope + { + return $this->operation('created', $resource); + } + + public function updated(string|object|null $resource = null): Envelope + { + return $this->operation('updated', $resource); + } + + public function saved(string|object|null $resource = null): Envelope + { + return $this->operation('saved', $resource); + } + + public function deleted(string|object|null $resource = null): Envelope + { + return $this->operation('deleted', $resource); + } + + public function operation(string $operation, string|object|null $resource = null): Envelope + { + if ($resource instanceof ResourceInterface) { + $type = $resource->getResourceType(); + $name = $resource->getResourceName(); + + $resource = sprintf( + '%s %s', + $type, + '' === $name ? '' : sprintf('"%s"', $name) + ); + } + + $parameters = [ + 'resource' => $resource ?: 'resource', + ]; + + return $this->preset($operation, $parameters); + } + + public function push(): Envelope + { + $envelope = $this->getEnvelope(); + + $this->storageManager->add($envelope); + + return $envelope; + } +} diff --git a/src/Prime/Notification/Type.php b/src/Prime/Notification/Type.php new file mode 100644 index 00000000..cd251abb --- /dev/null +++ b/src/Prime/Notification/Type.php @@ -0,0 +1,16 @@ + [FlasherInterface::class, NotificationFactoryInterface::class], + 'noty' => NotyInterface::class, + 'notyf' => NotyfInterface::class, + 'sweetalert' => SweetAlertInterface::class, + 'toastr' => ToastrInterface::class, + ]; + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return \array_key_exists($functionReflection->getName(), self::MAPPING); + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): ?Type + { + if (\count($functionCall->getArgs())) { + return new ObjectType(Envelope::class); + } + + $types = self::MAPPING[$functionReflection->getName()]; + + if (\is_array($types)) { + return TypeCombinator::union(...array_map(fn ($type) => new ObjectType($type), $types)); + } + + return new ObjectType($types); + } +} diff --git a/src/Prime/Phpstan/ReturnTypes/FlasherContainerDynamicStaticMethodReturnTypeExtension.php b/src/Prime/Phpstan/ReturnTypes/FlasherContainerDynamicStaticMethodReturnTypeExtension.php new file mode 100644 index 00000000..7f4332e8 --- /dev/null +++ b/src/Prime/Phpstan/ReturnTypes/FlasherContainerDynamicStaticMethodReturnTypeExtension.php @@ -0,0 +1,53 @@ + FlasherInterface::class, + 'flasher.noty' => NotyInterface::class, + 'flasher.notyf' => NotyfInterface::class, + 'flasher.sweetalert' => SweetAlertInterface::class, + 'flasher.toastr' => ToastrInterface::class, + ]; + + public function getClass(): string + { + return FlasherContainer::class; + } + + public function isStaticMethodSupported(MethodReflection $methodReflection): bool + { + return 'create' === $methodReflection->getName(); + } + + public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope): ?Type + { + $args = $methodCall->getArgs(); + $type = $scope->getType($args[0]->value); + + foreach ($type->getConstantStrings() as $service) { + $factory = $service->getValue(); + + return isset(self::MAPPING[$factory]) ? new ObjectType(self::MAPPING[$factory]) : null; + } + + return null; + } +} diff --git a/src/Prime/Plugin/FlasherPlugin.php b/src/Prime/Plugin/FlasherPlugin.php index 330ab8f3..70627437 100644 --- a/src/Prime/Plugin/FlasherPlugin.php +++ b/src/Prime/Plugin/FlasherPlugin.php @@ -1,289 +1,317 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Plugin; -use Flasher\Prime\Config\ConfigInterface; -use Flasher\Prime\Notification\NotificationInterface; +use Flasher\Prime\Factory\NotificationFactory; +use Flasher\Prime\FlasherInterface; +use Flasher\Prime\Notification\Type; /** - * @phpstan-import-type ConfigType from ConfigInterface + * @phpstan-type ConfigType array{ + * default: string, + * main_script: string, + * translate: bool, + * inject_assets: bool, + * scripts: string[], + * styles: string[], + * options: array, + * filter: array, + * flash_bag: false|array, + * presets: array, + * }>, + * plugins: array, + * }>, + * } */ final class FlasherPlugin extends Plugin { - /** - * {@inheritdoc} - */ - public function getName() + public function getAlias(): string { return 'flasher'; } - /** - * {@inheritdoc} - */ - public function getServiceID() + public function getName(): string { return 'flasher'; } - /** - * @return string - */ - public function getDefault() + public function getServiceId(): string { return 'flasher'; } - /** - * @return string|array{cdn: string, local: string} - */ - public function getRootScript() + public function getFactory(): string { - return array( - 'cdn' => 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.js', - 'local' => '/vendor/flasher/flasher.min.js', - ); + return NotificationFactory::class; } - public function getScripts() + public function getServiceAliases(): string { - $rootScript = $this->getRootScript(); - - return array( - 'cdn' => is_string($rootScript) ? array($rootScript) : array($rootScript['cdn']), - 'local' => is_string($rootScript) ? '' : array($rootScript['local']), - ); + return FlasherInterface::class; } - /** - * {@inheritDoc} - */ - public function getStyles() + public function getDefault(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher.min.css', - ), - ); + return 'flasher'; } - /** - * @return string - */ - public function getResourcesDir() + public function getRootScript(): string { - return realpath(__DIR__.'/../Resources') ?: ''; + return '/vendor/flasher/flasher.min.js'; } - /** - * @return array - */ - public function getFlashBagMapping() + public function getScripts(): string|array { - return array( - 'success' => array('success'), - 'error' => array('error', 'danger'), - 'warning' => array('warning', 'alarm'), - 'info' => array('info', 'notice', 'alert'), - ); + return []; } - /** - * {@inheritdoc} - */ - public function processConfiguration(array $options = array()) + public function getStyles(): string { - $options = $this->normalizeConfig($options); // @phpstan-ignore-line + return '/vendor/flasher/flasher.min.css'; + } - return array_merge(array( - 'default' => $this->getDefault(), - 'root_script' => $this->getRootScript(), - 'scripts' => array(), - 'styles' => $this->getStyles(), - 'options' => array(), - 'use_cdn' => true, - 'auto_translate' => true, - 'auto_render' => true, - 'flash_bag' => array( - 'enabled' => true, - 'mapping' => $this->getFlashBagMapping(), - ), - 'filter_criteria' => array(), - ), $options); + public function normalizeConfig(array $config = []): array + { + $config = parent::normalizeConfig($config); + + $config = $this->normalizePlugins($config); + $config = $this->normalizePresets($config); + $config = $this->addDefaultConfig($config); + $config = $this->normalizeFlashBag($config); + $config = $this->setPresetsDefaults($config); + + return $config; } /** * @param array{ - * root_script?: string|array, - * styles?: string|array, - * scripts ?: string|array, - * template_factory?: array{default: string, templates: array>}, - * auto_create_from_session?: bool, - * auto_render?: bool, - * types_mapping?: array, - * observer_events?: array, - * translate_by_default?: bool, - * presets?: array, - * }>, + * scripts: string[], + * styles: string[], + * options: array, + * plugins?: array>, * } $config * - * @phpstan-return ConfigType + * @return array{ + * scripts: string[], + * styles: string[], + * options: array, + * plugins: array, + * } */ - public function normalizeConfig(array $config) + private function normalizePlugins(array $config): array { - if (isset($config['root_script']) && is_string($config['root_script'])) { - $config['root_script'] = array( - 'local' => $config['root_script'], - 'cdn' => $config['root_script'], - ); + if (!isset($config['plugins']['flasher'])) { + $config['plugins']['flasher'] = [ + 'scripts' => [], + 'styles' => [], + 'options' => [], + ]; } - if (isset($config['styles'])) { - if (is_string($config['styles'])) { - $config['styles'] = array('cdn' => $config['styles'], 'local' => $config['styles']); + if (!empty($config['scripts'])) { + $config['plugins']['flasher']['scripts'] ??= []; + $config['plugins']['flasher']['scripts'] += $config['scripts']; + } + + if (!empty($config['styles'])) { + $config['plugins']['flasher']['styles'] ??= []; + $config['plugins']['flasher']['styles'] += $config['styles']; + } + + if (!empty($config['options'])) { + $config['plugins']['flasher']['options'] ??= []; + $config['plugins']['flasher']['options'] += $config['options']; + } + + foreach ($config['plugins'] as $name => $options) { + if (isset($options['scripts'])) { + $config['plugins'][$name]['scripts'] = (array) $options['scripts']; } - $config['styles'] = array_merge(array('cdn' => array(), 'local' => array()), $config['styles']); - - $config['styles']['cdn'] = (array) $config['styles']['cdn']; - $config['styles']['local'] = (array) $config['styles']['local']; + if (isset($options['styles'])) { + $config['plugins'][$name]['styles'] = (array) $options['styles']; + } } - if (isset($config['scripts'])) { - if (is_string($config['scripts'])) { - $config['scripts'] = array('cdn' => $config['scripts'], 'local' => $config['scripts']); + return $config; + } + + /** + * @param array{ + * scripts: string[], + * styles: string[], + * options: array, + * presets?: array>, + * plugins: array, + * } $config + * + * @return array{ + * scripts: string[], + * styles: string[], + * options: array, + * presets?: array>, + * plugins: array, + * } + */ + private function normalizePresets(array $config): array + { + foreach ($config['presets'] ?? [] as $name => $options) { + if (\is_string($options)) { + $options = ['message' => $options]; } - $config['scripts'] = array_merge(array('cdn' => array(), 'local' => array()), $config['scripts']); - - $config['scripts']['cdn'] = (array) $config['scripts']['cdn']; - $config['scripts']['local'] = (array) $config['scripts']['local']; + $config['presets'][$name] = $options; } - $deprecatedKeys = array(); - - if (isset($config['template_factory']['default'])) { - $deprecatedKeys[] = 'template_factory.default'; - unset($config['template_factory']['default']); - } - - if (isset($config['template_factory']['templates'])) { - $deprecatedKeys[] = 'template_factory.templates'; - $config['themes'] = $config['template_factory']['templates']; - unset($config['template_factory']['templates']); - } - - unset($config['template_factory']); - - if (isset($config['themes']['flasher']['options'])) { - $deprecatedKeys[] = 'themes.flasher.options'; - $config['options'] = $config['themes']['flasher']['options']; - unset($config['themes']['flasher']['options']); - } - - if (isset($config['auto_create_from_session'])) { - $deprecatedKeys[] = 'auto_create_from_session'; - $config['flash_bag']['enabled'] = $config['auto_create_from_session']; - unset($config['auto_create_from_session']); - } - - if (isset($config['types_mapping'])) { - $deprecatedKeys[] = 'types_mapping'; - $config['flash_bag']['mapping'] = $config['types_mapping']; - unset($config['types_mapping']); - } - - if (isset($config['observer_events'])) { - $deprecatedKeys[] = 'observer_events'; - unset($config['observer_events']); - } - - if (isset($config['translate_by_default'])) { - $deprecatedKeys[] = 'translate_by_default'; - $config['auto_translate'] = $config['translate_by_default']; - unset($config['translate_by_default']); - } - - if (array() !== $deprecatedKeys) { - @trigger_error(sprintf('Since php-flasher/flasher-laravel v1.0: The following configuration keys are deprecated and will be removed in v2.0: %s. Please use the new configuration structure.', implode(', ', $deprecatedKeys)), \E_USER_DEPRECATED); - } - - if (\array_key_exists('flash_bag', $config)) { - $config['flash_bag'] = $this->normalizeFlashBagConfig($config['flash_bag']); - } - - $config['presets'] = array_merge(array( - 'created' => array( - 'type' => NotificationInterface::SUCCESS, - 'message' => 'The resource was created', - ), - 'updated' => array( - 'type' => NotificationInterface::SUCCESS, - 'message' => 'The resource was updated', - ), - 'saved' => array( - 'type' => NotificationInterface::SUCCESS, - 'message' => 'The resource was saved', - ), - 'deleted' => array( - 'type' => NotificationInterface::SUCCESS, - 'message' => 'The resource was deleted', - ), - ), isset($config['presets']) ? $config['presets'] : array()); - return $config; // @phpstan-ignore-line } /** - * @param mixed $config + * @param array{ + * default?: string|null, + * main_script?: string|null, + * translate?: bool, + * inject_assets?: bool, + * filter?: array, + * scripts: string[], + * styles: string[], + * options: array, + * presets?: array>, + * plugins: array, + * } $config * - * @return array + * @return array{ + * default: string|null, + * main_script: string|null, + * translate: bool, + * inject_assets: bool, + * filter: array, + * scripts: string[], + * styles: string[], + * options: array, + * presets: array>, + * plugins: array, + * } */ - private function normalizeFlashBagConfig($config) + private function addDefaultConfig(array $config): array { - if (null === $config || false === $config) { - return array('enabled' => false); + $defaultPresets = [ + 'created' => ['type' => Type::SUCCESS, 'message' => 'The resource was created'], + 'updated' => ['type' => Type::SUCCESS, 'message' => 'The resource was updated'], + 'saved' => ['type' => Type::SUCCESS, 'message' => 'The resource was saved'], + 'deleted' => ['type' => Type::SUCCESS, 'message' => 'The resource was deleted'], + ]; + + $config['default'] = \array_key_exists('default', $config) ? $config['default'] : $this->getDefault(); + $config['main_script'] = \array_key_exists('main_script', $config) ? $config['main_script'] : $this->getRootScript(); + $config['translate'] = \array_key_exists('translate', $config) ? $config['translate'] : true; + $config['inject_assets'] = \array_key_exists('inject_assets', $config) ? $config['inject_assets'] : true; + $config['filter'] = \array_key_exists('filter', $config) ? $config['filter'] : []; + $config['presets'] = \array_key_exists('presets', $config) ? $config['presets'] : $defaultPresets; + + return $config; + } + + /** + * @param array{ + * default: string|null, + * main_script: string|null, + * translate: bool, + * inject_assets: bool, + * filter: array, + * scripts: string[], + * styles: string[], + * options: array, + * presets: array>, + * plugins: array, + * flash_bag?: bool|array, + * } $config + * + * @return array{ + * default: string|null, + * main_script: string|null, + * translate: bool, + * inject_assets: bool, + * filter: array, + * scripts: string[], + * styles: string[], + * options: array, + * presets: array>, + * plugins: array, + * flash_bag: false|array, + * } + */ + private function normalizeFlashBag(array $config): array + { + $mapping = [ + 'success' => ['success'], + 'error' => ['error', 'danger'], + 'warning' => ['warning', 'alarm'], + 'info' => ['info', 'notice', 'alert'], + ]; + + if (!\array_key_exists('flash_bag', $config) || true === $config['flash_bag']) { + $config['flash_bag'] = $mapping; } - if (!\is_array($config) || !\array_key_exists('mapping', $config) || !\is_array($config['mapping'])) { - return array('enabled' => true); + if (false === $config['flash_bag']) { + return $config; } - $mapping = $config['mapping']; - - foreach ($mapping as $key => $values) { - if (!\is_string($key)) { - continue; - } - - if (!\is_array($values)) { - $mapping[$key] = array($values); - } - - foreach ($mapping[$key] as $index => $value) { - if (!\is_string($value)) { - unset($mapping[$key][$index]); - } - } - - $mapping[$key] = array_values($mapping[$key]); + foreach ($config['flash_bag'] as $key => $value) { + $config['flash_bag'][$key] = array_values(array_unique(array_merge($mapping[$key] ?? [], (array) $value))); } - return array( - 'enabled' => true, - 'mapping' => $mapping, - ); + $config['flash_bag'] += $mapping; + + return $config; + } + + /** + * @param array{ + * default: string|null, + * main_script: string|null, + * translate: bool, + * inject_assets: bool, + * filter: array, + * scripts: string[], + * styles: string[], + * options: array, + * presets: array>, + * plugins: array, + * flash_bag: false|array, + * } $config + * + * @return array{ + * default: string|null, + * main_script: string|null, + * translate: bool, + * inject_assets: bool, + * filter: array, + * scripts: string[], + * styles: string[], + * options: array, + * presets: array>, + * plugins: array, + * flash_bag: false|array, + * } + */ + private function setPresetsDefaults(array $config): array + { + foreach ($config['presets'] as $name => $options) { + $config['presets'][$name]['type'] ??= Type::INFO; + $config['presets'][$name]['options'] ??= []; + } + + return $config; } } diff --git a/src/Prime/Plugin/Plugin.php b/src/Prime/Plugin/Plugin.php index 0a4ff2d6..16c12942 100644 --- a/src/Prime/Plugin/Plugin.php +++ b/src/Prime/Plugin/Plugin.php @@ -1,158 +1,72 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Plugin; abstract class Plugin implements PluginInterface { - /** - * {@inheritdoc} - */ - public function getAlias() - { - $alias = basename(str_replace('\\', '/', \get_class($this))); - $alias = str_replace('Plugin', '', $alias); - /** @var string $alias */ - $alias = preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $alias); - - return strtolower($alias); - } - - /** - * {@inheritdoc} - */ - public function getName() + public function getName(): string { return 'flasher_'.$this->getAlias(); } - /** - * {@inheritdoc} - */ - public function getServiceID() + public function getServiceId(): string { return 'flasher.'.$this->getAlias(); } - /** - * {@inheritdoc} - */ - public function getFactory() + public function getServiceAliases(): string|array { - return str_replace('Plugin', 'Factory', \get_class($this)); // @phpstan-ignore-line + return []; } - /** - * {@inheritdoc} - */ - public function getScripts() + public function getScripts(): string|array { - return array(); + return []; } - /** - * {@inheritdoc} - */ - public function getStyles() + public function getStyles(): string|array { - return array(); + return []; } - /** - * {@inheritdoc} - */ - public function getOptions() + public function getOptions(): array { - return array(); + return []; } - /** - * @return string - */ - public function getAssetsDir() + public function getAssetsDir(): string { $resourcesDir = $this->getResourcesDir(); - $assetsDir = rtrim($resourcesDir, '/').'/assets/'; + $assetsDir = rtrim($resourcesDir, '/').'/public/'; return realpath($assetsDir) ?: ''; } - /** - * @return string - */ - public function getResourcesDir() + public function getResourcesDir(): string { - $r = new \ReflectionClass($this); - $fileName = pathinfo($r->getFileName() ?: '', PATHINFO_DIRNAME).'/Resources/'; + $reflection = new \ReflectionClass($this); + $pluginDir = pathinfo($reflection->getFileName() ?: '', \PATHINFO_DIRNAME); + $resourcesDir = is_dir($pluginDir.'/Resources/') + ? $pluginDir.'/Resources/' + : $pluginDir.'/../Resources/'; - return realpath($fileName) ?: ''; + return realpath($resourcesDir) ?: ''; } - /** - * @param array{ - * scripts?: string|string[]|array{cdn?: string|string[], local?: string|string[]}, - * styles?: string|string[]|array{cdn?: string|string[], local?: string|string[]}, - * options?: array, - * } $config - * - * @return array{ - * scripts: array{cdn: string[], local: string[]}, - * styles: array{cdn: string[], local: string[]}, - * options: array, - * } - */ - public function normalizeConfig(array $config) + public function normalizeConfig(array $config): array { - $config = $this->processConfiguration($config); - - $config['styles'] = $this->normalizeAssets($config['styles']); - $config['scripts'] = $this->normalizeAssets($config['scripts']); - - return $config; - } - - /** - * @param array{ - * scripts?: string|string[]|array{cdn?: string|string[], local?: string|string[]}, - * styles?: string|string[]|array{cdn?: string|string[], local?: string|string[]}, - * options?: array, - * } $options - * - * @return array{ - * scripts: string|string[]|array{cdn?: string|string[], local?: string|string[]}, - * styles: string|string[]|array{cdn?: string|string[], local?: string|string[]}, - * options: array, - * } - */ - public function processConfiguration(array $options = array()) - { - return array_merge(array( + $config = [ 'scripts' => $this->getScripts(), 'styles' => $this->getStyles(), 'options' => $this->getOptions(), - ), $options); - } + ...$config, + ]; - /** - * @param string|array{cdn?: string|string[], local?: string|string[]} $assets - * - * @return array{cdn: string[], local: string[]} - */ - protected function normalizeAssets($assets = array()) - { - if (is_string($assets)) { - $assets = array('cdn' => $assets, 'local' => $assets); - } + $config['styles'] = (array) $config['styles']; + $config['scripts'] = (array) $config['scripts']; - $assets = array_merge(array('cdn' => null, 'local' => null), $assets); - - $assets['cdn'] = (array) $assets['cdn']; - $assets['local'] = (array) $assets['local']; - - return $assets; + return $config; } } diff --git a/src/Prime/Plugin/PluginInterface.php b/src/Prime/Plugin/PluginInterface.php index 1f021316..0cc9f383 100644 --- a/src/Prime/Plugin/PluginInterface.php +++ b/src/Prime/Plugin/PluginInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Plugin; @@ -11,70 +8,53 @@ use Flasher\Prime\Factory\NotificationFactoryInterface; interface PluginInterface { - /** - * @return string - */ - public function getAlias(); + public function getAlias(): string; - /** - * @return string - */ - public function getName(); + public function getName(): string; - /** - * @return string - */ - public function getServiceID(); + public function getServiceId(): string; /** * @return class-string */ - public function getFactory(); + public function getFactory(): string; /** - * @return string|string[]|array{cdn?: string|string[], local?: string|string[]} + * @return string|string[] */ - public function getScripts(); + public function getServiceAliases(): string|array; /** - * @return string|string[]|array{cdn?: string|string[], local?: string|string[]} + * @return string|string[] */ - public function getStyles(); + public function getScripts(): string|array; + + /** + * @return string|string[] + */ + public function getStyles(): string|array; /** * @return array */ - public function getOptions(); + public function getOptions(): array; + + public function getAssetsDir(): string; + + public function getResourcesDir(): string; /** - * @return string - */ - public function getAssetsDir(); - - /** - * @return string - */ - public function getResourcesDir(); - - /** - * @phpstan-param array{ - * scripts?: string|array, - * styles?: string|array, - * options?: array, + * @param array{ + * scripts?: string|string[], + * styles?: string|string[], + * options?: array, * } $config * - * @phpstan-return array{ - * scripts?: array, - * styles?: array, - * options?: array, + * @return array{ + * scripts: string[], + * styles: string[], + * options: array, * } */ - public function normalizeConfig(array $config); - - /** - * @param array $options - * - * @return array - */ - public function processConfiguration(array $options = array()); + public function normalizeConfig(array $config): array; } diff --git a/src/Prime/README.md b/src/Prime/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Prime/README.md +++ b/src/Prime/README.md @@ -36,7 +36,7 @@ Shining stars of our community: - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/Prime/Resources/assets/flasher-plugin.ts b/src/Prime/Resources/assets/flasher-plugin.ts new file mode 100644 index 00000000..e6a085f0 --- /dev/null +++ b/src/Prime/Resources/assets/flasher-plugin.ts @@ -0,0 +1,129 @@ +import './themes/index.scss' + +import type { Properties } from 'csstype' +import type { Envelope, Options, Theme } from './types' +import { AbstractPlugin } from './plugin' + +export default class FlasherPlugin extends AbstractPlugin { + private theme: Theme + private options = { + timeout: 5000, + timeouts: { + success: 5000, + info: 5000, + error: 5000, + warning: 5000, + }, + fps: 30, + position: 'top-right', + direction: 'top', + rtl: false, + style: {} as Properties, + } + + constructor(theme: Theme) { + super() + + this.theme = theme + } + + public renderEnvelopes(envelopes: Envelope[]): void { + const render = () => + envelopes.forEach((envelope) => { + // @ts-expect-error + const typeTimeout = this.options.timeouts[envelope.type] ?? this.options.timeout + const options = { + ...this.options, + ...envelope.options, + timeout: envelope.options.timeout ?? typeTimeout, + } + + this.addToContainer(this.createContainer(options), envelope, options) + }) + + document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render() + } + + public renderOptions(options: Options): void { + this.options = { ...this.options, ...options } + } + + private createContainer(options: { position: string, style: Properties }): HTMLDivElement { + let container = document.querySelector(`.fl-wrapper[data-position="${options.position}"]`) as HTMLDivElement + + if (!container) { + container = document.createElement('div') + container.className = 'fl-wrapper' + container.dataset.position = options.position + Object.entries(options.style).forEach(([key, value]) => container.style.setProperty(key, value)) + document.body.appendChild(container) + } + + container.dataset.turboCache = 'false' + + return container + } + + private addToContainer(container: HTMLDivElement, envelope: Envelope, options: { direction: string, timeout: number, fps: number, rtl: boolean }): void { + const notification = this.stringToHTML(this.theme.render(envelope)) + + notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' ')) + options.direction === 'bottom' ? container.append(notification) : container.prepend(notification) + + requestAnimationFrame(() => notification.classList.add('fl-show')) + + notification.querySelector('.fl-close')?.addEventListener('click', (event) => { + event.stopPropagation() + this.removeNotification(notification) + }) + + this.addProgressBar(notification, options) + } + + addProgressBar(notification: HTMLElement, { timeout, fps }: { timeout: number, fps: number }) { + if (timeout <= 0 || fps <= 0) { + return + } + + const progressBarContainer = notification.querySelector('.fl-progress-bar') + if (!progressBarContainer) { + return + } + + const progressBar = document.createElement('span') + progressBar.classList.add('fl-progress') + progressBarContainer.append(progressBar) + + const lapse = 1000 / fps + let width = 0 + const updateProgress = () => { + width += 1 + const percent = (1 - lapse * (width / timeout)) * 100 + progressBar.style.width = `${percent}%` + + if (percent <= 0) { + // eslint-disable-next-line ts/no-use-before-define + clearInterval(intervalId) + this.removeNotification(notification) + } + } + + let intervalId: number = window.setInterval(updateProgress, lapse) + notification.addEventListener('mouseout', () => intervalId = window.setInterval(updateProgress, lapse)) + notification.addEventListener('mouseover', () => clearInterval(intervalId)) + } + + private removeNotification(notification: HTMLElement) { + notification.classList.remove('fl-show') + notification.ontransitionend = () => { + !notification.parentElement?.hasChildNodes() && notification.parentElement?.remove() + notification.remove() + } + } + + private stringToHTML(str: string): HTMLElement { + const template = document.createElement('template') + template.innerHTML = str.trim() + return template.content.firstElementChild as HTMLElement + } +} diff --git a/src/Prime/Resources/assets/flasher.min.css b/src/Prime/Resources/assets/flasher.min.css deleted file mode 100644 index fb37c884..00000000 --- a/src/Prime/Resources/assets/flasher.min.css +++ /dev/null @@ -1 +0,0 @@ -.fl-main-container{position:fixed;transition:all 1s ease-in-out;width:24em;z-index:99999}@media only screen and (max-width:480px){.fl-main-container{left:.5em;right:.5em;width:auto}}.fl-main-container[data-position^=top-]{top:.5em}.fl-main-container[data-position^=bottom-]{bottom:.5em}.fl-main-container[data-position$=-right]{right:.5em}.fl-main-container[data-position$=-right] .fl-container{transform:translateX(110%)}.fl-main-container[data-position$=-left]{left:.5em}.fl-main-container[data-position$=-left] .fl-container{transform:translateX(-110%)}.fl-main-container[data-position$=-center]{left:50%;transform:translateX(-50%)}.fl-main-container[data-position=top-center] .fl-container{transform:translateY(-100vh)}.fl-main-container[data-position=bottom-center] .fl-container{transform:translateY(100vh)}.fl-main-container .fl-container{transition:transform .3s ease-in-out}.fl-main-container .fl-container.fl-show{transform:translate(0)}.fl-main-container .fl-container .fl-progress-bar{display:flex;height:.125em;margin-left:-1px}.fl-main-container .fl-container.fl-rtl{direction:rtl}.fl-main-container .fl-container.fl-rtl .fl-progress-bar{margin-left:auto;margin-right:-1px}.fl-main-container .fl-container.fl-success .fl-icon{background-color:#059669}.fl-main-container .fl-container.fl-success .fl-progress-bar{background-color:#6dface}.fl-main-container .fl-container.fl-success .fl-progress-bar .fl-progress{background-color:#059669}.fl-main-container .fl-container.fl-flasher.fl-success{border-left:.8em solid #059669}.fl-main-container .fl-container.fl-flasher.fl-success.fl-rtl{border-left:none;border-right:.8em solid #059669}.fl-main-container .fl-container.fl-flasher.fl-success:not(.fl-rtl){border-left:.8em solid #059669;border-right:none}.fl-main-container .fl-container.fl-flasher.fl-success .fl-title{color:#059669}.fl-main-container .fl-container.fl-info .fl-icon{background-color:#2563eb}.fl-main-container .fl-container.fl-info .fl-progress-bar{background-color:#e0e9fc}.fl-main-container .fl-container.fl-info .fl-progress-bar .fl-progress{background-color:#2563eb}.fl-main-container .fl-container.fl-flasher.fl-info{border-left:.8em solid #2563eb}.fl-main-container .fl-container.fl-flasher.fl-info.fl-rtl{border-left:none;border-right:.8em solid #2563eb}.fl-main-container .fl-container.fl-flasher.fl-info:not(.fl-rtl){border-left:.8em solid #2563eb;border-right:none}.fl-main-container .fl-container.fl-flasher.fl-info .fl-title{color:#2563eb}.fl-main-container .fl-container.fl-warning .fl-icon{background-color:#d97706}.fl-main-container .fl-container.fl-warning .fl-progress-bar{background-color:#fdd8ae}.fl-main-container .fl-container.fl-warning .fl-progress-bar .fl-progress{background-color:#d97706}.fl-main-container .fl-container.fl-flasher.fl-warning{border-left:.8em solid #d97706}.fl-main-container .fl-container.fl-flasher.fl-warning.fl-rtl{border-left:none;border-right:.8em solid #d97706}.fl-main-container .fl-container.fl-flasher.fl-warning:not(.fl-rtl){border-left:.8em solid #d97706;border-right:none}.fl-main-container .fl-container.fl-flasher.fl-warning .fl-title{color:#d97706}.fl-main-container .fl-container.fl-error .fl-icon{background-color:#dc2626}.fl-main-container .fl-container.fl-error .fl-progress-bar{background-color:#f8d6d6}.fl-main-container .fl-container.fl-error .fl-progress-bar .fl-progress{background-color:#dc2626}.fl-main-container .fl-container.fl-flasher.fl-error{border-left:.8em solid #dc2626}.fl-main-container .fl-container.fl-flasher.fl-error.fl-rtl{border-left:none;border-right:.8em solid #dc2626}.fl-main-container .fl-container.fl-flasher.fl-error:not(.fl-rtl){border-left:.8em solid #dc2626;border-right:none}.fl-main-container .fl-container.fl-flasher.fl-error .fl-title{color:#dc2626}.fl-main-container .fl-container .fl-icon{border-radius:50%;box-sizing:border-box;color:#fff;display:inline-block;height:1em;margin:0;min-height:1em;min-width:1em;position:relative;transition:all 1s;width:1em}.fl-main-container .fl-container .fl-icon:after,.fl-main-container .fl-container .fl-icon:before{border-width:0;box-sizing:border-box;content:"";position:absolute;transition:all 1s}.fl-main-container .fl-container.fl-success .fl-icon:after,.fl-main-container .fl-container.fl-success .fl-icon:before{background-color:currentColor;border-radius:.1em;height:.6em;left:.35em;top:.6em;transform:rotate(-135deg);transform-origin:.08em .08em;width:.16em}.fl-main-container .fl-container.fl-success .fl-icon:after{height:.16em;width:.4em}.fl-main-container .fl-container.fl-info .fl-icon:after,.fl-main-container .fl-container.fl-info .fl-icon:before{background-color:currentColor;border-radius:.03em;left:50%;transform:translateX(-50%);width:.15em}.fl-main-container .fl-container.fl-info .fl-icon:before{height:.38em;top:.4em}.fl-main-container .fl-container.fl-info .fl-icon:after{box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.fl-main-container .fl-container.fl-warning .fl-icon:after,.fl-main-container .fl-container.fl-warning .fl-icon:before{background-color:currentColor;border-radius:.03em;left:50%;transform:translateX(-50%);width:.15em}.fl-main-container .fl-container.fl-warning .fl-icon:before{height:.38em;top:.21em}.fl-main-container .fl-container.fl-warning .fl-icon:after{height:.13em;top:.65em}.fl-main-container .fl-container.fl-error .fl-icon:after,.fl-main-container .fl-container.fl-error .fl-icon:before{background-color:currentColor;border-radius:.1em;height:.7em;left:50%;top:50%;transform:translate(-50%,-50%) rotate(-135deg);width:.16em}.fl-main-container .fl-container.fl-error .fl-icon:after{transform:translate(-50%,-50%) rotate(-45deg)}.fl-main-container .fl-container.fl-flasher{background-color:#fff;box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);color:#4b5563;cursor:pointer;line-height:1.5;margin-top:.5em;word-break:break-word}.fl-main-container .fl-container.fl-flasher.fl-rtl{border-radius:0 .375em .375em 0}.fl-main-container .fl-container.fl-flasher:not(.fl-rtl){border-radius:.375em 0 0 .375em}.fl-main-container .fl-container.fl-flasher .fl-content{align-items:center;display:flex;padding:.75em}.fl-main-container .fl-container.fl-flasher .fl-icon{font-size:2.5em}.fl-main-container .fl-container.fl-flasher .fl-message,.fl-main-container .fl-container.fl-flasher .fl-title{display:block;line-height:1.25em;margin-left:1em;margin-right:1em}.fl-main-container .fl-container.fl-flasher .fl-message:first-letter,.fl-main-container .fl-container.fl-flasher .fl-title:first-letter{text-transform:uppercase}.fl-main-container .fl-container.fl-flasher .fl-title{font-size:1em;font-weight:700}.fl-main-container .fl-container.fl-flasher .fl-message{font-size:.875em;margin-top:.25em} \ No newline at end of file diff --git a/src/Prime/Resources/assets/flasher.min.js b/src/Prime/Resources/assets/flasher.min.js deleted file mode 100644 index 065b20c0..00000000 --- a/src/Prime/Resources/assets/flasher.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).flasher=e()}(this,(function(){"use strict";function t(t,e,n){if(n||2===arguments.length)for(var o,r=0,i=e.length;r
'+(null!==(e=n.title)&&void 0!==e?e:n.type)+''+n.message+'
'}}),n})); diff --git a/src/Prime/Resources/assets/flasher.ts b/src/Prime/Resources/assets/flasher.ts new file mode 100644 index 00000000..3d5b68e1 --- /dev/null +++ b/src/Prime/Resources/assets/flasher.ts @@ -0,0 +1,206 @@ +import type { Context, Envelope, Options, PluginInterface, Response, Theme } from './types' +import { AbstractPlugin } from './plugin' +import FlasherPlugin from './flasher-plugin' + +export default class Flasher extends AbstractPlugin { + private defaultPlugin = 'flasher' + private plugins: Map = new Map() + private themes: Map = new Map() + + public async render(response: Partial): Promise { + const resolved = this.resolveResponse(response) + + await this.addAssets([ + { + urls: resolved.styles, + nonce: resolved.context.csp_style_nonce as string, + type: 'style', + }, + { + urls: resolved.scripts, + nonce: resolved.context.csp_script_nonce as string, + type: 'script', + }, + ]) + + this.renderOptions(resolved.options) + this.renderEnvelopes(resolved.envelopes) + } + + public renderEnvelopes(envelopes: Envelope[]): void { + const map: Record = {} + + envelopes.forEach((envelope) => { + const plugin = this.resolvePluginAlias(envelope.metadata.plugin) + + map[plugin] = map[plugin] || [] + map[plugin].push(envelope) + }) + + Object.entries(map).forEach(([plugin, envelopes]) => { + this.use(plugin).renderEnvelopes(envelopes) + }) + } + + public renderOptions(options: Options): void { + Object.entries(options).forEach(([plugin, option]) => { + // @ts-expect-error + this.use(plugin).renderOptions(option) + }) + } + + public addPlugin(name: string, plugin: PluginInterface): void { + this.plugins.set(name, plugin) + } + + public addTheme(name: string, theme: Theme): void { + this.themes.set(name, theme) + } + + public use(name: string): PluginInterface { + name = this.resolvePluginAlias(name) + this.resolvePlugin(name) + + const plugin = this.plugins.get(name) + if (!plugin) { + throw new Error(`Unable to resolve "${name}" plugin, did you forget to register it?`) + } + + return plugin + } + + public create(name: string): PluginInterface { + return this.use(name) + } + + private resolveResponse(response: Partial): Response { + const resolved = { + envelopes: [], + options: {}, + scripts: [], + styles: [], + context: {}, + ...response, + } as Response + + Object.entries(resolved.options).forEach(([plugin, options]) => { + resolved.options[plugin] = this.resolveOptions(options) + }) + + resolved.context.csp_style_nonce = resolved.context.csp_style_nonce || '' + resolved.context.csp_script_nonce = resolved.context.csp_script_nonce || '' + + resolved.envelopes.forEach((envelope) => { + envelope.metadata = envelope.metadata || {} + envelope.metadata.plugin = this.resolvePluginAlias(envelope.metadata.plugin) + this.addThemeStyles(resolved, envelope.metadata.plugin) + envelope.options = this.resolveOptions(envelope.options) + envelope.context = response.context as Context + }) + + return resolved + } + + private resolveOptions(options: Options): Options { + Object.entries(options).forEach(([key, value]) => { + options[key] = this.resolveFunction(value) + }) + + return options + } + + private resolveFunction(func: unknown): unknown { + if (typeof func !== 'string') { + return func + } + + const functionRegex = /^function\s*(\w*)\s*\(([^)]*)\)\s*\{([\s\S]*)\}$/ + const arrowFunctionRegex = /^\s*(\(([^)]*)\)|[^=]+)\s*=>\s*([\s\S]+)$/ + + const match = func.match(functionRegex) || func.match(arrowFunctionRegex) + if (!match) { + return func + } + + const args = match[2]?.split(',').map((arg) => arg.trim()) ?? [] + let body = match[3].trim() + + // Arrow functions with a single expression can omit the curly braces and the return keyword. + // This check is to ensure that the function body is properly wrapped with curly braces. + if (!body.startsWith('{')) { + body = `{ return ${body}; }` + } + + try { + // eslint-disable-next-line no-new-func + return new Function(...args, body) + } catch (e) { + console.error('Error converting string to function:', e) + return func + } + } + + private resolvePlugin(alias: string): void { + const factory = this.plugins.get(alias) + if (factory || !alias.includes('theme.')) { + return + } + + const view = this.themes.get(alias.replace('theme.', '')) + if (!view) { + return + } + + this.addPlugin(alias, new FlasherPlugin(view)) + } + + private resolvePluginAlias(alias?: string): string { + alias = alias || this.defaultPlugin + + return alias === 'flasher' ? 'theme.flasher' : alias + } + + private async addAssets(assets: Array<{ urls: string[], nonce: string, type: 'style' | 'script' }>): Promise { + for (const { urls, nonce, type } of assets) { + for (const url of urls) { + await this.loadAsset(url, nonce, type) + } + } + } + + private async loadAsset(url: string, nonce: string, type: 'style' | 'script'): Promise { + if (document.querySelector(`${type === 'style' ? 'link' : 'script'}[src="${url}"]`)) { + return + } + + const element = document.createElement(type === 'style' ? 'link' : 'script') as HTMLLinkElement & HTMLScriptElement & { [attrName: string]: string } + if (type === 'style') { + element.rel = 'stylesheet' + element.href = url + } else { + element.type = 'text/javascript' + element.src = url + } + + if (nonce) { + element.setAttribute('nonce', nonce) + } + document.head.appendChild(element) + + return new Promise((resolve, reject) => { + element.onload = () => resolve() + element.onerror = () => reject(new Error(`Failed to load ${url}`)) + }) + } + + private addThemeStyles(response: Response, plugin: string): void { + if (plugin !== 'flasher' && !plugin.includes('theme.')) { + return + } + + plugin = plugin.replace('theme.', '') + const styles = this.themes.get(plugin)?.styles || [] + + response.styles = Array.from(new Set([...response.styles, ...styles])) + } +} diff --git a/src/Prime/Resources/assets/index.ts b/src/Prime/Resources/assets/index.ts new file mode 100644 index 00000000..90acffed --- /dev/null +++ b/src/Prime/Resources/assets/index.ts @@ -0,0 +1,7 @@ +import Flasher from './flasher' +import { flasherTheme } from './themes/flasher' + +const flasher = new Flasher() +flasher.addTheme('flasher', flasherTheme) + +export default flasher diff --git a/src/Prime/Resources/assets/plugin.ts b/src/Prime/Resources/assets/plugin.ts new file mode 100644 index 00000000..d43e7ae6 --- /dev/null +++ b/src/Prime/Resources/assets/plugin.ts @@ -0,0 +1,56 @@ +import type { Envelope, Options, PluginInterface } from './types' + +export abstract class AbstractPlugin implements PluginInterface { + abstract renderEnvelopes(envelopes: Envelope[]): void + + abstract renderOptions(options: Options): void + + public success(message: string | Options, title?: string | Options, options?: Options): void { + this.flash('success', message, title, options) + } + + public error(message: string | Options, title?: string | Options, options?: Options): void { + this.flash('error', message, title, options) + } + + public info(message: string | Options, title?: string | Options, options?: Options): void { + this.flash('info', message, title, options) + } + + public warning(message: string | Options, title?: string | Options, options?: Options): void { + this.flash('warning', message, title, options) + } + + public flash(type: string | Options, message: string | Options, title?: string | Options, options?: Options): void { + if (typeof type === 'object') { + options = type + type = options.type as unknown as string + message = options.message as unknown as string + title = options.title as unknown as string + } else if (typeof message === 'object') { + options = message + message = options.message as unknown as string + title = options.title as unknown as string + } else if (typeof title === 'object') { + options = title + title = options.title as unknown as string + } + + if (undefined === message) { + throw new Error('message option is required') + } + + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + } + + this.renderOptions(options || {}) + this.renderEnvelopes([envelope]) + } +} diff --git a/src/Prime/Resources/assets/theme.ts b/src/Prime/Resources/assets/theme.ts new file mode 100644 index 00000000..b632f74c --- /dev/null +++ b/src/Prime/Resources/assets/theme.ts @@ -0,0 +1,19 @@ +import type { Envelope } from './types' + +export const theme = { + render: (envelope: Envelope): string => { + const { type, title, message } = envelope + + return ` +
+
+
+
+ ${title} + ${message} +
+
+ +
` + }, +} diff --git a/src/Prime/Resources/assets/themes/container.scss b/src/Prime/Resources/assets/themes/container.scss new file mode 100644 index 00000000..26bf201b --- /dev/null +++ b/src/Prime/Resources/assets/themes/container.scss @@ -0,0 +1,15 @@ +.fl-container { + color: var(--text-color); + opacity: 0; + transform: translate(0, -20px); + transition: all 0.5s ease-in-out; + + &.fl-show { + opacity: 1; + transform: translate(0, 0) !important; + } + + &.fl-rtl { + direction: rtl; + } +} diff --git a/src/Prime/Resources/assets/themes/flasher/flasher.scss b/src/Prime/Resources/assets/themes/flasher/flasher.scss new file mode 100644 index 00000000..def53777 --- /dev/null +++ b/src/Prime/Resources/assets/themes/flasher/flasher.scss @@ -0,0 +1,100 @@ +body.fl-dark .fl-flasher, +html.fl-dark .fl-flasher { + --background-color: var(--dark-background-color); + --text-color: var(--dark-text-color); +} + +.fl-flasher { + line-height: 1.5; + background-color: var(--background-color); + color: var(--text-color); + box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + word-break: break-word; + padding: 0.75em; + margin: 0.75em 0; + position: relative; + + &.fl-rtl { + border-radius: 0 0.375em 0.375em 0; + } + + &:not(.fl-rtl) { + border-radius: 0.375em 0 0 0.375em; + } + + .fl-content { + display: flex; + align-items: center; + } + + .fl-icon { + font-size: 2.5em; + } + + .fl-title, + .fl-message { + display: block; + margin-left: 1em; + margin-right: 1em; + line-height: 1.25em; + } + + .fl-title { + font-size: 1em; + font-weight: bold; + } + + .fl-message { + margin-top: 0.25em; + font-size: 0.875em; + } + + .fl-close { + cursor: pointer; + background-color: transparent; + border: none; + position: absolute; + top: 1rem; + right: 0.5rem; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.5rem; + margin: -0.5rem; + font-size: 25px; + line-height: 0; + color: #a8aaab; + transition: color 0.3s ease, transform 0.3s ease; + + &:hover { + color: darken(#a8aaab, 10%); + transform: scale(1.1); + } + } + + &.fl-rtl .fl-close { + right: auto; + left: 0.5rem; + } + + + @each $type in success, info, warning, error { + &.fl-#{$type} { + border-left: 0.8em solid var(--#{$type}-color); + + &.fl-rtl { + border-right: 0.8em solid var(--#{$type}-color); + border-left: none; + } + + &:not(.fl-rtl) { + border-right: none; + border-left: 0.8em solid var(--#{$type}-color); + } + + .fl-title { + color: var(--#{$type}-color); + } + } + } +} diff --git a/src/Prime/Resources/assets/themes/flasher/index.ts b/src/Prime/Resources/assets/themes/flasher/index.ts new file mode 100644 index 00000000..f18ddf00 --- /dev/null +++ b/src/Prime/Resources/assets/themes/flasher/index.ts @@ -0,0 +1,22 @@ +import './flasher.scss' + +import type { Envelope } from '../../types' + +export const flasherTheme = { + render: (envelope: Envelope): string => { + const { type, title, message } = envelope + + return ` +
+
+
+
+ ${title} + ${message} +
+ +
+ +
` + }, +} diff --git a/src/Prime/Resources/assets/themes/icons.scss b/src/Prime/Resources/assets/themes/icons.scss new file mode 100644 index 00000000..38904abb --- /dev/null +++ b/src/Prime/Resources/assets/themes/icons.scss @@ -0,0 +1,109 @@ +.fl-icon { + position: relative; + box-sizing: border-box; + display: inline-block; + width: 1em; + min-width: 1em; + height: 1em; + min-height: 1em; + margin: 0; + color: white; + border-radius: 50%; + transition: all 1s; + + &::before, + &::after { + position: absolute; + box-sizing: border-box; + content: ""; + border-width: 0; + transition: all 1s; + } +} + +.fl-success .fl-icon { + &::before, + &::after { + top: 0.6em; + left: 0.35em; + width: 0.16em; + height: 0.6em; + background-color: currentcolor; + border-radius: 0.1em; + transform: rotate(-135deg); + transform-origin: 0.08em 0.08em; + } + + &::after { + width: 0.4em; + height: 0.16em; + } +} + +.fl-info .fl-icon { + &::before, + &::after { + left: 50%; + width: 0.15em; + background-color: currentcolor; + border-radius: 0.03em; + transform: translateX(-50%); + } + + &::before { + top: 0.4em; + height: 0.38em; + } + + &::after { + top: 0.21em; + height: 0.13em; + box-shadow: -0.06em 0.19em, -0.06em 0.44em, 0.06em 0.44em; + } +} + +.fl-warning .fl-icon { + &::before, + &::after { + left: 50%; + width: 0.15em; + background-color: currentcolor; + border-radius: 0.03em; + transform: translateX(-50%); + } + + &::before { + top: 0.21em; + height: 0.38em; + } + + &::after { + top: 0.65em; + height: 0.13em; + } +} + +.fl-error .fl-icon { + &::before, + &::after { + top: 50%; + left: 50%; + width: 0.16em; + height: 0.7em; + background-color: currentcolor; + border-radius: 0.1em; + transform: translate(-50%, -50%) rotate(-135deg); + } + + &::after { + transform: translate(-50%, -50%) rotate(-45deg); + } +} + +@each $type in success, info, warning, error { + .fl-#{$type} { + .fl-icon { + background-color: var(--#{$type}-color); + } + } +} diff --git a/src/Prime/Resources/assets/themes/index.scss b/src/Prime/Resources/assets/themes/index.scss new file mode 100644 index 00000000..1719a816 --- /dev/null +++ b/src/Prime/Resources/assets/themes/index.scss @@ -0,0 +1,19 @@ +:root { + --background-color: rgb(255, 255, 255); + --text-color: rgb(75, 85, 99); + --dark-background-color: rgb(15, 23, 42); + --dark-text-color: rgb(255, 255, 255); + --success-color: #10b981; + --info-color: #3b82f6; + --warning-color: #f59e0b; + --error-color: #ef4444; + --success-color-light: hsl(160deg, 70%, 90%); + --info-color-light: hsl(217deg, 69%, 90%); + --warning-color-light: hsl(33deg, 89%, 90%); + --error-color-light: hsl(0deg, 75%, 90%); +} + +@import "wrapper"; +@import "container"; +@import "icons"; +@import "progress"; diff --git a/src/Prime/Resources/assets/themes/progress.scss b/src/Prime/Resources/assets/themes/progress.scss new file mode 100644 index 00000000..e7de5c05 --- /dev/null +++ b/src/Prime/Resources/assets/themes/progress.scss @@ -0,0 +1,20 @@ +.fl-progress-bar { + display: flex; + height: 0.125em; + position: absolute; + bottom: 0; + left: 0; + right: 0; +} + +@each $type in success, info, warning, error { + .fl-#{$type} { + .fl-progress-bar { + background-color: var(--#{$type}-color-light); + + .fl-progress { + background-color: var(--#{$type}-color); + } + } + } +} diff --git a/src/Prime/Resources/assets/themes/wrapper.scss b/src/Prime/Resources/assets/themes/wrapper.scss new file mode 100644 index 00000000..81dce595 --- /dev/null +++ b/src/Prime/Resources/assets/themes/wrapper.scss @@ -0,0 +1,49 @@ +.fl-wrapper { + position: fixed; + z-index: 10; + width: 24em; + transition: all 1s ease-in-out; + + @media only screen and (width <= 480px) { + width: 90%; + left: 5%; + right: 5%; + } + + &[data-position^="top-"] { + top: 0.5em; + } + + &[data-position^="bottom-"] { + bottom: 0.5em; + } + + &[data-position$="-right"] { + right: 0.5em; + + .fl-container { + transform: translateX(110%); + } + } + + &[data-position$="-left"] { + left: 0.5em; + + .fl-container { + transform: translateX(-110%); + } + } + + &[data-position$="-center"] { + left: 50%; + transform: translateX(-50%); + } + + &[data-position="top-center"] .fl-container { + transform: translateY(-100vh); + } + + &[data-position="bottom-center"] .fl-container { + transform: translateY(100vh); + } +} diff --git a/src/Prime/Resources/assets/types.ts b/src/Prime/Resources/assets/types.ts new file mode 100644 index 00000000..1d20afd9 --- /dev/null +++ b/src/Prime/Resources/assets/types.ts @@ -0,0 +1,35 @@ +export type Options = { [option: string]: unknown } + +export type Context = { [key: string]: unknown } + +export type Envelope = { + message: string + title: string + type: string + options: Options + metadata: { plugin: string } + context?: Context +} + +export type Response = { + envelopes: Envelope[] + options: { [plugin: string]: Options } + scripts: string[] + styles: string[] + context: Context +} + +export type PluginInterface = { + success: (message: string | Options, title?: string | Options, options?: Options) => void + error: (message: string | Options, title?: string | Options, options?: Options) => void + info: (message: string | Options, title?: string | Options, options?: Options) => void + warning: (message: string | Options, title?: string | Options, options?: Options) => void + flash: (type: string | Options, message: string | Options, title?: string | Options, options?: Options) => void + renderEnvelopes: (envelopes: Envelope[]) => void + renderOptions: (options: Options) => void +} + +export type Theme = { + styles?: string | string[] + render: (envelope: Envelope) => string +} diff --git a/src/Prime/Resources/dist/flasher-plugin.d.ts b/src/Prime/Resources/dist/flasher-plugin.d.ts new file mode 100644 index 00000000..f0a12b15 --- /dev/null +++ b/src/Prime/Resources/dist/flasher-plugin.d.ts @@ -0,0 +1,18 @@ +import './themes/index.scss'; +import type { Envelope, Options, Theme } from './types'; +import { AbstractPlugin } from './plugin'; +export default class FlasherPlugin extends AbstractPlugin { + private theme; + private options; + constructor(theme: Theme); + renderEnvelopes(envelopes: Envelope[]): void; + renderOptions(options: Options): void; + private createContainer; + private addToContainer; + addProgressBar(notification: HTMLElement, { timeout, fps }: { + timeout: number; + fps: number; + }): void; + private removeNotification; + private stringToHTML; +} diff --git a/src/Prime/Resources/dist/flasher.d.ts b/src/Prime/Resources/dist/flasher.d.ts new file mode 100644 index 00000000..388a6960 --- /dev/null +++ b/src/Prime/Resources/dist/flasher.d.ts @@ -0,0 +1,22 @@ +import type { Envelope, Options, PluginInterface, Response, Theme } from './types'; +import { AbstractPlugin } from './plugin'; +export default class Flasher extends AbstractPlugin { + private defaultPlugin; + private plugins; + private themes; + render(response: Partial): Promise; + renderEnvelopes(envelopes: Envelope[]): void; + renderOptions(options: Options): void; + addPlugin(name: string, plugin: PluginInterface): void; + addTheme(name: string, theme: Theme): void; + use(name: string): PluginInterface; + create(name: string): PluginInterface; + private resolveResponse; + private resolveOptions; + private resolveFunction; + private resolvePlugin; + private resolvePluginAlias; + private addAssets; + private loadAsset; + private addThemeStyles; +} diff --git a/src/Prime/Resources/dist/flasher.esm.js b/src/Prime/Resources/dist/flasher.esm.js new file mode 100644 index 00000000..f25df558 --- /dev/null +++ b/src/Prime/Resources/dist/flasher.esm.js @@ -0,0 +1,343 @@ +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } +} + +class FlasherPlugin extends AbstractPlugin { + constructor(theme) { + super(); + this.options = { + timeout: 5000, + timeouts: { + success: 5000, + info: 5000, + error: 5000, + warning: 5000, + }, + fps: 30, + position: 'top-right', + direction: 'top', + rtl: false, + style: {}, + }; + this.theme = theme; + } + renderEnvelopes(envelopes) { + const render = () => envelopes.forEach((envelope) => { + var _a, _b; + const typeTimeout = (_a = this.options.timeouts[envelope.type]) !== null && _a !== void 0 ? _a : this.options.timeout; + const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_b = envelope.options.timeout) !== null && _b !== void 0 ? _b : typeTimeout }); + this.addToContainer(this.createContainer(options), envelope, options); + }); + document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render(); + } + renderOptions(options) { + this.options = Object.assign(Object.assign({}, this.options), options); + } + createContainer(options) { + let container = document.querySelector(`.fl-wrapper[data-position="${options.position}"]`); + if (!container) { + container = document.createElement('div'); + container.className = 'fl-wrapper'; + container.dataset.position = options.position; + Object.entries(options.style).forEach(([key, value]) => container.style.setProperty(key, value)); + document.body.appendChild(container); + } + container.dataset.turboCache = 'false'; + return container; + } + addToContainer(container, envelope, options) { + var _a; + const notification = this.stringToHTML(this.theme.render(envelope)); + notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' ')); + options.direction === 'bottom' ? container.append(notification) : container.prepend(notification); + requestAnimationFrame(() => notification.classList.add('fl-show')); + (_a = notification.querySelector('.fl-close')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', (event) => { + event.stopPropagation(); + this.removeNotification(notification); + }); + this.addProgressBar(notification, options); + } + addProgressBar(notification, { timeout, fps }) { + if (timeout <= 0 || fps <= 0) { + return; + } + const progressBarContainer = notification.querySelector('.fl-progress-bar'); + if (!progressBarContainer) { + return; + } + const progressBar = document.createElement('span'); + progressBar.classList.add('fl-progress'); + progressBarContainer.append(progressBar); + const lapse = 1000 / fps; + let width = 0; + const updateProgress = () => { + width += 1; + const percent = (1 - lapse * (width / timeout)) * 100; + progressBar.style.width = `${percent}%`; + if (percent <= 0) { + clearInterval(intervalId); + this.removeNotification(notification); + } + }; + let intervalId = window.setInterval(updateProgress, lapse); + notification.addEventListener('mouseout', () => intervalId = window.setInterval(updateProgress, lapse)); + notification.addEventListener('mouseover', () => clearInterval(intervalId)); + } + removeNotification(notification) { + notification.classList.remove('fl-show'); + notification.ontransitionend = () => { + var _a, _b; + !((_a = notification.parentElement) === null || _a === void 0 ? void 0 : _a.hasChildNodes()) && ((_b = notification.parentElement) === null || _b === void 0 ? void 0 : _b.remove()); + notification.remove(); + }; + } + stringToHTML(str) { + const template = document.createElement('template'); + template.innerHTML = str.trim(); + return template.content.firstElementChild; + } +} + +class Flasher extends AbstractPlugin { + constructor() { + super(...arguments); + this.defaultPlugin = 'flasher'; + this.plugins = new Map(); + this.themes = new Map(); + } + render(response) { + return __awaiter(this, void 0, void 0, function* () { + const resolved = this.resolveResponse(response); + yield this.addAssets([ + { + urls: resolved.styles, + nonce: resolved.context.csp_style_nonce, + type: 'style', + }, + { + urls: resolved.scripts, + nonce: resolved.context.csp_script_nonce, + type: 'script', + }, + ]); + this.renderOptions(resolved.options); + this.renderEnvelopes(resolved.envelopes); + }); + } + renderEnvelopes(envelopes) { + const map = {}; + envelopes.forEach((envelope) => { + const plugin = this.resolvePluginAlias(envelope.metadata.plugin); + map[plugin] = map[plugin] || []; + map[plugin].push(envelope); + }); + Object.entries(map).forEach(([plugin, envelopes]) => { + this.use(plugin).renderEnvelopes(envelopes); + }); + } + renderOptions(options) { + Object.entries(options).forEach(([plugin, option]) => { + this.use(plugin).renderOptions(option); + }); + } + addPlugin(name, plugin) { + this.plugins.set(name, plugin); + } + addTheme(name, theme) { + this.themes.set(name, theme); + } + use(name) { + name = this.resolvePluginAlias(name); + this.resolvePlugin(name); + const plugin = this.plugins.get(name); + if (!plugin) { + throw new Error(`Unable to resolve "${name}" plugin, did you forget to register it?`); + } + return plugin; + } + create(name) { + return this.use(name); + } + resolveResponse(response) { + const resolved = Object.assign({ envelopes: [], options: {}, scripts: [], styles: [], context: {} }, response); + Object.entries(resolved.options).forEach(([plugin, options]) => { + resolved.options[plugin] = this.resolveOptions(options); + }); + resolved.context.csp_style_nonce = resolved.context.csp_style_nonce || ''; + resolved.context.csp_script_nonce = resolved.context.csp_script_nonce || ''; + resolved.envelopes.forEach((envelope) => { + envelope.metadata = envelope.metadata || {}; + envelope.metadata.plugin = this.resolvePluginAlias(envelope.metadata.plugin); + this.addThemeStyles(resolved, envelope.metadata.plugin); + envelope.options = this.resolveOptions(envelope.options); + envelope.context = response.context; + }); + return resolved; + } + resolveOptions(options) { + Object.entries(options).forEach(([key, value]) => { + options[key] = this.resolveFunction(value); + }); + return options; + } + resolveFunction(func) { + var _a, _b; + if (typeof func !== 'string') { + return func; + } + const functionRegex = /^function\s*(\w*)\s*\(([^)]*)\)\s*\{([\s\S]*)\}$/; + const arrowFunctionRegex = /^\s*(\(([^)]*)\)|[^=]+)\s*=>\s*([\s\S]+)$/; + const match = func.match(functionRegex) || func.match(arrowFunctionRegex); + if (!match) { + return func; + } + const args = (_b = (_a = match[2]) === null || _a === void 0 ? void 0 : _a.split(',').map((arg) => arg.trim())) !== null && _b !== void 0 ? _b : []; + let body = match[3].trim(); + if (!body.startsWith('{')) { + body = `{ return ${body}; }`; + } + try { + return new Function(...args, body); + } + catch (e) { + console.error('Error converting string to function:', e); + return func; + } + } + resolvePlugin(alias) { + const factory = this.plugins.get(alias); + if (factory || !alias.includes('theme.')) { + return; + } + const view = this.themes.get(alias.replace('theme.', '')); + if (!view) { + return; + } + this.addPlugin(alias, new FlasherPlugin(view)); + } + resolvePluginAlias(alias) { + alias = alias || this.defaultPlugin; + return alias === 'flasher' ? 'theme.flasher' : alias; + } + addAssets(assets) { + return __awaiter(this, void 0, void 0, function* () { + for (const { urls, nonce, type } of assets) { + for (const url of urls) { + yield this.loadAsset(url, nonce, type); + } + } + }); + } + loadAsset(url, nonce, type) { + return __awaiter(this, void 0, void 0, function* () { + if (document.querySelector(`${type === 'style' ? 'link' : 'script'}[src="${url}"]`)) { + return; + } + const element = document.createElement(type === 'style' ? 'link' : 'script'); + if (type === 'style') { + element.rel = 'stylesheet'; + element.href = url; + } + else { + element.type = 'text/javascript'; + element.src = url; + } + if (nonce) { + element.setAttribute('nonce', nonce); + } + document.head.appendChild(element); + return new Promise((resolve, reject) => { + element.onload = () => resolve(); + element.onerror = () => reject(new Error(`Failed to load ${url}`)); + }); + }); + } + addThemeStyles(response, plugin) { + var _a; + if (plugin !== 'flasher' && !plugin.includes('theme.')) { + return; + } + plugin = plugin.replace('theme.', ''); + const styles = ((_a = this.themes.get(plugin)) === null || _a === void 0 ? void 0 : _a.styles) || []; + response.styles = Array.from(new Set([...response.styles, ...styles])); + } +} + +const flasherTheme = { + render: (envelope) => { + const { type, title, message } = envelope; + return ` +
+
+
+
+ ${title} + ${message} +
+ +
+ +
`; + }, +}; + +const flasher = new Flasher(); +flasher.addTheme('flasher', flasherTheme); + +export { flasher as default }; diff --git a/src/Prime/Resources/dist/flasher.js b/src/Prime/Resources/dist/flasher.js new file mode 100644 index 00000000..24f389a6 --- /dev/null +++ b/src/Prime/Resources/dist/flasher.js @@ -0,0 +1,351 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.flasher = factory()); +})(this, (function () { 'use strict'; + + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + + class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } + } + + class FlasherPlugin extends AbstractPlugin { + constructor(theme) { + super(); + this.options = { + timeout: 5000, + timeouts: { + success: 5000, + info: 5000, + error: 5000, + warning: 5000, + }, + fps: 30, + position: 'top-right', + direction: 'top', + rtl: false, + style: {}, + }; + this.theme = theme; + } + renderEnvelopes(envelopes) { + const render = () => envelopes.forEach((envelope) => { + var _a, _b; + const typeTimeout = (_a = this.options.timeouts[envelope.type]) !== null && _a !== void 0 ? _a : this.options.timeout; + const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_b = envelope.options.timeout) !== null && _b !== void 0 ? _b : typeTimeout }); + this.addToContainer(this.createContainer(options), envelope, options); + }); + document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render(); + } + renderOptions(options) { + this.options = Object.assign(Object.assign({}, this.options), options); + } + createContainer(options) { + let container = document.querySelector(`.fl-wrapper[data-position="${options.position}"]`); + if (!container) { + container = document.createElement('div'); + container.className = 'fl-wrapper'; + container.dataset.position = options.position; + Object.entries(options.style).forEach(([key, value]) => container.style.setProperty(key, value)); + document.body.appendChild(container); + } + container.dataset.turboCache = 'false'; + return container; + } + addToContainer(container, envelope, options) { + var _a; + const notification = this.stringToHTML(this.theme.render(envelope)); + notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' ')); + options.direction === 'bottom' ? container.append(notification) : container.prepend(notification); + requestAnimationFrame(() => notification.classList.add('fl-show')); + (_a = notification.querySelector('.fl-close')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', (event) => { + event.stopPropagation(); + this.removeNotification(notification); + }); + this.addProgressBar(notification, options); + } + addProgressBar(notification, { timeout, fps }) { + if (timeout <= 0 || fps <= 0) { + return; + } + const progressBarContainer = notification.querySelector('.fl-progress-bar'); + if (!progressBarContainer) { + return; + } + const progressBar = document.createElement('span'); + progressBar.classList.add('fl-progress'); + progressBarContainer.append(progressBar); + const lapse = 1000 / fps; + let width = 0; + const updateProgress = () => { + width += 1; + const percent = (1 - lapse * (width / timeout)) * 100; + progressBar.style.width = `${percent}%`; + if (percent <= 0) { + clearInterval(intervalId); + this.removeNotification(notification); + } + }; + let intervalId = window.setInterval(updateProgress, lapse); + notification.addEventListener('mouseout', () => intervalId = window.setInterval(updateProgress, lapse)); + notification.addEventListener('mouseover', () => clearInterval(intervalId)); + } + removeNotification(notification) { + notification.classList.remove('fl-show'); + notification.ontransitionend = () => { + var _a, _b; + !((_a = notification.parentElement) === null || _a === void 0 ? void 0 : _a.hasChildNodes()) && ((_b = notification.parentElement) === null || _b === void 0 ? void 0 : _b.remove()); + notification.remove(); + }; + } + stringToHTML(str) { + const template = document.createElement('template'); + template.innerHTML = str.trim(); + return template.content.firstElementChild; + } + } + + class Flasher extends AbstractPlugin { + constructor() { + super(...arguments); + this.defaultPlugin = 'flasher'; + this.plugins = new Map(); + this.themes = new Map(); + } + render(response) { + return __awaiter(this, void 0, void 0, function* () { + const resolved = this.resolveResponse(response); + yield this.addAssets([ + { + urls: resolved.styles, + nonce: resolved.context.csp_style_nonce, + type: 'style', + }, + { + urls: resolved.scripts, + nonce: resolved.context.csp_script_nonce, + type: 'script', + }, + ]); + this.renderOptions(resolved.options); + this.renderEnvelopes(resolved.envelopes); + }); + } + renderEnvelopes(envelopes) { + const map = {}; + envelopes.forEach((envelope) => { + const plugin = this.resolvePluginAlias(envelope.metadata.plugin); + map[plugin] = map[plugin] || []; + map[plugin].push(envelope); + }); + Object.entries(map).forEach(([plugin, envelopes]) => { + this.use(plugin).renderEnvelopes(envelopes); + }); + } + renderOptions(options) { + Object.entries(options).forEach(([plugin, option]) => { + this.use(plugin).renderOptions(option); + }); + } + addPlugin(name, plugin) { + this.plugins.set(name, plugin); + } + addTheme(name, theme) { + this.themes.set(name, theme); + } + use(name) { + name = this.resolvePluginAlias(name); + this.resolvePlugin(name); + const plugin = this.plugins.get(name); + if (!plugin) { + throw new Error(`Unable to resolve "${name}" plugin, did you forget to register it?`); + } + return plugin; + } + create(name) { + return this.use(name); + } + resolveResponse(response) { + const resolved = Object.assign({ envelopes: [], options: {}, scripts: [], styles: [], context: {} }, response); + Object.entries(resolved.options).forEach(([plugin, options]) => { + resolved.options[plugin] = this.resolveOptions(options); + }); + resolved.context.csp_style_nonce = resolved.context.csp_style_nonce || ''; + resolved.context.csp_script_nonce = resolved.context.csp_script_nonce || ''; + resolved.envelopes.forEach((envelope) => { + envelope.metadata = envelope.metadata || {}; + envelope.metadata.plugin = this.resolvePluginAlias(envelope.metadata.plugin); + this.addThemeStyles(resolved, envelope.metadata.plugin); + envelope.options = this.resolveOptions(envelope.options); + envelope.context = response.context; + }); + return resolved; + } + resolveOptions(options) { + Object.entries(options).forEach(([key, value]) => { + options[key] = this.resolveFunction(value); + }); + return options; + } + resolveFunction(func) { + var _a, _b; + if (typeof func !== 'string') { + return func; + } + const functionRegex = /^function\s*(\w*)\s*\(([^)]*)\)\s*\{([\s\S]*)\}$/; + const arrowFunctionRegex = /^\s*(\(([^)]*)\)|[^=]+)\s*=>\s*([\s\S]+)$/; + const match = func.match(functionRegex) || func.match(arrowFunctionRegex); + if (!match) { + return func; + } + const args = (_b = (_a = match[2]) === null || _a === void 0 ? void 0 : _a.split(',').map((arg) => arg.trim())) !== null && _b !== void 0 ? _b : []; + let body = match[3].trim(); + if (!body.startsWith('{')) { + body = `{ return ${body}; }`; + } + try { + return new Function(...args, body); + } + catch (e) { + console.error('Error converting string to function:', e); + return func; + } + } + resolvePlugin(alias) { + const factory = this.plugins.get(alias); + if (factory || !alias.includes('theme.')) { + return; + } + const view = this.themes.get(alias.replace('theme.', '')); + if (!view) { + return; + } + this.addPlugin(alias, new FlasherPlugin(view)); + } + resolvePluginAlias(alias) { + alias = alias || this.defaultPlugin; + return alias === 'flasher' ? 'theme.flasher' : alias; + } + addAssets(assets) { + return __awaiter(this, void 0, void 0, function* () { + for (const { urls, nonce, type } of assets) { + for (const url of urls) { + yield this.loadAsset(url, nonce, type); + } + } + }); + } + loadAsset(url, nonce, type) { + return __awaiter(this, void 0, void 0, function* () { + if (document.querySelector(`${type === 'style' ? 'link' : 'script'}[src="${url}"]`)) { + return; + } + const element = document.createElement(type === 'style' ? 'link' : 'script'); + if (type === 'style') { + element.rel = 'stylesheet'; + element.href = url; + } + else { + element.type = 'text/javascript'; + element.src = url; + } + if (nonce) { + element.setAttribute('nonce', nonce); + } + document.head.appendChild(element); + return new Promise((resolve, reject) => { + element.onload = () => resolve(); + element.onerror = () => reject(new Error(`Failed to load ${url}`)); + }); + }); + } + addThemeStyles(response, plugin) { + var _a; + if (plugin !== 'flasher' && !plugin.includes('theme.')) { + return; + } + plugin = plugin.replace('theme.', ''); + const styles = ((_a = this.themes.get(plugin)) === null || _a === void 0 ? void 0 : _a.styles) || []; + response.styles = Array.from(new Set([...response.styles, ...styles])); + } + } + + const flasherTheme = { + render: (envelope) => { + const { type, title, message } = envelope; + return ` +
+
+
+
+ ${title} + ${message} +
+ +
+ +
`; + }, + }; + + const flasher = new Flasher(); + flasher.addTheme('flasher', flasherTheme); + + return flasher; + +})); diff --git a/src/Prime/Resources/dist/flasher.min.css b/src/Prime/Resources/dist/flasher.min.css new file mode 100644 index 00000000..8d192211 --- /dev/null +++ b/src/Prime/Resources/dist/flasher.min.css @@ -0,0 +1,2 @@ +:root{--background-color:#fff;--text-color:#4b5563;--dark-background-color:#0f172a;--dark-text-color:#fff;--success-color:#10b981;--info-color:#3b82f6;--warning-color:#f59e0b;--error-color:#ef4444;--success-color-light:#d4f7eb;--info-color-light:#d4e1f7;--warning-color-light:#fce8cf;--error-color-light:#f9d2d2}.fl-wrapper{position:fixed;-webkit-transition:all 1s ease-in-out;-moz-transition:all 1s ease-in-out;transition:all 1s ease-in-out;width:24em;z-index:10}@media only screen and (width <= 480px){.fl-wrapper{left:5%;right:5%;width:90%}}.fl-wrapper[data-position^=top-]{top:.5em}.fl-wrapper[data-position^=bottom-]{bottom:.5em}.fl-wrapper[data-position$=-right]{right:.5em}.fl-wrapper[data-position$=-right] .fl-container{-webkit-transform:translateX(110%);-moz-transform:translateX(110%);-ms-transform:translateX(110%);transform:translateX(110%)}.fl-wrapper[data-position$=-left]{left:.5em}.fl-wrapper[data-position$=-left] .fl-container{-webkit-transform:translateX(-110%);-moz-transform:translateX(-110%);-ms-transform:translateX(-110%);transform:translateX(-110%)}.fl-wrapper[data-position$=-center]{left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.fl-wrapper[data-position=top-center] .fl-container{-webkit-transform:translateY(-100vh);-moz-transform:translateY(-100vh);-ms-transform:translateY(-100vh);transform:translateY(-100vh)}.fl-wrapper[data-position=bottom-center] .fl-container{-webkit-transform:translateY(100vh);-moz-transform:translateY(100vh);-ms-transform:translateY(100vh);transform:translateY(100vh)}.fl-container{color:var(--text-color);opacity:0;-webkit-transform:translateY(-20px);-moz-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px);-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;transition:all .5s ease-in-out}.fl-container.fl-show{opacity:1;-webkit-transform:translate(0)!important;-moz-transform:translate(0)!important;-ms-transform:translate(0)!important;transform:translate(0)!important}.fl-container.fl-rtl{direction:rtl}.fl-icon{border-radius:50%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#fff;display:inline-block;height:1em;margin:0;min-height:1em;min-width:1em;position:relative;-webkit-transition:all 1s;-moz-transition:all 1s;transition:all 1s;width:1em}.fl-icon:after,.fl-icon:before{border-width:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;content:"";position:absolute;-webkit-transition:all 1s;-moz-transition:all 1s;transition:all 1s}.fl-success .fl-icon:after,.fl-success .fl-icon:before{background-color:currentcolor;border-radius:.1em;height:.6em;left:.35em;top:.6em;-webkit-transform:rotate(-135deg);-moz-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg);-webkit-transform-origin:.08em .08em;-moz-transform-origin:.08em .08em;-ms-transform-origin:.08em .08em;transform-origin:.08em .08em;width:.16em}.fl-success .fl-icon:after{height:.16em;width:.4em}.fl-info .fl-icon:after,.fl-info .fl-icon:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.fl-info .fl-icon:before{height:.38em;top:.4em}.fl-info .fl-icon:after{-webkit-box-shadow:-.06em .19em,-.06em .44em,.06em .44em;box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.fl-warning .fl-icon:after,.fl-warning .fl-icon:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.fl-warning .fl-icon:before{height:.38em;top:.21em}.fl-warning .fl-icon:after{height:.13em;top:.65em}.fl-error .fl-icon:after,.fl-error .fl-icon:before{background-color:currentcolor;border-radius:.1em;height:.7em;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) rotate(-135deg);-moz-transform:translate(-50%,-50%) rotate(-135deg);-ms-transform:translate(-50%,-50%) rotate(-135deg);transform:translate(-50%,-50%) rotate(-135deg);width:.16em}.fl-error .fl-icon:after{-webkit-transform:translate(-50%,-50%) rotate(-45deg);-moz-transform:translate(-50%,-50%) rotate(-45deg);-ms-transform:translate(-50%,-50%) rotate(-45deg);transform:translate(-50%,-50%) rotate(-45deg)}.fl-success .fl-icon{background-color:var(--success-color)}.fl-info .fl-icon{background-color:var(--info-color)}.fl-warning .fl-icon{background-color:var(--warning-color)}.fl-error .fl-icon{background-color:var(--error-color)}.fl-progress-bar{bottom:0;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex;height:.125em;left:0;position:absolute;right:0}.fl-success .fl-progress-bar{background-color:var(--success-color-light)}.fl-success .fl-progress-bar .fl-progress{background-color:var(--success-color)}.fl-info .fl-progress-bar{background-color:var(--info-color-light)}.fl-info .fl-progress-bar .fl-progress{background-color:var(--info-color)}.fl-warning .fl-progress-bar{background-color:var(--warning-color-light)}.fl-warning .fl-progress-bar .fl-progress{background-color:var(--warning-color)}.fl-error .fl-progress-bar{background-color:var(--error-color-light)}.fl-error .fl-progress-bar .fl-progress{background-color:var(--error-color)} +body.fl-dark .fl-flasher,html.fl-dark .fl-flasher{--background-color:var(--dark-background-color);--text-color:var(--dark-text-color)}.fl-flasher{background-color:var(--background-color);-webkit-box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);color:var(--text-color);line-height:1.5;margin:.75em 0;padding:.75em;position:relative;word-break:break-word}.fl-flasher.fl-rtl{border-radius:0 .375em .375em 0}.fl-flasher:not(.fl-rtl){border-radius:.375em 0 0 .375em}.fl-flasher .fl-content{-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex}.fl-flasher .fl-icon{font-size:2.5em}.fl-flasher .fl-message,.fl-flasher .fl-title{display:block;line-height:1.25em;margin-left:1em;margin-right:1em}.fl-flasher .fl-title{font-size:1em;font-weight:700}.fl-flasher .fl-message{font-size:.875em;margin-top:.25em}.fl-flasher .fl-close{-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;align-items:center;background-color:transparent;border:none;color:#a8aaab;cursor:pointer;display:-webkit-inline-box;display:-webkit-inline-flex;display:-moz-inline-box;display:inline-flex;font-size:25px;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;justify-content:center;line-height:0;margin:-.5rem;padding:.5rem;position:absolute;right:.5rem;top:1rem;-webkit-transition:color .3s ease,-webkit-transform .3s ease;transition:color .3s ease,-webkit-transform .3s ease;-moz-transition:color .3s ease,transform .3s ease,-moz-transform .3s ease;transition:color .3s ease,transform .3s ease;transition:color .3s ease,transform .3s ease,-webkit-transform .3s ease,-moz-transform .3s ease}.fl-flasher .fl-close:hover{color:#8e9192;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.fl-flasher.fl-rtl .fl-close{left:.5rem;right:auto}.fl-flasher.fl-success{border-left:.8em solid var(--success-color)}.fl-flasher.fl-success.fl-rtl{border-left:none;border-right:.8em solid var(--success-color)}.fl-flasher.fl-success:not(.fl-rtl){border-left:.8em solid var(--success-color);border-right:none}.fl-flasher.fl-success .fl-title{color:var(--success-color)}.fl-flasher.fl-info{border-left:.8em solid var(--info-color)}.fl-flasher.fl-info.fl-rtl{border-left:none;border-right:.8em solid var(--info-color)}.fl-flasher.fl-info:not(.fl-rtl){border-left:.8em solid var(--info-color);border-right:none}.fl-flasher.fl-info .fl-title{color:var(--info-color)}.fl-flasher.fl-warning{border-left:.8em solid var(--warning-color)}.fl-flasher.fl-warning.fl-rtl{border-left:none;border-right:.8em solid var(--warning-color)}.fl-flasher.fl-warning:not(.fl-rtl){border-left:.8em solid var(--warning-color);border-right:none}.fl-flasher.fl-warning .fl-title{color:var(--warning-color)}.fl-flasher.fl-error{border-left:.8em solid var(--error-color)}.fl-flasher.fl-error.fl-rtl{border-left:none;border-right:.8em solid var(--error-color)}.fl-flasher.fl-error:not(.fl-rtl){border-left:.8em solid var(--error-color);border-right:none}.fl-flasher.fl-error .fl-title{color:var(--error-color)} \ No newline at end of file diff --git a/src/Prime/Resources/dist/flasher.min.js b/src/Prime/Resources/dist/flasher.min.js new file mode 100644 index 00000000..a7032d73 --- /dev/null +++ b/src/Prime/Resources/dist/flasher.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).flasher=t()}(this,(function(){"use strict";function e(e,t,s,n){return new(s||(s=Promise))((function(o,r){function i(e){try{a(n.next(e))}catch(e){r(e)}}function l(e){try{a(n.throw(e))}catch(e){r(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(i,l)}a((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,n){if("object"==typeof e?(e=(n=e).type,t=n.message,s=n.title):"object"==typeof t?(t=(n=t).message,s=n.title):"object"==typeof s&&(s=(n=s).title),void 0===t)throw new Error("message option is required");const o={type:e,message:t,title:s||e,options:n||{},metadata:{plugin:""}};this.renderOptions(n||{}),this.renderEnvelopes([o])}}class s extends t{constructor(e){super(),this.options={timeout:5e3,timeouts:{success:5e3,info:5e3,error:5e3,warning:5e3},fps:30,position:"top-right",direction:"top",rtl:!1,style:{}},this.theme=e}renderEnvelopes(e){const t=()=>e.forEach((e=>{var t,s;const n=null!==(t=this.options.timeouts[e.type])&&void 0!==t?t:this.options.timeout,o=Object.assign(Object.assign(Object.assign({},this.options),e.options),{timeout:null!==(s=e.options.timeout)&&void 0!==s?s:n});this.addToContainer(this.createContainer(o),e,o)}));"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}renderOptions(e){this.options=Object.assign(Object.assign({},this.options),e)}createContainer(e){let t=document.querySelector(`.fl-wrapper[data-position="${e.position}"]`);return t||(t=document.createElement("div"),t.className="fl-wrapper",t.dataset.position=e.position,Object.entries(e.style).forEach((([e,s])=>t.style.setProperty(e,s))),document.body.appendChild(t)),t.dataset.turboCache="false",t}addToContainer(e,t,s){var n;const o=this.stringToHTML(this.theme.render(t));o.classList.add(...("fl-container"+(s.rtl?" fl-rtl":"")).split(" ")),"bottom"===s.direction?e.append(o):e.prepend(o),requestAnimationFrame((()=>o.classList.add("fl-show"))),null===(n=o.querySelector(".fl-close"))||void 0===n||n.addEventListener("click",(e=>{e.stopPropagation(),this.removeNotification(o)})),this.addProgressBar(o,s)}addProgressBar(e,{timeout:t,fps:s}){if(t<=0||s<=0)return;const n=e.querySelector(".fl-progress-bar");if(!n)return;const o=document.createElement("span");o.classList.add("fl-progress"),n.append(o);const r=1e3/s;let i=0;const l=()=>{i+=1;const s=100*(1-r*(i/t));o.style.width=`${s}%`,s<=0&&(clearInterval(a),this.removeNotification(e))};let a=window.setInterval(l,r);e.addEventListener("mouseout",(()=>a=window.setInterval(l,r))),e.addEventListener("mouseover",(()=>clearInterval(a)))}removeNotification(e){e.classList.remove("fl-show"),e.ontransitionend=()=>{var t,s;!(null===(t=e.parentElement)||void 0===t?void 0:t.hasChildNodes())&&(null===(s=e.parentElement)||void 0===s||s.remove()),e.remove()}}stringToHTML(e){const t=document.createElement("template");return t.innerHTML=e.trim(),t.content.firstElementChild}}const n=new class extends t{constructor(){super(...arguments),this.defaultPlugin="flasher",this.plugins=new Map,this.themes=new Map}render(t){return e(this,void 0,void 0,(function*(){const e=this.resolveResponse(t);yield this.addAssets([{urls:e.styles,nonce:e.context.csp_style_nonce,type:"style"},{urls:e.scripts,nonce:e.context.csp_script_nonce,type:"script"}]),this.renderOptions(e.options),this.renderEnvelopes(e.envelopes)}))}renderEnvelopes(e){const t={};e.forEach((e=>{const s=this.resolvePluginAlias(e.metadata.plugin);t[s]=t[s]||[],t[s].push(e)})),Object.entries(t).forEach((([e,t])=>{this.use(e).renderEnvelopes(t)}))}renderOptions(e){Object.entries(e).forEach((([e,t])=>{this.use(e).renderOptions(t)}))}addPlugin(e,t){this.plugins.set(e,t)}addTheme(e,t){this.themes.set(e,t)}use(e){e=this.resolvePluginAlias(e),this.resolvePlugin(e);const t=this.plugins.get(e);if(!t)throw new Error(`Unable to resolve "${e}" plugin, did you forget to register it?`);return t}create(e){return this.use(e)}resolveResponse(e){const t=Object.assign({envelopes:[],options:{},scripts:[],styles:[],context:{}},e);return Object.entries(t.options).forEach((([e,s])=>{t.options[e]=this.resolveOptions(s)})),t.context.csp_style_nonce=t.context.csp_style_nonce||"",t.context.csp_script_nonce=t.context.csp_script_nonce||"",t.envelopes.forEach((s=>{s.metadata=s.metadata||{},s.metadata.plugin=this.resolvePluginAlias(s.metadata.plugin),this.addThemeStyles(t,s.metadata.plugin),s.options=this.resolveOptions(s.options),s.context=e.context})),t}resolveOptions(e){return Object.entries(e).forEach((([t,s])=>{e[t]=this.resolveFunction(s)})),e}resolveFunction(e){var t,s;if("string"!=typeof e)return e;const n=e.match(/^function\s*(\w*)\s*\(([^)]*)\)\s*\{([\s\S]*)\}$/)||e.match(/^\s*(\(([^)]*)\)|[^=]+)\s*=>\s*([\s\S]+)$/);if(!n)return e;const o=null!==(s=null===(t=n[2])||void 0===t?void 0:t.split(",").map((e=>e.trim())))&&void 0!==s?s:[];let r=n[3].trim();r.startsWith("{")||(r=`{ return ${r}; }`);try{return new Function(...o,r)}catch(t){return console.error("Error converting string to function:",t),e}}resolvePlugin(e){if(this.plugins.get(e)||!e.includes("theme."))return;const t=this.themes.get(e.replace("theme.",""));t&&this.addPlugin(e,new s(t))}resolvePluginAlias(e){return"flasher"===(e=e||this.defaultPlugin)?"theme.flasher":e}addAssets(t){return e(this,void 0,void 0,(function*(){for(const{urls:e,nonce:s,type:n}of t)for(const t of e)yield this.loadAsset(t,s,n)}))}loadAsset(t,s,n){return e(this,void 0,void 0,(function*(){if(document.querySelector(`${"style"===n?"link":"script"}[src="${t}"]`))return;const e=document.createElement("style"===n?"link":"script");return"style"===n?(e.rel="stylesheet",e.href=t):(e.type="text/javascript",e.src=t),s&&e.setAttribute("nonce",s),document.head.appendChild(e),new Promise(((s,n)=>{e.onload=()=>s(),e.onerror=()=>n(new Error(`Failed to load ${t}`))}))}))}addThemeStyles(e,t){var s;if("flasher"!==t&&!t.includes("theme."))return;t=t.replace("theme.","");const n=(null===(s=this.themes.get(t))||void 0===s?void 0:s.styles)||[];e.styles=Array.from(new Set([...e.styles,...n]))}};return n.addTheme("flasher",{render:e=>{const{type:t,title:s,message:n}=e;return`\n
\n
\n
\n
\n ${s}\n ${n}\n
\n \n
\n \n
`}}),n})); diff --git a/src/Prime/Resources/dist/index.d.ts b/src/Prime/Resources/dist/index.d.ts new file mode 100644 index 00000000..c51dbf1d --- /dev/null +++ b/src/Prime/Resources/dist/index.d.ts @@ -0,0 +1,3 @@ +import Flasher from './flasher'; +declare const flasher: Flasher; +export default flasher; diff --git a/src/Prime/Resources/dist/plugin.d.ts b/src/Prime/Resources/dist/plugin.d.ts new file mode 100644 index 00000000..92f833aa --- /dev/null +++ b/src/Prime/Resources/dist/plugin.d.ts @@ -0,0 +1,10 @@ +import type { Envelope, Options, PluginInterface } from './types'; +export declare abstract class AbstractPlugin implements PluginInterface { + abstract renderEnvelopes(envelopes: Envelope[]): void; + abstract renderOptions(options: Options): void; + success(message: string | Options, title?: string | Options, options?: Options): void; + error(message: string | Options, title?: string | Options, options?: Options): void; + info(message: string | Options, title?: string | Options, options?: Options): void; + warning(message: string | Options, title?: string | Options, options?: Options): void; + flash(type: string | Options, message: string | Options, title?: string | Options, options?: Options): void; +} diff --git a/src/Prime/Resources/dist/plugin.js b/src/Prime/Resources/dist/plugin.js new file mode 100644 index 00000000..b3f956b7 --- /dev/null +++ b/src/Prime/Resources/dist/plugin.js @@ -0,0 +1,47 @@ +class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } +} + +export { AbstractPlugin }; diff --git a/src/Prime/Resources/dist/theme.d.ts b/src/Prime/Resources/dist/theme.d.ts new file mode 100644 index 00000000..06f64063 --- /dev/null +++ b/src/Prime/Resources/dist/theme.d.ts @@ -0,0 +1,4 @@ +import type { Envelope } from './types'; +export declare const theme: { + render: (envelope: Envelope) => string; +}; diff --git a/src/Prime/Resources/dist/themes/flasher/index.d.ts b/src/Prime/Resources/dist/themes/flasher/index.d.ts new file mode 100644 index 00000000..72bb7564 --- /dev/null +++ b/src/Prime/Resources/dist/themes/flasher/index.d.ts @@ -0,0 +1,5 @@ +import './flasher.scss'; +import type { Envelope } from '../../types'; +export declare const flasherTheme: { + render: (envelope: Envelope) => string; +}; diff --git a/src/Prime/Resources/dist/types.d.ts b/src/Prime/Resources/dist/types.d.ts new file mode 100644 index 00000000..4efa5f23 --- /dev/null +++ b/src/Prime/Resources/dist/types.d.ts @@ -0,0 +1,38 @@ +export type Options = { + [option: string]: unknown; +}; +export type Context = { + [key: string]: unknown; +}; +export type Envelope = { + message: string; + title: string; + type: string; + options: Options; + metadata: { + plugin: string; + }; + context?: Context; +}; +export type Response = { + envelopes: Envelope[]; + options: { + [plugin: string]: Options; + }; + scripts: string[]; + styles: string[]; + context: Context; +}; +export type PluginInterface = { + success: (message: string | Options, title?: string | Options, options?: Options) => void; + error: (message: string | Options, title?: string | Options, options?: Options) => void; + info: (message: string | Options, title?: string | Options, options?: Options) => void; + warning: (message: string | Options, title?: string | Options, options?: Options) => void; + flash: (type: string | Options, message: string | Options, title?: string | Options, options?: Options) => void; + renderEnvelopes: (envelopes: Envelope[]) => void; + renderOptions: (options: Options) => void; +}; +export type Theme = { + styles?: string | string[]; + render: (envelope: Envelope) => string; +}; diff --git a/src/Prime/Resources/package.json b/src/Prime/Resources/package.json new file mode 100644 index 00000000..d638d33e --- /dev/null +++ b/src/Prime/Resources/package.json @@ -0,0 +1,16 @@ +{ + "name": "@flasher/flasher", + "version": "2.0.0", + "type": "module", + "license": "MIT", + "main": "dist/flasher.cjs.js", + "module": "dist/flasher.esm.js", + "browser": "dist/flasher.umd.js", + "types": "dist/index.d.ts", + "scripts": { + "ncu": "ncu -u" + }, + "devDependencies": { + "csstype": "^3.1.3" + } +} diff --git a/src/Prime/Resources/public/flasher.min.css b/src/Prime/Resources/public/flasher.min.css new file mode 100644 index 00000000..8d192211 --- /dev/null +++ b/src/Prime/Resources/public/flasher.min.css @@ -0,0 +1,2 @@ +:root{--background-color:#fff;--text-color:#4b5563;--dark-background-color:#0f172a;--dark-text-color:#fff;--success-color:#10b981;--info-color:#3b82f6;--warning-color:#f59e0b;--error-color:#ef4444;--success-color-light:#d4f7eb;--info-color-light:#d4e1f7;--warning-color-light:#fce8cf;--error-color-light:#f9d2d2}.fl-wrapper{position:fixed;-webkit-transition:all 1s ease-in-out;-moz-transition:all 1s ease-in-out;transition:all 1s ease-in-out;width:24em;z-index:10}@media only screen and (width <= 480px){.fl-wrapper{left:5%;right:5%;width:90%}}.fl-wrapper[data-position^=top-]{top:.5em}.fl-wrapper[data-position^=bottom-]{bottom:.5em}.fl-wrapper[data-position$=-right]{right:.5em}.fl-wrapper[data-position$=-right] .fl-container{-webkit-transform:translateX(110%);-moz-transform:translateX(110%);-ms-transform:translateX(110%);transform:translateX(110%)}.fl-wrapper[data-position$=-left]{left:.5em}.fl-wrapper[data-position$=-left] .fl-container{-webkit-transform:translateX(-110%);-moz-transform:translateX(-110%);-ms-transform:translateX(-110%);transform:translateX(-110%)}.fl-wrapper[data-position$=-center]{left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}.fl-wrapper[data-position=top-center] .fl-container{-webkit-transform:translateY(-100vh);-moz-transform:translateY(-100vh);-ms-transform:translateY(-100vh);transform:translateY(-100vh)}.fl-wrapper[data-position=bottom-center] .fl-container{-webkit-transform:translateY(100vh);-moz-transform:translateY(100vh);-ms-transform:translateY(100vh);transform:translateY(100vh)}.fl-container{color:var(--text-color);opacity:0;-webkit-transform:translateY(-20px);-moz-transform:translateY(-20px);-ms-transform:translateY(-20px);transform:translateY(-20px);-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;transition:all .5s ease-in-out}.fl-container.fl-show{opacity:1;-webkit-transform:translate(0)!important;-moz-transform:translate(0)!important;-ms-transform:translate(0)!important;transform:translate(0)!important}.fl-container.fl-rtl{direction:rtl}.fl-icon{border-radius:50%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#fff;display:inline-block;height:1em;margin:0;min-height:1em;min-width:1em;position:relative;-webkit-transition:all 1s;-moz-transition:all 1s;transition:all 1s;width:1em}.fl-icon:after,.fl-icon:before{border-width:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;content:"";position:absolute;-webkit-transition:all 1s;-moz-transition:all 1s;transition:all 1s}.fl-success .fl-icon:after,.fl-success .fl-icon:before{background-color:currentcolor;border-radius:.1em;height:.6em;left:.35em;top:.6em;-webkit-transform:rotate(-135deg);-moz-transform:rotate(-135deg);-ms-transform:rotate(-135deg);transform:rotate(-135deg);-webkit-transform-origin:.08em .08em;-moz-transform-origin:.08em .08em;-ms-transform-origin:.08em .08em;transform-origin:.08em .08em;width:.16em}.fl-success .fl-icon:after{height:.16em;width:.4em}.fl-info .fl-icon:after,.fl-info .fl-icon:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.fl-info .fl-icon:before{height:.38em;top:.4em}.fl-info .fl-icon:after{-webkit-box-shadow:-.06em .19em,-.06em .44em,.06em .44em;box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.fl-warning .fl-icon:after,.fl-warning .fl-icon:before{background-color:currentcolor;border-radius:.03em;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:.15em}.fl-warning .fl-icon:before{height:.38em;top:.21em}.fl-warning .fl-icon:after{height:.13em;top:.65em}.fl-error .fl-icon:after,.fl-error .fl-icon:before{background-color:currentcolor;border-radius:.1em;height:.7em;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) rotate(-135deg);-moz-transform:translate(-50%,-50%) rotate(-135deg);-ms-transform:translate(-50%,-50%) rotate(-135deg);transform:translate(-50%,-50%) rotate(-135deg);width:.16em}.fl-error .fl-icon:after{-webkit-transform:translate(-50%,-50%) rotate(-45deg);-moz-transform:translate(-50%,-50%) rotate(-45deg);-ms-transform:translate(-50%,-50%) rotate(-45deg);transform:translate(-50%,-50%) rotate(-45deg)}.fl-success .fl-icon{background-color:var(--success-color)}.fl-info .fl-icon{background-color:var(--info-color)}.fl-warning .fl-icon{background-color:var(--warning-color)}.fl-error .fl-icon{background-color:var(--error-color)}.fl-progress-bar{bottom:0;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex;height:.125em;left:0;position:absolute;right:0}.fl-success .fl-progress-bar{background-color:var(--success-color-light)}.fl-success .fl-progress-bar .fl-progress{background-color:var(--success-color)}.fl-info .fl-progress-bar{background-color:var(--info-color-light)}.fl-info .fl-progress-bar .fl-progress{background-color:var(--info-color)}.fl-warning .fl-progress-bar{background-color:var(--warning-color-light)}.fl-warning .fl-progress-bar .fl-progress{background-color:var(--warning-color)}.fl-error .fl-progress-bar{background-color:var(--error-color-light)}.fl-error .fl-progress-bar .fl-progress{background-color:var(--error-color)} +body.fl-dark .fl-flasher,html.fl-dark .fl-flasher{--background-color:var(--dark-background-color);--text-color:var(--dark-text-color)}.fl-flasher{background-color:var(--background-color);-webkit-box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);color:var(--text-color);line-height:1.5;margin:.75em 0;padding:.75em;position:relative;word-break:break-word}.fl-flasher.fl-rtl{border-radius:0 .375em .375em 0}.fl-flasher:not(.fl-rtl){border-radius:.375em 0 0 .375em}.fl-flasher .fl-content{-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:flex}.fl-flasher .fl-icon{font-size:2.5em}.fl-flasher .fl-message,.fl-flasher .fl-title{display:block;line-height:1.25em;margin-left:1em;margin-right:1em}.fl-flasher .fl-title{font-size:1em;font-weight:700}.fl-flasher .fl-message{font-size:.875em;margin-top:.25em}.fl-flasher .fl-close{-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;align-items:center;background-color:transparent;border:none;color:#a8aaab;cursor:pointer;display:-webkit-inline-box;display:-webkit-inline-flex;display:-moz-inline-box;display:inline-flex;font-size:25px;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;justify-content:center;line-height:0;margin:-.5rem;padding:.5rem;position:absolute;right:.5rem;top:1rem;-webkit-transition:color .3s ease,-webkit-transform .3s ease;transition:color .3s ease,-webkit-transform .3s ease;-moz-transition:color .3s ease,transform .3s ease,-moz-transform .3s ease;transition:color .3s ease,transform .3s ease;transition:color .3s ease,transform .3s ease,-webkit-transform .3s ease,-moz-transform .3s ease}.fl-flasher .fl-close:hover{color:#8e9192;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1)}.fl-flasher.fl-rtl .fl-close{left:.5rem;right:auto}.fl-flasher.fl-success{border-left:.8em solid var(--success-color)}.fl-flasher.fl-success.fl-rtl{border-left:none;border-right:.8em solid var(--success-color)}.fl-flasher.fl-success:not(.fl-rtl){border-left:.8em solid var(--success-color);border-right:none}.fl-flasher.fl-success .fl-title{color:var(--success-color)}.fl-flasher.fl-info{border-left:.8em solid var(--info-color)}.fl-flasher.fl-info.fl-rtl{border-left:none;border-right:.8em solid var(--info-color)}.fl-flasher.fl-info:not(.fl-rtl){border-left:.8em solid var(--info-color);border-right:none}.fl-flasher.fl-info .fl-title{color:var(--info-color)}.fl-flasher.fl-warning{border-left:.8em solid var(--warning-color)}.fl-flasher.fl-warning.fl-rtl{border-left:none;border-right:.8em solid var(--warning-color)}.fl-flasher.fl-warning:not(.fl-rtl){border-left:.8em solid var(--warning-color);border-right:none}.fl-flasher.fl-warning .fl-title{color:var(--warning-color)}.fl-flasher.fl-error{border-left:.8em solid var(--error-color)}.fl-flasher.fl-error.fl-rtl{border-left:none;border-right:.8em solid var(--error-color)}.fl-flasher.fl-error:not(.fl-rtl){border-left:.8em solid var(--error-color);border-right:none}.fl-flasher.fl-error .fl-title{color:var(--error-color)} \ No newline at end of file diff --git a/src/Prime/Resources/public/flasher.min.js b/src/Prime/Resources/public/flasher.min.js new file mode 100644 index 00000000..a7032d73 --- /dev/null +++ b/src/Prime/Resources/public/flasher.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).flasher=t()}(this,(function(){"use strict";function e(e,t,s,n){return new(s||(s=Promise))((function(o,r){function i(e){try{a(n.next(e))}catch(e){r(e)}}function l(e){try{a(n.throw(e))}catch(e){r(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(i,l)}a((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,n){if("object"==typeof e?(e=(n=e).type,t=n.message,s=n.title):"object"==typeof t?(t=(n=t).message,s=n.title):"object"==typeof s&&(s=(n=s).title),void 0===t)throw new Error("message option is required");const o={type:e,message:t,title:s||e,options:n||{},metadata:{plugin:""}};this.renderOptions(n||{}),this.renderEnvelopes([o])}}class s extends t{constructor(e){super(),this.options={timeout:5e3,timeouts:{success:5e3,info:5e3,error:5e3,warning:5e3},fps:30,position:"top-right",direction:"top",rtl:!1,style:{}},this.theme=e}renderEnvelopes(e){const t=()=>e.forEach((e=>{var t,s;const n=null!==(t=this.options.timeouts[e.type])&&void 0!==t?t:this.options.timeout,o=Object.assign(Object.assign(Object.assign({},this.options),e.options),{timeout:null!==(s=e.options.timeout)&&void 0!==s?s:n});this.addToContainer(this.createContainer(o),e,o)}));"loading"===document.readyState?document.addEventListener("DOMContentLoaded",t):t()}renderOptions(e){this.options=Object.assign(Object.assign({},this.options),e)}createContainer(e){let t=document.querySelector(`.fl-wrapper[data-position="${e.position}"]`);return t||(t=document.createElement("div"),t.className="fl-wrapper",t.dataset.position=e.position,Object.entries(e.style).forEach((([e,s])=>t.style.setProperty(e,s))),document.body.appendChild(t)),t.dataset.turboCache="false",t}addToContainer(e,t,s){var n;const o=this.stringToHTML(this.theme.render(t));o.classList.add(...("fl-container"+(s.rtl?" fl-rtl":"")).split(" ")),"bottom"===s.direction?e.append(o):e.prepend(o),requestAnimationFrame((()=>o.classList.add("fl-show"))),null===(n=o.querySelector(".fl-close"))||void 0===n||n.addEventListener("click",(e=>{e.stopPropagation(),this.removeNotification(o)})),this.addProgressBar(o,s)}addProgressBar(e,{timeout:t,fps:s}){if(t<=0||s<=0)return;const n=e.querySelector(".fl-progress-bar");if(!n)return;const o=document.createElement("span");o.classList.add("fl-progress"),n.append(o);const r=1e3/s;let i=0;const l=()=>{i+=1;const s=100*(1-r*(i/t));o.style.width=`${s}%`,s<=0&&(clearInterval(a),this.removeNotification(e))};let a=window.setInterval(l,r);e.addEventListener("mouseout",(()=>a=window.setInterval(l,r))),e.addEventListener("mouseover",(()=>clearInterval(a)))}removeNotification(e){e.classList.remove("fl-show"),e.ontransitionend=()=>{var t,s;!(null===(t=e.parentElement)||void 0===t?void 0:t.hasChildNodes())&&(null===(s=e.parentElement)||void 0===s||s.remove()),e.remove()}}stringToHTML(e){const t=document.createElement("template");return t.innerHTML=e.trim(),t.content.firstElementChild}}const n=new class extends t{constructor(){super(...arguments),this.defaultPlugin="flasher",this.plugins=new Map,this.themes=new Map}render(t){return e(this,void 0,void 0,(function*(){const e=this.resolveResponse(t);yield this.addAssets([{urls:e.styles,nonce:e.context.csp_style_nonce,type:"style"},{urls:e.scripts,nonce:e.context.csp_script_nonce,type:"script"}]),this.renderOptions(e.options),this.renderEnvelopes(e.envelopes)}))}renderEnvelopes(e){const t={};e.forEach((e=>{const s=this.resolvePluginAlias(e.metadata.plugin);t[s]=t[s]||[],t[s].push(e)})),Object.entries(t).forEach((([e,t])=>{this.use(e).renderEnvelopes(t)}))}renderOptions(e){Object.entries(e).forEach((([e,t])=>{this.use(e).renderOptions(t)}))}addPlugin(e,t){this.plugins.set(e,t)}addTheme(e,t){this.themes.set(e,t)}use(e){e=this.resolvePluginAlias(e),this.resolvePlugin(e);const t=this.plugins.get(e);if(!t)throw new Error(`Unable to resolve "${e}" plugin, did you forget to register it?`);return t}create(e){return this.use(e)}resolveResponse(e){const t=Object.assign({envelopes:[],options:{},scripts:[],styles:[],context:{}},e);return Object.entries(t.options).forEach((([e,s])=>{t.options[e]=this.resolveOptions(s)})),t.context.csp_style_nonce=t.context.csp_style_nonce||"",t.context.csp_script_nonce=t.context.csp_script_nonce||"",t.envelopes.forEach((s=>{s.metadata=s.metadata||{},s.metadata.plugin=this.resolvePluginAlias(s.metadata.plugin),this.addThemeStyles(t,s.metadata.plugin),s.options=this.resolveOptions(s.options),s.context=e.context})),t}resolveOptions(e){return Object.entries(e).forEach((([t,s])=>{e[t]=this.resolveFunction(s)})),e}resolveFunction(e){var t,s;if("string"!=typeof e)return e;const n=e.match(/^function\s*(\w*)\s*\(([^)]*)\)\s*\{([\s\S]*)\}$/)||e.match(/^\s*(\(([^)]*)\)|[^=]+)\s*=>\s*([\s\S]+)$/);if(!n)return e;const o=null!==(s=null===(t=n[2])||void 0===t?void 0:t.split(",").map((e=>e.trim())))&&void 0!==s?s:[];let r=n[3].trim();r.startsWith("{")||(r=`{ return ${r}; }`);try{return new Function(...o,r)}catch(t){return console.error("Error converting string to function:",t),e}}resolvePlugin(e){if(this.plugins.get(e)||!e.includes("theme."))return;const t=this.themes.get(e.replace("theme.",""));t&&this.addPlugin(e,new s(t))}resolvePluginAlias(e){return"flasher"===(e=e||this.defaultPlugin)?"theme.flasher":e}addAssets(t){return e(this,void 0,void 0,(function*(){for(const{urls:e,nonce:s,type:n}of t)for(const t of e)yield this.loadAsset(t,s,n)}))}loadAsset(t,s,n){return e(this,void 0,void 0,(function*(){if(document.querySelector(`${"style"===n?"link":"script"}[src="${t}"]`))return;const e=document.createElement("style"===n?"link":"script");return"style"===n?(e.rel="stylesheet",e.href=t):(e.type="text/javascript",e.src=t),s&&e.setAttribute("nonce",s),document.head.appendChild(e),new Promise(((s,n)=>{e.onload=()=>s(),e.onerror=()=>n(new Error(`Failed to load ${t}`))}))}))}addThemeStyles(e,t){var s;if("flasher"!==t&&!t.includes("theme."))return;t=t.replace("theme.","");const n=(null===(s=this.themes.get(t))||void 0===s?void 0:s.styles)||[];e.styles=Array.from(new Set([...e.styles,...n]))}};return n.addTheme("flasher",{render:e=>{const{type:t,title:s,message:n}=e;return`\n
\n
\n
\n
\n ${s}\n ${n}\n
\n \n
\n \n
`}}),n})); diff --git a/src/Prime/Response/Presenter/ArrayPresenter.php b/src/Prime/Response/Presenter/ArrayPresenter.php index 690b6f07..581f3da4 100644 --- a/src/Prime/Response/Presenter/ArrayPresenter.php +++ b/src/Prime/Response/Presenter/ArrayPresenter.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response\Presenter; @@ -12,9 +9,21 @@ use Flasher\Prime\Response\Response; final class ArrayPresenter implements PresenterInterface { /** - * {@inheritdoc} + * @return array{ + * envelopes: array, + * metadata: array, + * }>, + * scripts: string[], + * styles: string[], + * options: array>, + * context: array, + * } */ - public function render(Response $response) + public function render(Response $response): array { return $response->toArray(); } diff --git a/src/Prime/Response/Presenter/HtmlPresenter.php b/src/Prime/Response/Presenter/HtmlPresenter.php index 1d8a80b2..58603f6c 100644 --- a/src/Prime/Response/Presenter/HtmlPresenter.php +++ b/src/Prime/Response/Presenter/HtmlPresenter.php @@ -1,129 +1,148 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response\Presenter; use Flasher\Prime\Response\Response; +use Livewire\LivewireManager; final class HtmlPresenter implements PresenterInterface { - const FLASHER_FLASH_BAG_PLACE_HOLDER = 'FLASHER_FLASH_BAG_PLACE_HOLDER'; - const HEAD_END_PLACE_HOLDER = ''; - const BODY_END_PLACE_HOLDER = ''; + public const FLASHER_REPLACE_ME = '/** {--FLASHER_REPLACE_ME--} **/'; + public const HEAD_END_PLACE_HOLDER = ''; + public const BODY_END_PLACE_HOLDER = ''; /** - * {@inheritdoc} + * @throws \JsonException */ - public function render(Response $response) + public function render(Response $response): string { - $options = json_encode($response->toArray(true)); + /** @var array{csp_script_nonce?: ?string, envelopes_only?: bool} $context */ $context = $response->getContext(); - if (isset($context['envelopes_only']) && true === $context['envelopes_only']) { - return $options; + $options = $response->toArray(); + $html = ''; + + foreach ($options['envelopes'] as $index => $envelope) { + if (isset($envelope['metadata']['html'])) { + $html .= $envelope['metadata']['html']; + unset($options['envelopes'][$index]); + } } - $rootScript = $response->getRootScript(); - $placeHolder = self::FLASHER_FLASH_BAG_PLACE_HOLDER; + $options['envelopes'] = array_values($options['envelopes']); + $jsonOptions = json_encode($options, \JSON_THROW_ON_ERROR); + + if ($context['envelopes_only'] ?? false) { + return $jsonOptions; + } + + $nonce = $context['csp_script_nonce'] ?? null; + + $mainScript = $response->getMainScript(); + $replaceMe = self::FLASHER_REPLACE_ME; + $nonceAttribute = $nonce ? " nonce='{$nonce}'" : ''; + $scriptTagWithNonce = $nonce ? "tag.setAttribute('nonce', '{$nonce}');" : ''; $livewireListener = $this->getLivewireListenerScript(); - return << -(function() { - var rootScript = '{$rootScript}'; - var {$placeHolder} = {}; - var options = mergeOptions({$options}, {$placeHolder}); + return $html.<< + (function(window, document) { + const merge = (first, second) => { + if (Array.isArray(first) && Array.isArray(second)) { + return [...first, ...second.filter(item => !first.includes(item))]; + } - function mergeOptions(first, second) { - return { - context: merge(first.context || {}, second.context || {}), - envelopes: merge(first.envelopes || [], second.envelopes || []), - options: merge(first.options || {}, second.options || {}), - scripts: merge(first.scripts || [], second.scripts || []), - styles: merge(first.styles || [], second.styles || []), - }; - } + if (typeof first === 'object' && typeof second === 'object') { + for (const [key, value] of Object.entries(second)) { + first[key] = key in first ? { ...first[key], ...value } : value; + } + return first; + } - function merge(first, second) { - if (Array.isArray(first) && Array.isArray(second)) { - return first.concat(second).filter(function(item, index, array) { - return array.indexOf(item) === index; - }); - } + return undefined; + }; - return Object.assign({}, first, second); - } + const mergeOptions = (...options) => { + const result = {}; - function renderOptions(options) { - if(!window.hasOwnProperty('flasher')) { - console.error('Flasher is not loaded'); - return; - } + options.forEach(option => { + Object.entries(option).forEach(([key, value]) => { + result[key] = key in result ? merge(result[key], value) : value; + }); + }); - requestAnimationFrame(function () { - window.flasher.render(options); - }); - } + return result; + }; - function render(options) { - if ('loading' !== document.readyState) { - renderOptions(options); + const renderCallback = (options) => { + if(!window.flasher) { + throw new Error('Flasher is not loaded'); + } - return; - } + window.flasher.render(options); + }; - document.addEventListener('DOMContentLoaded', function() { - renderOptions(options); - }); - } + const render = (options) => { + if (options instanceof Event) { + options = options.detail; + } - if (1 === document.querySelectorAll('script.flasher-js').length) { - document.addEventListener('flasher:render', function (event) { - render(event.detail); - }); + if (['interactive', 'complete'].includes(document.readyState)) { + renderCallback(options); + } else { + document.addEventListener('DOMContentLoaded', () => renderCallback(options)); + } + }; - {$livewireListener} - } + const addScriptAndRender = (options) => { + const mainScript = '{$mainScript}'; - if (window.hasOwnProperty('flasher') || !rootScript || document.querySelector('script[src="' + rootScript + '"]')) { - render(options); - } else { - var tag = document.createElement('script'); - tag.setAttribute('src', rootScript); - tag.setAttribute('type', 'text/javascript'); - tag.onload = function () { - render(options); - }; + if (window.flasher || !mainScript || document.querySelector('script[src="' + mainScript + '"]')) { + render(options); + } else { + const tag = document.createElement('script'); + tag.src = mainScript; + tag.type = 'text/javascript'; + {$scriptTagWithNonce} + tag.onload = () => render(options); - document.head.appendChild(tag); - } -})(); - -JAVASCRIPT; + document.head.appendChild(tag); + } + }; + + const addRenderListener = () => { + if (1 === document.querySelectorAll('script.flasher-js').length) { + document.addEventListener('flasher:render', render); + } + + {$livewireListener} + }; + + const options = []; + options.push({$jsonOptions}); + {$replaceMe} + addScriptAndRender(mergeOptions(...options)); + addRenderListener(); + })(window, document); + + JAVASCRIPT; } /** * Generate the script for Livewire event handling. - * - * @return string */ - private function getLivewireListenerScript() + private function getLivewireListenerScript(): string { - if (!class_exists('Livewire\LivewireManager')) { + if (!class_exists(LivewireManager::class)) { return ''; } return << { + document.querySelectorAll('.fl-no-cache').forEach(el => el.remove()); + }); + JAVASCRIPT; } } diff --git a/src/Prime/Response/Presenter/PresenterInterface.php b/src/Prime/Response/Presenter/PresenterInterface.php index 97515384..8691fc12 100644 --- a/src/Prime/Response/Presenter/PresenterInterface.php +++ b/src/Prime/Response/Presenter/PresenterInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response\Presenter; @@ -11,8 +8,5 @@ use Flasher\Prime\Response\Response; interface PresenterInterface { - /** - * @return mixed - */ - public function render(Response $response); + public function render(Response $response): mixed; } diff --git a/src/Prime/Response/Resource/ResourceManager.php b/src/Prime/Response/Resource/ResourceManager.php index 1fcf86fa..39b06769 100644 --- a/src/Prime/Response/Resource/ResourceManager.php +++ b/src/Prime/Response/Resource/ResourceManager.php @@ -1,241 +1,80 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response\Resource; -use Flasher\Prime\Config\Config; -use Flasher\Prime\Config\ConfigInterface; +use Flasher\Prime\Asset\AssetManagerInterface; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Response\Response; -use Flasher\Prime\Stamp\HandlerStamp; -use Flasher\Prime\Stamp\ViewStamp; +use Flasher\Prime\Stamp\HtmlStamp; +use Flasher\Prime\Stamp\PluginStamp; use Flasher\Prime\Template\TemplateEngineInterface; -final class ResourceManager implements ResourceManagerInterface +/** + * @phpstan-type ResourceType array{ + * scripts?: string[], + * styles?: string[], + * options?: array, + * view?: string, + * } + */ +final readonly class ResourceManager implements ResourceManagerInterface { /** - * @var ConfigInterface + * @phpstan-param ResourceType[] $resources */ - private $config; - - /** - * @var TemplateEngineInterface|null - */ - private $templateEngine; - - /** - * @var array - */ - private $scripts = array(); - - /** - * @var array - */ - private $styles = array(); - - /** - * @var array> - */ - private $options = array(); - - public function __construct(ConfigInterface $config = null, TemplateEngineInterface $templateEngine = null) - { - $this->config = $config ?: new Config(); - $this->templateEngine = $templateEngine; + public function __construct( + private TemplateEngineInterface $templateEngine, + private AssetManagerInterface $assetManager, + private string $mainScript, + private array $resources, + ) { } - /** - * {@inheritdoc} - */ - public function buildResponse(Response $response) + public function populateResponse(Response $response): Response { - $rootScript = $this->selectAssets($this->config->get('root_script')); - $rootScript = is_string($rootScript) ? $rootScript : null; + $response->setMainScript($this->assetManager->getPath($this->mainScript)); - $response->setRootScript($rootScript); - - $handlers = array(); + $plugins = []; foreach ($response->getEnvelopes() as $envelope) { - $handler = $this->resolveHandler($envelope); - if (null === $handler || \in_array($handler, $handlers, true)) { + $plugin = $envelope->get(PluginStamp::class)?->getPlugin(); + if (null === $plugin) { continue; } - $handlers[] = $handler; - $this->populateResponse($response, $handler); + $resource = $this->resources[$plugin] ?? []; + if (isset($resource['view'])) { + $this->addHtmlStamp($resource['view'], $envelope); + } + + if (\in_array($plugin, $plugins, true)) { + continue; + } + + $plugins[] = $plugin; + $this->addResources($response, $plugin); } return $response; } - /** - * {@inheritdoc} - */ - public function addScripts($handler, array $scripts) + private function addHtmlStamp(string $view, Envelope $envelope): void { - $this->scripts[$handler] = $scripts; + $compiled = $this->templateEngine->render($view, ['envelope' => $envelope]); + + $envelope->withStamp(new HtmlStamp($compiled)); } - /** - * {@inheritdoc} - */ - public function addStyles($handler, array $styles) + private function addResources(Response $response, string $plugin): void { - $this->styles[$handler] = $styles; - } - - /** - * {@inheritdoc} - */ - public function addOptions($handler, array $options) - { - $this->options[$handler] = $options; - } - - /** - * @return ConfigInterface - */ - public function getConfig() - { - return $this->config; - } - - /** - * @param mixed $assets - * - * @return string[]|string - */ - private function selectAssets($assets) - { - $use = $this->config->get('use_cdn', true) ? 'cdn' : 'local'; - - return is_array($assets) && array_key_exists($use, $assets) ? $assets[$use] : $assets; - } - - /** - * @return string|null - */ - private function resolveHandler(Envelope $envelope) - { - $handlerStamp = $envelope->get('Flasher\Prime\Stamp\HandlerStamp'); - if (!$handlerStamp instanceof HandlerStamp) { - return null; + $resource = $this->resources[$plugin] ?? []; + if ([] === $resource && str_starts_with($plugin, 'theme.')) { + $resource = $this->resources['flasher'] ?? []; } - $handler = $handlerStamp->getHandler(); - if ('flasher' !== $handler && 0 !== strpos($handler, 'theme.')) { - return $handler; - } - - $theme = $this->getTheme($handler); - if (null === $theme) { - return $handler; - } - - if (!isset($this->scripts[$handler])) { - $scripts = $this->config->get('themes.'.$theme.'.scripts', array()); - $this->addScripts('theme.'.$theme, (array) $scripts); - } - - if (!isset($this->styles[$handler])) { - $styles = $this->config->get('themes.'.$theme.'.styles', array()); - $this->addStyles('theme.'.$theme, (array) $styles); - } - - if (!isset($this->options[$handler])) { - $options = $this->config->get('themes.'.$theme.'.options', array()); - $this->addOptions('theme.'.$theme, $options); - } - - if ('flasher' === $theme) { - $scripts = $this->config->get('scripts', array()); - - if (isset($this->scripts['theme.flasher'])) { - $scripts = array_merge($this->scripts['theme.flasher'], $scripts); - } - - if (isset($this->scripts['flasher'])) { - $scripts = array_merge($this->scripts['flasher'], $scripts); - } - - $this->addScripts('theme.flasher', (array) $scripts); - - $styles = $this->config->get('styles', array()); - if (isset($this->styles['theme.flasher'])) { - $styles = array_merge($this->styles['theme.flasher'], $styles); - } - if (isset($this->scripts['flasher'])) { - $styles = array_merge($this->styles['flasher'], $styles); - } - $this->addStyles('theme.flasher', (array) $styles); - - $options = $this->config->get('options', array()); - if (isset($this->options['theme.flasher'])) { - $options = array_merge($this->options['theme.flasher'], $options); - } - if (isset($this->options['flasher'])) { - $options = array_merge($this->options['flasher'], $options); - } - $this->addOptions('theme.flasher', $options); - } - - /** @var string|null $view */ - $view = $this->config->get('themes.'.$theme.'.view'); - if (null === $view || null === $this->templateEngine) { - return 'theme.'.$theme; - } - - $compiled = $this->templateEngine->render($view, array('envelope' => $envelope)); - $envelope->withStamp(new ViewStamp($compiled)); - - return 'theme.'.$theme; - } - - /** - * @param string $handler - * - * @return string|null - */ - private function getTheme($handler) - { - if ('flasher' === $handler) { - return 'flasher'; - } - - if (0 === strpos($handler, 'theme.')) { - return substr($handler, \strlen('theme.')); - } - - return null; - } - - /** - * @param string $handler - * - * @return void - */ - private function populateResponse(Response $response, $handler) - { - if (isset($this->scripts[$handler])) { - $scripts = $this->selectAssets($this->scripts[$handler]); - $scripts = is_array($scripts) ? $scripts : array(); - - $response->addScripts($scripts); - } - - if (isset($this->styles[$handler])) { - $styles = $this->selectAssets($this->styles[$handler]); - $styles = is_array($styles) ? $styles : array(); - - $response->addStyles($styles); - } - - if (isset($this->options[$handler])) { - $response->addOptions($handler, $this->options[$handler]); - } + $response->addScripts($this->assetManager->getPaths($resource['scripts'] ?? [])); + $response->addStyles($this->assetManager->getPaths($resource['styles'] ?? [])); + $response->addOptions($plugin, $resource['options'] ?? []); } } diff --git a/src/Prime/Response/Resource/ResourceManagerInterface.php b/src/Prime/Response/Resource/ResourceManagerInterface.php index ba1fee3f..0793f9a7 100644 --- a/src/Prime/Response/Resource/ResourceManagerInterface.php +++ b/src/Prime/Response/Resource/ResourceManagerInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response\Resource; @@ -11,32 +8,5 @@ use Flasher\Prime\Response\Response; interface ResourceManagerInterface { - /** - * @return Response - */ - public function buildResponse(Response $response); - - /** - * @param string $handler - * @param string[] $scripts - * - * @return void - */ - public function addScripts($handler, array $scripts); - - /** - * @param string $handler - * @param string[] $styles - * - * @return void - */ - public function addStyles($handler, array $styles); - - /** - * @param string $handler - * @param array $options - * - * @return void - */ - public function addOptions($handler, array $options); + public function populateResponse(Response $response): Response; } diff --git a/src/Prime/Response/Response.php b/src/Prime/Response/Response.php index cb33ec31..924367b5 100644 --- a/src/Prime/Response/Response.php +++ b/src/Prime/Response/Response.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response; @@ -11,123 +8,101 @@ use Flasher\Prime\Notification\Envelope; final class Response { - /** - * @var Envelope[] - */ - private $envelopes; - - /** - * @var string|null - */ - private $rootScript; + private string $mainScript = ''; /** * @var string[] */ - private $scripts = array(); + private array $scripts = []; /** * @var string[] */ - private $styles = array(); + private array $styles = []; /** * @var array> */ - private $options = array(); + private array $options = []; /** - * @var array + * @param Envelope[] $envelopes the array of notification envelopes + * @param array $context additional context for the response */ - private $context; - - /** - * @param Envelope[] $envelopes - * @param array $context - */ - public function __construct(array $envelopes, array $context) + public function __construct(private readonly array $envelopes, private readonly array $context) { - $this->envelopes = $envelopes; - $this->context = $context; } /** - * @param string[] $scripts + * Add scripts to the response. * - * @return void + * @param string[] $scripts the scripts to add */ - public function addScripts(array $scripts) + public function addScripts(array $scripts): void { - $this->scripts = array_merge($this->scripts, $scripts); + $this->scripts = $this->addItems($this->scripts, $scripts); } /** - * @param string[] $styles + * Add styles to the response. * - * @return void + * @param string[] $styles the styles to add */ - public function addStyles(array $styles) + public function addStyles(array $styles): void { - $this->styles = array_merge($this->styles, $styles); + $this->styles = $this->addItems($this->styles, $styles); } /** - * @param string $alias - * @param array $options + * Add or merge options for a specific alias. * - * @return void + * @param string $alias the alias for the options + * @param array $options the options to add or merge */ - public function addOptions($alias, array $options) + public function addOptions(string $alias, array $options): void { + $options = array_merge($this->options[$alias] ?? [], $options); $this->options[$alias] = $options; } /** * @return Envelope[] */ - public function getEnvelopes() + public function getEnvelopes(): array { return $this->envelopes; } - /** - * @return string|null - */ - public function getRootScript() + public function getMainScript(): string { - return $this->rootScript; + return $this->mainScript; } - /** - * @param string|null $rootScript - * - * @return void - */ - public function setRootScript($rootScript) + public function setMainScript(string $mainScript): void { - $this->rootScript = $rootScript; + $this->mainScript = $mainScript; } /** * @return string[] */ - public function getStyles() + public function getStyles(): array { - return array_values(array_filter(array_unique($this->styles))); + return $this->styles; } /** * @return string[] */ - public function getScripts() + public function getScripts(): array { - return array_values(array_filter(array_unique($this->scripts))); + return $this->scripts; } /** * @return array> */ - public function getOptions() + public function getOptions(): array { return $this->options; } @@ -135,33 +110,50 @@ final class Response /** * @return array */ - public function getContext() + public function getContext(): array { return $this->context; } /** - * @param mixed $filter - * - * @return array + * @return array{ + * envelopes: array, + * metadata: array, + * }>, + * scripts: string[], + * styles: string[], + * options: array>, + * context: array, + * } */ - public function toArray($filter = false) + public function toArray(): array { - $envelopes = array_map(function (Envelope $envelope) { - return $envelope->toArray(); - }, $this->getEnvelopes()); + $envelopes = array_map(static fn (Envelope $envelope): array => $envelope->toArray(), $this->envelopes); - $response = array( + return [ 'envelopes' => $envelopes, - 'scripts' => $this->getScripts(), - 'styles' => $this->getStyles(), - 'options' => $this->getOptions(), - ); + 'scripts' => $this->scripts, + 'styles' => $this->styles, + 'options' => $this->options, + 'context' => $this->context, + ]; + } - if (false === $filter) { - return $response; - } + /** + * @param string[] $existingItems + * @param string[] $newItems + * + * @return string[] + */ + private function addItems(array $existingItems, array $newItems): array + { + $items = array_merge($existingItems, $newItems); + $items = array_filter(array_unique($items)); - return array_filter($response); + return array_values($items); } } diff --git a/src/Prime/Response/ResponseManager.php b/src/Prime/Response/ResponseManager.php index 44a4d661..a6f82b44 100644 --- a/src/Prime/Response/ResponseManager.php +++ b/src/Prime/Response/ResponseManager.php @@ -1,72 +1,47 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response; use Flasher\Prime\EventDispatcher\Event\PresentationEvent; use Flasher\Prime\EventDispatcher\Event\ResponseEvent; -use Flasher\Prime\EventDispatcher\EventDispatcher; use Flasher\Prime\EventDispatcher\EventDispatcherInterface; +use Flasher\Prime\Exception\PresenterNotFoundException; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Response\Presenter\ArrayPresenter; use Flasher\Prime\Response\Presenter\HtmlPresenter; use Flasher\Prime\Response\Presenter\PresenterInterface; -use Flasher\Prime\Response\Resource\ResourceManager; use Flasher\Prime\Response\Resource\ResourceManagerInterface; -use Flasher\Prime\Storage\StorageManager; use Flasher\Prime\Storage\StorageManagerInterface; final class ResponseManager implements ResponseManagerInterface { /** - * @var array + * @var callable[]|PresenterInterface[] */ - private $presenters; + private array $presenters = []; - /** - * @var ResourceManagerInterface - */ - private $resourceManager; - - /** - * @var StorageManagerInterface - */ - private $storageManager; - - /** - * @var EventDispatcherInterface - */ - private $eventDispatcher; - - public function __construct(ResourceManagerInterface $resourceManager = null, StorageManagerInterface $storageManager = null, EventDispatcherInterface $eventDispatcher = null) - { - $this->resourceManager = $resourceManager ?: new ResourceManager(); - $this->storageManager = $storageManager ?: new StorageManager(); - $this->eventDispatcher = $eventDispatcher ?: new EventDispatcher(); - - $this->addPresenter('html', new HtmlPresenter()); - $this->addPresenter('json', new ArrayPresenter()); - $this->addPresenter('array', new ArrayPresenter()); + public function __construct( + private readonly ResourceManagerInterface $resourceManager, + private readonly StorageManagerInterface $storageManager, + private readonly EventDispatcherInterface $eventDispatcher, + ) { + $this->addPresenter('html', fn () => new HtmlPresenter()); + $this->addPresenter('json', fn () => new ArrayPresenter()); + $this->addPresenter('array', fn () => new ArrayPresenter()); } - /** - * {@inheritdoc} - */ - public function render(array $criteria = array(), $presenter = 'html', array $context = array()) + public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed { $envelopes = $this->storageManager->filter($criteria); - - $this->storageManager->remove($envelopes); + $this->storageManager->remove(...$envelopes); $event = new PresentationEvent($envelopes, $context); $this->eventDispatcher->dispatch($event); $response = $this->createResponse($event->getEnvelopes(), $context); - $response = $this->createPresenter($presenter)->render($response); + $response = $this->presentResponse($response, $presenter); $event = new ResponseEvent($response, $presenter); $this->eventDispatcher->dispatch($event); @@ -74,23 +49,15 @@ final class ResponseManager implements ResponseManagerInterface return $event->getResponse(); } - /** - * {@inheritdoc} - */ - public function addPresenter($alias, $presenter) + public function addPresenter(string $alias, callable|PresenterInterface $presenter): void { $this->presenters[$alias] = $presenter; } - /** - * @param string $alias - * - * @return PresenterInterface - */ - private function createPresenter($alias) + private function createPresenter(string $alias): PresenterInterface { if (!isset($this->presenters[$alias])) { - throw new \InvalidArgumentException(sprintf('Presenter [%s] not supported.', $alias)); + throw PresenterNotFoundException::create($alias, array_keys($this->presenters)); } $presenter = $this->presenters[$alias]; @@ -99,15 +66,20 @@ final class ResponseManager implements ResponseManagerInterface } /** - * @param Envelope[] $envelopes - * @param mixed[] $context - * - * @return Response + * @param Envelope[] $envelopes + * @param array $context */ - private function createResponse($envelopes, $context) + private function createResponse(array $envelopes, array $context): Response { $response = new Response($envelopes, $context); - return $this->resourceManager->buildResponse($response); + return $this->resourceManager->populateResponse($response); + } + + private function presentResponse(Response $response, string $presenter): mixed + { + $presenter = $this->createPresenter($presenter); + + return $presenter->render($response); } } diff --git a/src/Prime/Response/ResponseManagerInterface.php b/src/Prime/Response/ResponseManagerInterface.php index 1088ef0f..963e87a6 100644 --- a/src/Prime/Response/ResponseManagerInterface.php +++ b/src/Prime/Response/ResponseManagerInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Response; @@ -12,19 +9,10 @@ use Flasher\Prime\Response\Presenter\PresenterInterface; interface ResponseManagerInterface { /** - * @param mixed[] $criteria - * @param string $presenter - * @param mixed[] $context - * - * @return mixed + * @param array $criteria + * @param array $context */ - public function render(array $criteria = array(), $presenter = 'html', array $context = array()); + public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed; - /** - * @param string $alias - * @param callable|PresenterInterface $presenter - * - * @return void - */ - public function addPresenter($alias, $presenter); + public function addPresenter(string $alias, callable|PresenterInterface $presenter): void; } diff --git a/src/Prime/Stamp/ContextStamp.php b/src/Prime/Stamp/ContextStamp.php index 758d8db5..d06a5c4d 100644 --- a/src/Prime/Stamp/ContextStamp.php +++ b/src/Prime/Stamp/ContextStamp.php @@ -1,40 +1,31 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class ContextStamp implements StampInterface, PresentableStampInterface +final readonly class ContextStamp implements PresentableStampInterface, StampInterface { /** - * @var mixed[] + * @param array $context */ - private $context; - - /** - * @param mixed[] $context - */ - public function __construct(array $context) + public function __construct(private array $context) { - $this->context = $context; } /** - * @return mixed[] + * @return array */ - public function getContext() + public function getContext(): array { return $this->context; } /** - * {@inheritdoc} + * @return array{context: array} */ - public function toArray() + public function toArray(): array { - return array('context' => $this->getContext()); + return ['context' => $this->context]; } } diff --git a/src/Prime/Stamp/CreatedAtStamp.php b/src/Prime/Stamp/CreatedAtStamp.php index 7af63bbc..b2e78549 100644 --- a/src/Prime/Stamp/CreatedAtStamp.php +++ b/src/Prime/Stamp/CreatedAtStamp.php @@ -1,47 +1,40 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class CreatedAtStamp implements StampInterface, OrderableStampInterface, PresentableStampInterface +final readonly class CreatedAtStamp implements OrderableStampInterface, PresentableStampInterface, StampInterface { - /** - * @var \DateTime - */ - private $createdAt; + private \DateTimeImmutable $createdAt; + + private string $format; /** - * @var string + * @param \DateTimeImmutable|null $createdAt the datetime object representing the creation time + * @param string|null $format the format in which the datetime should be presented */ - private $format; - - /** - * @param string|null $format - * - * @throws \Exception - */ - public function __construct(\DateTime $createdAt = null, $format = null) + public function __construct(?\DateTimeImmutable $createdAt = null, ?string $format = null) { - $this->createdAt = $createdAt ?: new \DateTime('now', new \DateTimeZone('Africa/Casablanca')); + $this->createdAt = $createdAt ?: new \DateTimeImmutable(); $this->format = $format ?: 'Y-m-d H:i:s'; } - /** - * @return \DateTime - */ - public function getCreatedAt() + public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } /** - * {@inheritdoc} + * Compares the current stamp with another orderable stamp. + * + * @param StampInterface $orderable the stamp to compare with + * + * @return int returns less than 0 if current is less than the given stamp, + * greater than 0 if current is greater + * and 0 if they are equal */ - public function compare($orderable) + public function compare(StampInterface $orderable): int { if (!$orderable instanceof self) { return 1; @@ -51,12 +44,10 @@ final class CreatedAtStamp implements StampInterface, OrderableStampInterface, P } /** - * {@inheritdoc} + * @return array{created_at: string} returns an associative array representation of the stamp */ - public function toArray() + public function toArray(): array { - $createdAt = $this->getCreatedAt(); - - return array('created_at' => $createdAt->format($this->format)); + return ['created_at' => $this->createdAt->format($this->format)]; } } diff --git a/src/Prime/Stamp/DelayStamp.php b/src/Prime/Stamp/DelayStamp.php index 11c6724b..2976f609 100644 --- a/src/Prime/Stamp/DelayStamp.php +++ b/src/Prime/Stamp/DelayStamp.php @@ -1,31 +1,16 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class DelayStamp implements StampInterface +final readonly class DelayStamp implements StampInterface { - /** - * @var int - */ - private $delay; - - /** - * @param int $delay - */ - public function __construct($delay) + public function __construct(private int $delay) { - $this->delay = $delay; } - /** - * @return int - */ - public function getDelay() + public function getDelay(): int { return $this->delay; } diff --git a/src/Prime/Stamp/HandlerStamp.php b/src/Prime/Stamp/HandlerStamp.php deleted file mode 100644 index 3b4d9960..00000000 --- a/src/Prime/Stamp/HandlerStamp.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace Flasher\Prime\Stamp; - -final class HandlerStamp implements StampInterface, PresentableStampInterface -{ - /** - * @var string - */ - private $handler; - - /** - * @param string $handler - */ - public function __construct($handler) - { - $this->handler = $handler; - } - - /** - * @return string - */ - public function getHandler() - { - return $this->handler; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - return array('handler' => $this->getHandler()); - } -} diff --git a/src/Prime/Stamp/HopsStamp.php b/src/Prime/Stamp/HopsStamp.php index 0627a1d8..2d653330 100644 --- a/src/Prime/Stamp/HopsStamp.php +++ b/src/Prime/Stamp/HopsStamp.php @@ -1,31 +1,16 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class HopsStamp implements StampInterface +final readonly class HopsStamp implements StampInterface { - /** - * @var int - */ - private $amount; - - /** - * @param int $amount - */ - public function __construct($amount) + public function __construct(private int $amount) { - $this->amount = $amount; } - /** - * @return int - */ - public function getAmount() + public function getAmount(): int { return $this->amount; } diff --git a/src/Prime/Stamp/HtmlStamp.php b/src/Prime/Stamp/HtmlStamp.php new file mode 100644 index 00000000..43c10fc8 --- /dev/null +++ b/src/Prime/Stamp/HtmlStamp.php @@ -0,0 +1,22 @@ +html; + } + + public function toArray(): array + { + return ['html' => $this->html]; + } +} diff --git a/src/Prime/Stamp/IdStamp.php b/src/Prime/Stamp/IdStamp.php new file mode 100644 index 00000000..9eb91188 --- /dev/null +++ b/src/Prime/Stamp/IdStamp.php @@ -0,0 +1,84 @@ +id = $id ?? $this->generateUniqueId(); + } + + /** + * Generates a unique identifier. + * + * @return string the generated unique identifier + */ + private function generateUniqueId(): string + { + try { + return bin2hex(random_bytes(16)); + } catch (\Exception) { + // Handle the exception or fallback to another method of ID generation + // For example, using uniqid() as a fallback + return uniqid('', true); + } + } + + /** + * Indexes an array of envelopes by their ID. + * + * @param Envelope[] $envelopes an array of envelopes to index + * + * @return array an associative array of envelopes indexed by their ID + */ + public static function indexById(array $envelopes): array + { + $map = []; + + foreach ($envelopes as $envelope) { + $stamp = $envelope->get(self::class); + if ($stamp instanceof self) { + $map[$stamp->getId()] = $envelope; + continue; + } + + $newStamp = new self(); + $envelope->withStamp($newStamp); + $map[$newStamp->getId()] = $envelope; + } + + return $map; + } + + /** + * Gets the identifier. + * + * @return string the identifier + */ + public function getId(): string + { + return $this->id; + } + + /** + * Converts the stamp to an array. + * + * @return array{id: string} an associative array with the identifier + */ + public function toArray(): array + { + return ['id' => $this->id]; + } +} diff --git a/src/Prime/Stamp/OrderableStampInterface.php b/src/Prime/Stamp/OrderableStampInterface.php index 4a707a56..e0def512 100644 --- a/src/Prime/Stamp/OrderableStampInterface.php +++ b/src/Prime/Stamp/OrderableStampInterface.php @@ -1,18 +1,10 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; interface OrderableStampInterface { - /** - * @param mixed $orderable - * - * @return int - */ - public function compare($orderable); + public function compare(StampInterface $orderable): int; } diff --git a/src/Prime/Stamp/PluginStamp.php b/src/Prime/Stamp/PluginStamp.php new file mode 100644 index 00000000..f5262cdd --- /dev/null +++ b/src/Prime/Stamp/PluginStamp.php @@ -0,0 +1,25 @@ +plugin; + } + + /** + * @return array{plugin: string} + */ + public function toArray(): array + { + return ['plugin' => $this->plugin]; + } +} diff --git a/src/Prime/Stamp/PresentableStampInterface.php b/src/Prime/Stamp/PresentableStampInterface.php index 515f3186..50628085 100644 --- a/src/Prime/Stamp/PresentableStampInterface.php +++ b/src/Prime/Stamp/PresentableStampInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; @@ -12,5 +9,5 @@ interface PresentableStampInterface /** * @return array */ - public function toArray(); + public function toArray(): array; } diff --git a/src/Prime/Stamp/PresenterStamp.php b/src/Prime/Stamp/PresenterStamp.php new file mode 100644 index 00000000..2a4dd2a1 --- /dev/null +++ b/src/Prime/Stamp/PresenterStamp.php @@ -0,0 +1,20 @@ +pattern; + } +} diff --git a/src/Prime/Stamp/PresetStamp.php b/src/Prime/Stamp/PresetStamp.php index 69c86b71..e3379b27 100644 --- a/src/Prime/Stamp/PresetStamp.php +++ b/src/Prime/Stamp/PresetStamp.php @@ -1,38 +1,19 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class PresetStamp implements StampInterface +final readonly class PresetStamp implements StampInterface { /** - * @var string - */ - private $preset; - - /** - * @var array - */ - private $parameters; - - /** - * @param string $preset * @param array $parameters */ - public function __construct($preset, array $parameters = array()) + public function __construct(private string $preset, private array $parameters = []) { - $this->preset = $preset; - $this->parameters = $parameters; } - /** - * @return string - */ - public function getPreset() + public function getPreset(): string { return $this->preset; } @@ -40,7 +21,7 @@ final class PresetStamp implements StampInterface /** * @return array */ - public function getParameters() + public function getParameters(): array { return $this->parameters; } diff --git a/src/Prime/Stamp/PriorityStamp.php b/src/Prime/Stamp/PriorityStamp.php index ad73670d..4cb6fe6d 100644 --- a/src/Prime/Stamp/PriorityStamp.php +++ b/src/Prime/Stamp/PriorityStamp.php @@ -1,39 +1,21 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class PriorityStamp implements StampInterface, OrderableStampInterface, PresentableStampInterface +final readonly class PriorityStamp implements OrderableStampInterface, PresentableStampInterface, StampInterface { - /** - * @var int - */ - private $priority; - - /** - * @param int $priority - */ - public function __construct($priority) + public function __construct(private int $priority) { - $this->priority = $priority; } - /** - * @return int - */ - public function getPriority() + public function getPriority(): int { return $this->priority; } - /** - * {@inheritdoc} - */ - public function compare($orderable) + public function compare(StampInterface $orderable): int { if (!$orderable instanceof self) { return 1; @@ -43,10 +25,10 @@ final class PriorityStamp implements StampInterface, OrderableStampInterface, Pr } /** - * {@inheritdoc} + * @return array{priority: int} */ - public function toArray() + public function toArray(): array { - return array('priority' => $this->getPriority()); + return ['priority' => $this->priority]; } } diff --git a/src/Prime/Stamp/StampInterface.php b/src/Prime/Stamp/StampInterface.php index 1076caf3..883b413e 100644 --- a/src/Prime/Stamp/StampInterface.php +++ b/src/Prime/Stamp/StampInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; diff --git a/src/Prime/Stamp/TranslationStamp.php b/src/Prime/Stamp/TranslationStamp.php index bebca677..03dadeb1 100644 --- a/src/Prime/Stamp/TranslationStamp.php +++ b/src/Prime/Stamp/TranslationStamp.php @@ -1,69 +1,28 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class TranslationStamp implements StampInterface +final readonly class TranslationStamp implements StampInterface { - /** - * @var array - */ - private $parameters; - - /** - * @var string|null - */ - private $locale; - /** * @param array $parameters - * @param string|null $locale */ - public function __construct($parameters = array(), $locale = null) + public function __construct(private array $parameters = [], private ?string $locale = null) { - $order = self::parametersOrder($parameters, $locale); - $parameters = $order['parameters']; - $locale = $order['locale']; - - $this->parameters = $parameters; - $this->locale = $locale; } /** * @return array */ - public function getParameters() + public function getParameters(): array { return $this->parameters; } - /** - * @return string|null - */ - public function getLocale() + public function getLocale(): ?string { return $this->locale; } - - /** - * @param mixed $parameters - * @param mixed|null $locale - * - * @return array{parameters: array, locale: string|null} - */ - public static function parametersOrder($parameters = array(), $locale = null) - { - if (\is_string($parameters)) { - $locale = $parameters; - $parameters = array(); - - @trigger_error('Since php-flasher/flasher v1.4, passing the locale as first parameter is deprecated and will be removed in v2.0. Use the second parameter instead.', \E_USER_DEPRECATED); - } - - return array('parameters' => $parameters, 'locale' => $locale); // @phpstan-ignore-line - } } diff --git a/src/Prime/Stamp/UnlessStamp.php b/src/Prime/Stamp/UnlessStamp.php index 6307f6b4..f14aeefa 100644 --- a/src/Prime/Stamp/UnlessStamp.php +++ b/src/Prime/Stamp/UnlessStamp.php @@ -1,31 +1,16 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class UnlessStamp implements StampInterface +final readonly class UnlessStamp implements StampInterface { - /** - * @var bool - */ - private $condition; - - /** - * @param bool $condition - */ - public function __construct($condition) + public function __construct(private bool $condition) { - $this->condition = $condition; } - /** - * @return bool - */ - public function getCondition() + public function getCondition(): bool { return $this->condition; } diff --git a/src/Prime/Stamp/UuidStamp.php b/src/Prime/Stamp/UuidStamp.php deleted file mode 100644 index eb31ac07..00000000 --- a/src/Prime/Stamp/UuidStamp.php +++ /dev/null @@ -1,77 +0,0 @@ - - */ - -namespace Flasher\Prime\Stamp; - -use Flasher\Prime\Notification\Envelope; - -final class UuidStamp implements StampInterface, PresentableStampInterface -{ - /** - * @var string - */ - private $uuid; - - /** - * @param string|null $uuid - */ - public function __construct($uuid = null) - { - $this->uuid = $uuid ?: sprintf( - '%04X%04X-%04X-%04X-%04X-%04X%04X%04X', - mt_rand(0, 65535), - mt_rand(0, 65535), - mt_rand(0, 65535), - mt_rand(16384, 20479), - mt_rand(32768, 49151), - mt_rand(0, 65535), - mt_rand(0, 65535), - mt_rand(0, 65535) - ); - } - - /** - * @param Envelope[]|Envelope... $envelopes - * - * @return array - */ - public static function indexByUuid($envelopes) - { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - - $map = array(); - - foreach ($envelopes as $envelope) { - $uuidStamp = $envelope->get('Flasher\Prime\Stamp\UuidStamp'); - if (!$uuidStamp instanceof UuidStamp) { - $uuidStamp = new UuidStamp(spl_object_hash($envelope)); - $envelope->withStamp($uuidStamp); - } - - $uuid = $uuidStamp->getUuid(); - $map[$uuid] = $envelope; - } - - return $map; - } - - /** - * @return string - */ - public function getUuid() - { - return $this->uuid; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - return array('uuid' => $this->getUuid()); - } -} diff --git a/src/Prime/Stamp/ViewStamp.php b/src/Prime/Stamp/ViewStamp.php deleted file mode 100644 index d53323aa..00000000 --- a/src/Prime/Stamp/ViewStamp.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace Flasher\Prime\Stamp; - -final class ViewStamp implements StampInterface, PresentableStampInterface -{ - /** - * @var string - */ - private $view; - - /** - * @param string $template - */ - public function __construct($template) - { - $this->view = $template; - } - - /** - * @return string - */ - public function getView() - { - return $this->view; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - return array('view' => $this->getView()); - } -} diff --git a/src/Prime/Stamp/WhenStamp.php b/src/Prime/Stamp/WhenStamp.php index 1cbe04f0..a5c4716b 100644 --- a/src/Prime/Stamp/WhenStamp.php +++ b/src/Prime/Stamp/WhenStamp.php @@ -1,31 +1,16 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Stamp; -final class WhenStamp implements StampInterface +final readonly class WhenStamp implements StampInterface { - /** - * @var bool - */ - private $condition; - - /** - * @param bool $condition - */ - public function __construct($condition) + public function __construct(private bool $condition) { - $this->condition = $condition; } - /** - * @return bool - */ - public function getCondition() + public function getCondition(): bool { return $this->condition; } diff --git a/src/Prime/Storage/Bag/ArrayBag.php b/src/Prime/Storage/Bag/ArrayBag.php index 70e96608..cfe6e5fe 100644 --- a/src/Prime/Storage/Bag/ArrayBag.php +++ b/src/Prime/Storage/Bag/ArrayBag.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Storage\Bag; @@ -14,20 +11,14 @@ final class ArrayBag implements BagInterface /** * @var Envelope[] */ - private $envelopes = array(); + private array $envelopes = []; - /** - * {@inheritDoc} - */ - public function get() + public function get(): array { return $this->envelopes; } - /** - * {@inheritDoc} - */ - public function set(array $envelopes) + public function set(array $envelopes): void { $this->envelopes = $envelopes; } diff --git a/src/Prime/Storage/Bag/BagInterface.php b/src/Prime/Storage/Bag/BagInterface.php index 23bf4acd..ae946e5c 100644 --- a/src/Prime/Storage/Bag/BagInterface.php +++ b/src/Prime/Storage/Bag/BagInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Storage\Bag; @@ -14,12 +11,10 @@ interface BagInterface /** * @return Envelope[] */ - public function get(); + public function get(): array; /** * @param Envelope[] $envelopes - * - * @return void */ - public function set(array $envelopes); + public function set(array $envelopes): void; } diff --git a/src/Prime/Storage/Bag/StaticBag.php b/src/Prime/Storage/Bag/StaticBag.php index 14de24fb..5c3f9ee2 100644 --- a/src/Prime/Storage/Bag/StaticBag.php +++ b/src/Prime/Storage/Bag/StaticBag.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Storage\Bag; @@ -14,20 +11,14 @@ final class StaticBag implements BagInterface /** * @var Envelope[] */ - private static $envelopes = array(); + private static array $envelopes = []; - /** - * {@inheritDoc} - */ - public function get() + public function get(): array { return self::$envelopes; } - /** - * {@inheritDoc} - */ - public function set(array $envelopes) + public function set(array $envelopes): void { self::$envelopes = $envelopes; } diff --git a/src/Prime/Storage/Filter/Criteria/CriteriaInterface.php b/src/Prime/Storage/Filter/Criteria/CriteriaInterface.php new file mode 100644 index 00000000..cb9581e5 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/CriteriaInterface.php @@ -0,0 +1,17 @@ +extractRange('priority', $criteria); + + $this->minDelay = $criteria['min']; + $this->maxDelay = $criteria['max']; + } + + public function apply(array $envelopes): array + { + return array_filter($envelopes, fn (Envelope $envelope): bool => $this->match($envelope)); + } + + public function match(Envelope $envelope): bool + { + $stamp = $envelope->get(DelayStamp::class); + + if (!$stamp instanceof DelayStamp) { + return false; + } + + $delay = $stamp->getDelay(); + + if (null === $this->maxDelay) { + return $delay >= $this->minDelay; + } + + if ($delay <= $this->maxDelay) { + return $delay >= $this->minDelay; + } + + return false; + } +} diff --git a/src/Prime/Storage/Filter/Criteria/FilterCriteria.php b/src/Prime/Storage/Filter/Criteria/FilterCriteria.php new file mode 100644 index 00000000..9b1babb4 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/FilterCriteria.php @@ -0,0 +1,44 @@ +callbacks[] = $callback; + } + } + + /** + * Applies the filter callbacks to the envelopes. + */ + public function apply(array $envelopes): array + { + foreach ($this->callbacks as $callback) { + $envelopes = $callback($envelopes); + } + + return $envelopes; + } +} diff --git a/src/Prime/Storage/Filter/Criteria/HopsCriteria.php b/src/Prime/Storage/Filter/Criteria/HopsCriteria.php new file mode 100644 index 00000000..ffb865b2 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/HopsCriteria.php @@ -0,0 +1,49 @@ +extractRange('priority', $criteria); + + $this->minAmount = $criteria['min']; + $this->maxAmount = $criteria['max']; + } + + public function apply(array $envelopes): array + { + return array_filter($envelopes, fn (Envelope $e): bool => $this->match($e)); + } + + public function match(Envelope $envelope): bool + { + $stamp = $envelope->get(HopsStamp::class); + + if (!$stamp instanceof HopsStamp) { + return false; + } + + if (null === $this->maxAmount) { + return $stamp->getAmount() >= $this->minAmount; + } + + if ($stamp->getAmount() <= $this->maxAmount) { + return $stamp->getAmount() >= $this->minAmount; + } + + return false; + } +} diff --git a/src/Prime/Storage/Filter/Criteria/LimitCriteria.php b/src/Prime/Storage/Filter/Criteria/LimitCriteria.php new file mode 100644 index 00000000..d20e3595 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/LimitCriteria.php @@ -0,0 +1,24 @@ +limit = $criteria; + } + + public function apply(array $envelopes): array + { + return \array_slice($envelopes, 0, $this->limit, true); + } +} diff --git a/src/Prime/Storage/Filter/Criteria/OrderByCriteria.php b/src/Prime/Storage/Filter/Criteria/OrderByCriteria.php new file mode 100644 index 00000000..3f44a854 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/OrderByCriteria.php @@ -0,0 +1,101 @@ +> + */ + private array $aliases = [ + 'context' => ContextStamp::class, + 'created_at' => CreatedAtStamp::class, + 'delay' => DelayStamp::class, + 'handler' => PluginStamp::class, + 'hops' => HopsStamp::class, + 'preset' => PresetStamp::class, + 'priority' => PriorityStamp::class, + 'translation' => TranslationStamp::class, + 'unless' => UnlessStamp::class, + 'uuid' => IdStamp::class, + 'when' => WhenStamp::class, + ]; + + /** + * @var array, "ASC"|"DESC"> + */ + private array $orderings = []; + + public function __construct(mixed $criteria) + { + if (!\is_string($criteria) && !\is_array($criteria)) { + throw new \InvalidArgumentException(sprintf('Invalid type for criteria "order_by". Expect a "string" or an "array", got "%s".', get_debug_type($criteria))); + } + + foreach ((array) $criteria as $field => $direction) { + if (\is_int($field)) { + $field = $direction; + $direction = self::ASC; + } + + if (!\is_string($field)) { + throw new \InvalidArgumentException(sprintf('Invalid Field value, must be "string", got "%s".', get_debug_type($field))); + } + + $direction = strtoupper((string) $direction); + + if (!\in_array($direction, [self::ASC, self::DESC], true)) { + throw new \InvalidArgumentException(sprintf('Invalid ordering direction: must be "ASC" or "DESC", got "%s".', $direction)); + } + + $field = $this->aliases[$field] ?? $field; + if (!is_a($field, StampInterface::class, true)) { + throw new \InvalidArgumentException(sprintf('Field "%s" is not a valid class-string of "%s".', $field, StampInterface::class)); + } + + $this->orderings[$field] = $direction; + } + } + + public function apply(array $envelopes): array + { + usort($envelopes, function (Envelope $first, Envelope $second): int { + foreach ($this->orderings as $field => $ordering) { + $stampA = $first->get($field); + $stampB = $second->get($field); + + if (!$stampA instanceof OrderableStampInterface || !$stampB instanceof OrderableStampInterface) { + return 0; + } + + return self::ASC === $ordering + ? $stampA->compare($stampB) + : $stampB->compare($stampA); + } + + return 0; + }); + + return $envelopes; + } +} diff --git a/src/Prime/Storage/Filter/Criteria/PresenterCriteria.php b/src/Prime/Storage/Filter/Criteria/PresenterCriteria.php new file mode 100644 index 00000000..ae2fbd31 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/PresenterCriteria.php @@ -0,0 +1,31 @@ +presenter = $criteria; + } + + public function apply(array $envelopes): array + { + return array_filter($envelopes, function (Envelope $envelope) { + $pattern = $envelope->get(PresenterStamp::class)?->getPattern() ?: '/.*/'; + + return 1 === preg_match($pattern, $this->presenter); + }); + } +} diff --git a/src/Prime/Storage/Filter/Criteria/PriorityCriteria.php b/src/Prime/Storage/Filter/Criteria/PriorityCriteria.php new file mode 100644 index 00000000..3a3b08c6 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/PriorityCriteria.php @@ -0,0 +1,51 @@ +extractRange('priority', $criteria); + + $this->minPriority = $criteria['min']; + $this->maxPriority = $criteria['max']; + } + + public function apply(array $envelopes): array + { + return array_filter($envelopes, fn (Envelope $envelope): bool => $this->match($envelope)); + } + + public function match(Envelope $envelope): bool + { + $stamp = $envelope->get(PriorityStamp::class); + + if (!$stamp instanceof PriorityStamp) { + return false; + } + + $priority = $stamp->getPriority(); + + if (null === $this->maxPriority) { + return $priority >= $this->minPriority; + } + + if ($priority <= $this->maxPriority) { + return $priority >= $this->minPriority; + } + + return false; + } +} diff --git a/src/Prime/Storage/Filter/Criteria/RangeExtractor.php b/src/Prime/Storage/Filter/Criteria/RangeExtractor.php new file mode 100644 index 00000000..7c1ed9f4 --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/RangeExtractor.php @@ -0,0 +1,42 @@ + $criteria, 'max' => null]; + } + + $min = $criteria['min'] ?? null; + $max = $criteria['max'] ?? null; + + if (null !== $min && !\is_int($min)) { + throw new \InvalidArgumentException(sprintf('Invalid type for "min" in criteria "%s". Expected int, got "%s".', $name, get_debug_type($min))); + } + + if (null !== $max && !\is_int($max)) { + throw new \InvalidArgumentException(sprintf('Invalid type for "max" in criteria "%s". Expected int, got "%s".', $name, get_debug_type($max))); + } + + return ['min' => $min, 'max' => $max]; + } +} diff --git a/src/Prime/Storage/Filter/Criteria/StampsCriteria.php b/src/Prime/Storage/Filter/Criteria/StampsCriteria.php new file mode 100644 index 00000000..55a01f4a --- /dev/null +++ b/src/Prime/Storage/Filter/Criteria/StampsCriteria.php @@ -0,0 +1,45 @@ + + */ + private array $stamps = []; + + public function __construct(mixed $criteria, private readonly string $strategy = self::STRATEGY_AND) + { + if (!\is_array($criteria)) { + throw new \InvalidArgumentException("Invalid type for criteria 'stamps'."); + } + + foreach ($criteria as $key => $value) { + $this->stamps[$key] = $value; + } + } + + public function apply(array $envelopes): array + { + return array_filter($envelopes, fn (Envelope $e): bool => $this->match($e)); + } + + public function match(Envelope $envelope): bool + { + $diff = array_diff($this->stamps, array_keys($envelope->all())); + + if (self::STRATEGY_AND === $this->strategy) { + return [] === $diff; + } + + return \count($diff) < \count($this->stamps); + } +} diff --git a/src/Prime/Storage/Filter/Filter.php b/src/Prime/Storage/Filter/Filter.php new file mode 100644 index 00000000..8b491154 --- /dev/null +++ b/src/Prime/Storage/Filter/Filter.php @@ -0,0 +1,29 @@ +criteriaChain as $criteria) { + $envelopes = $criteria->apply($envelopes); + } + + return $envelopes; + } + + public function addCriteria(CriteriaInterface $criteria): void + { + $this->criteriaChain[] = $criteria; + } +} diff --git a/src/Prime/Storage/Filter/FilterFactory.php b/src/Prime/Storage/Filter/FilterFactory.php new file mode 100644 index 00000000..b64e2ae8 --- /dev/null +++ b/src/Prime/Storage/Filter/FilterFactory.php @@ -0,0 +1,79 @@ + + */ + private array $criteria = []; + + public function __construct() + { + $criteriaClasses = [ + 'priority' => PriorityCriteria::class, + 'hops' => HopsCriteria::class, + 'delay' => DelayCriteria::class, + 'order_by' => OrderByCriteria::class, + 'limit' => LimitCriteria::class, + 'stamps' => StampsCriteria::class, + 'filter' => FilterCriteria::class, + 'presenter' => PresenterCriteria::class, + ]; + + foreach ($criteriaClasses as $name => $criteriaClass) { + $this->addCriteria($name, fn (mixed $criteria) => new $criteriaClass($criteria)); + } + } + + public function createFilter(array $config): Filter + { + $filter = new Filter(); + + foreach ($config as $name => $value) { + $criteria = $this->createCriteria($name, $value); + + $filter->addCriteria($criteria); + } + + return $filter; + } + + public function addCriteria(string $name, callable|CriteriaInterface $criteria): void + { + $this->criteria[$name] = $criteria; + } + + /** + * @throws CriteriaNotRegisteredException + */ + private function createCriteria(string $name, mixed $value): CriteriaInterface + { + if (!isset($this->criteria[$name])) { + throw CriteriaNotRegisteredException::create($name, array_keys($this->criteria)); + } + + $criteria = $this->criteria[$name]; + $criteria = \is_callable($criteria) ? $criteria($value) : $criteria; + + if (!$criteria instanceof CriteriaInterface) { + throw new \UnexpectedValueException(sprintf('Expected an instance of "%s", got "%s" instead.', CriteriaInterface::class, get_debug_type($criteria))); + } + + return $criteria; + } +} diff --git a/src/Prime/Storage/Filter/FilterFactoryInterface.php b/src/Prime/Storage/Filter/FilterFactoryInterface.php new file mode 100644 index 00000000..cbc4aaea --- /dev/null +++ b/src/Prime/Storage/Filter/FilterFactoryInterface.php @@ -0,0 +1,20 @@ + $config + * + * @throws CriteriaNotRegisteredException + */ + public function createFilter(array $config): Filter; + + public function addCriteria(string $name, callable|CriteriaInterface $criteria): void; +} diff --git a/src/Prime/Storage/Filter/FilterInterface.php b/src/Prime/Storage/Filter/FilterInterface.php new file mode 100644 index 00000000..baea67ea --- /dev/null +++ b/src/Prime/Storage/Filter/FilterInterface.php @@ -0,0 +1,20 @@ +bag->get()); + } + + public function add(Envelope ...$envelopes): void + { + $this->save(...$envelopes); + } + + public function update(Envelope ...$envelopes): void + { + $this->save(...$envelopes); + } + + public function remove(Envelope ...$envelopes): void + { + $envelopes = IdStamp::indexById($envelopes); + $stored = IdStamp::indexById($this->all()); + $envelopes = array_diff_key($stored, $envelopes); + + $this->bag->set(array_values($envelopes)); + } + + public function clear(): void + { + $this->bag->set([]); + } + + private function save(Envelope ...$envelopes): void + { + $envelopes = IdStamp::indexById($envelopes); + $stored = IdStamp::indexById($this->all()); + $envelopes = [...$stored, ...$envelopes]; + + $this->bag->set(array_values($envelopes)); + } +} diff --git a/src/Prime/Storage/StorageBag.php b/src/Prime/Storage/StorageBag.php deleted file mode 100644 index c42da821..00000000 --- a/src/Prime/Storage/StorageBag.php +++ /dev/null @@ -1,83 +0,0 @@ - - */ - -namespace Flasher\Prime\Storage; - -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Prime\Storage\Bag\ArrayBag; -use Flasher\Prime\Storage\Bag\BagInterface; - -final class StorageBag implements StorageInterface -{ - /** - * @var BagInterface - */ - private $bag; - - public function __construct(BagInterface $bag = null) - { - $this->bag = null !== $bag && 'cli' !== \PHP_SAPI ? $bag : new ArrayBag(); - } - - /** - * {@inheritdoc} - */ - public function all() - { - return array_values($this->bag->get()); - } - - /** - * {@inheritdoc} - */ - public function add($envelopes) - { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - $envelopes = UuidStamp::indexByUuid($envelopes); - - $stored = UuidStamp::indexByUuid($this->all()); - $envelopes = array_merge($stored, $envelopes); - - $this->bag->set(array_values($envelopes)); - } - - /** - * {@inheritdoc} - */ - public function update($envelopes) - { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - $envelopes = UuidStamp::indexByUuid($envelopes); - - $stored = UuidStamp::indexByUuid($this->all()); - $envelopes = array_merge($stored, $envelopes); - - $this->bag->set(array_values($envelopes)); - } - - /** - * {@inheritdoc} - */ - public function remove($envelopes) - { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - $envelopes = UuidStamp::indexByUuid($envelopes); - - $stored = UuidStamp::indexByUuid($this->all()); - $envelopes = array_diff_key($stored, $envelopes); - - $this->bag->set(array_values($envelopes)); - } - - /** - * {@inheritdoc} - */ - public function clear() - { - $this->bag->set(array()); - } -} diff --git a/src/Prime/Storage/StorageInterface.php b/src/Prime/Storage/StorageInterface.php index 12d92c1c..77f26a39 100644 --- a/src/Prime/Storage/StorageInterface.php +++ b/src/Prime/Storage/StorageInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Storage; @@ -14,33 +11,13 @@ interface StorageInterface /** * @return Envelope[] */ - public function all(); + public function all(): array; - /** - * @param Envelope|Envelope[] $envelopes - * - * @return void - */ - public function add($envelopes); + public function add(Envelope ...$envelopes): void; - /** - * @param Envelope|Envelope[] $envelopes - * - * @return void - */ - public function update($envelopes); + public function update(Envelope ...$envelopes): void; - /** - * @param Envelope|Envelope[] $envelopes - * - * @return void - */ - public function remove($envelopes); + public function remove(Envelope ...$envelopes): void; - /** - * Remove all notifications from the storage. - * - * @return void - */ - public function clear(); + public function clear(): void; } diff --git a/src/Prime/Storage/StorageManager.php b/src/Prime/Storage/StorageManager.php index e770042e..f69a59ce 100644 --- a/src/Prime/Storage/StorageManager.php +++ b/src/Prime/Storage/StorageManager.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Storage; @@ -14,114 +11,78 @@ use Flasher\Prime\EventDispatcher\Event\PostRemoveEvent; use Flasher\Prime\EventDispatcher\Event\PostUpdateEvent; use Flasher\Prime\EventDispatcher\Event\RemoveEvent; use Flasher\Prime\EventDispatcher\Event\UpdateEvent; -use Flasher\Prime\EventDispatcher\EventDispatcher; use Flasher\Prime\EventDispatcher\EventDispatcherInterface; +use Flasher\Prime\Exception\CriteriaNotRegisteredException; +use Flasher\Prime\Notification\Envelope; +use Flasher\Prime\Storage\Filter\FilterFactoryInterface; -final class StorageManager implements StorageManagerInterface +final readonly class StorageManager implements StorageManagerInterface { /** - * @var StorageInterface + * @param array $criteria */ - private $storage; - - /** - * @var EventDispatcherInterface - */ - private $eventDispatcher; - - /** - * @var mixed[] - */ - private $criteria = array(); - - /** - * @param mixed[] $criteria - */ - public function __construct(StorageInterface $storage = null, EventDispatcherInterface $eventDispatcher = null, array $criteria = array()) - { - $this->storage = $storage ?: new StorageBag(); - $this->eventDispatcher = $eventDispatcher ?: new EventDispatcher(); - $this->criteria = $criteria; + public function __construct( + private StorageInterface $storage, + private EventDispatcherInterface $eventDispatcher, + private FilterFactoryInterface $filterFactory, + private array $criteria = [], + ) { } - /** - * {@inheritdoc} - */ - public function all() + public function all(): array { return $this->storage->all(); } /** - * {@inheritdoc} + * @throws CriteriaNotRegisteredException */ - public function filter(array $criteria = array()) + public function filter(array $criteria = []): array { - $criteria = array_merge($this->criteria, $criteria); + $criteria = [...$this->criteria, ...$criteria]; + $filter = $this->filterFactory->createFilter($criteria); - $criteria['delay'] = 0; - // @phpstan-ignore-next-line - $criteria['hops']['min'] = 1; - - $event = new FilterEvent($this->all(), $criteria); + $event = new FilterEvent($filter, $this->all(), $criteria); $this->eventDispatcher->dispatch($event); - return $event->getEnvelopes(); + return $event->getFilter()->apply($event->getEnvelopes()); } - /** - * {@inheritdoc} - */ - public function add($envelopes) + public function add(Envelope ...$envelopes): void { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - $event = new PersistEvent($envelopes); $this->eventDispatcher->dispatch($event); - $this->storage->add($event->getEnvelopes()); + $this->storage->add(...$event->getEnvelopes()); $event = new PostPersistEvent($event->getEnvelopes()); $this->eventDispatcher->dispatch($event); } - /** - * {@inheritdoc} - */ - public function update($envelopes) + public function update(Envelope ...$envelopes): void { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - $event = new UpdateEvent($envelopes); $this->eventDispatcher->dispatch($event); - $this->storage->update($event->getEnvelopes()); + $this->storage->update(...$event->getEnvelopes()); $event = new PostUpdateEvent($event->getEnvelopes()); $this->eventDispatcher->dispatch($event); } - /** - * {@inheritdoc} - */ - public function remove($envelopes) + public function remove(Envelope ...$envelopes): void { - $envelopes = \is_array($envelopes) ? $envelopes : \func_get_args(); - $event = new RemoveEvent($envelopes); $this->eventDispatcher->dispatch($event); - $this->storage->update($event->getEnvelopesToKeep()); - $this->storage->remove($event->getEnvelopesToRemove()); + $this->storage->update(...$event->getEnvelopesToKeep()); + $this->storage->remove(...$event->getEnvelopesToRemove()); $event = new PostRemoveEvent($event->getEnvelopesToRemove(), $event->getEnvelopesToKeep()); $this->eventDispatcher->dispatch($event); } - /** - * {@inheritdoc} - */ - public function clear() + public function clear(): void { $this->storage->clear(); } diff --git a/src/Prime/Storage/StorageManagerInterface.php b/src/Prime/Storage/StorageManagerInterface.php index 86c678a4..263e6c53 100644 --- a/src/Prime/Storage/StorageManagerInterface.php +++ b/src/Prime/Storage/StorageManagerInterface.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Storage; @@ -14,40 +11,20 @@ interface StorageManagerInterface /** * @return Envelope[] */ - public function all(); + public function all(): array; /** - * @param mixed[] $criteria + * @param array $criteria * * @return Envelope[] */ - public function filter(array $criteria = array()); + public function filter(array $criteria = []): array; - /** - * @param Envelope|Envelope[] $envelopes - * - * @return void - */ - public function add($envelopes); + public function add(Envelope ...$envelopes): void; - /** - * @param Envelope|Envelope[] $envelopes - * - * @return void - */ - public function update($envelopes); + public function update(Envelope ...$envelopes): void; - /** - * @param Envelope|Envelope[] $envelopes - * - * @return void - */ - public function remove($envelopes); + public function remove(Envelope ...$envelopes): void; - /** - * remove All notifications from storage. - * - * @return void - */ - public function clear(); + public function clear(): void; } diff --git a/src/Prime/Support/Traits/ForwardsCalls.php b/src/Prime/Support/Traits/ForwardsCalls.php new file mode 100644 index 00000000..cba5d435 --- /dev/null +++ b/src/Prime/Support/Traits/ForwardsCalls.php @@ -0,0 +1,75 @@ +{$method}(...$parameters); + } catch (\Error|\BadMethodCallException $e) { + $pattern = '~^Call to undefined method (?P[^:]+)::(?P[^\(]+)\(\)$~'; + + if (!preg_match($pattern, $e->getMessage(), $matches)) { + throw $e; + } + + if ($matches['class'] !== $object::class || $matches['method'] !== $method) { + throw $e; + } + + static::throwBadMethodCallException($method); + } + } + + /** + * Forward a method call to the given object, returning $this if the forwarded call returned itself. + * + * @param mixed[] $parameters + * + * @throws \BadMethodCallException + */ + protected function forwardDecoratedCallTo(object $object, string $method, array $parameters): mixed + { + $result = $this->forwardCallTo($object, $method, $parameters); + + return $result === $object ? $this : $result; + } + + /** + * Throw a bad method call exception for the given method. + * + * @throws \BadMethodCallException + */ + protected static function throwBadMethodCallException(string $method): never + { + throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', static::class, $method)); + } +} diff --git a/src/Prime/Support/Traits/Macroable.php b/src/Prime/Support/Traits/Macroable.php new file mode 100644 index 00000000..5c7ce868 --- /dev/null +++ b/src/Prime/Support/Traits/Macroable.php @@ -0,0 +1,127 @@ + + */ + protected static array $macros = []; + + /** + * Register a custom macro. + */ + public static function macro(string $name, object|callable $macro): void + { + static::$macros[$name] = $macro; + } + + /** + * Mix another object into the class. + * + * @throws \ReflectionException + * @throws \InvalidArgumentException + */ + public static function mixin(object $mixin, bool $replace = true): void + { + $methods = (new \ReflectionClass($mixin))->getMethods( + \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED + ); + + foreach ($methods as $method) { + $macro = $method->invoke($mixin); + + if (!\is_callable($macro) && !\is_object($macro)) { + throw new \InvalidArgumentException(sprintf('Expect the result of method %s::%s from the mixin object to be be a callable or an object, got "%s".', $mixin::class, $method->name, get_debug_type($macro))); + } + + if ($replace || !static::hasMacro($method->name)) { + static::macro($method->name, $macro); + } + } + } + + /** + * Checks if macro is registered. + */ + public static function hasMacro(string $name): bool + { + return isset(static::$macros[$name]); + } + + /** + * Dynamically handle calls to the class. + * + * @param mixed[] $parameters + * + * @throws \BadMethodCallException + */ + public static function __callStatic(string $method, array $parameters): mixed + { + if (!static::hasMacro($method)) { + throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method)); + } + + $macro = static::$macros[$method]; + + if ($macro instanceof \Closure) { + $macro = $macro->bindTo(null, static::class); + } + + if (!\is_callable($macro)) { + throw new \BadMethodCallException(sprintf('Macro %s is not callable.', $method)); + } + + return $macro(...$parameters); + } + + /** + * Dynamically handle calls to the class. + * + * @param mixed[] $parameters + * + * @throws \BadMethodCallException + */ + public function __call(string $method, array $parameters): mixed + { + if (!static::hasMacro($method)) { + throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method)); + } + + $macro = static::$macros[$method]; + + if ($macro instanceof \Closure) { + $macro = $macro->bindTo($this, static::class); + } + + if (!\is_callable($macro)) { + throw new \BadMethodCallException(sprintf('Macro %s is not callable.', $method)); + } + + return $macro(...$parameters); + } +} diff --git a/src/Prime/Support/Traits/MethodAliasResolver.php b/src/Prime/Support/Traits/MethodAliasResolver.php new file mode 100644 index 00000000..1a4a832c --- /dev/null +++ b/src/Prime/Support/Traits/MethodAliasResolver.php @@ -0,0 +1,68 @@ + + */ + protected array $methodAliases = []; + + /** + * Retrieves all method aliases. + * + * @return array + */ + protected function getMethodAliases(): array + { + return $this->methodAliases; + } + + /** + * Retrieves the real method name for a given alias. + */ + protected function resolveMethodAlias(string $method): string + { + if (!$this->hasMethodAlias($method)) { + throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method)); + } + + return $this->methodAliases[$method]; + } + + /** + * Checks if a method alias exists. + */ + protected function hasMethodAlias(string $method): bool + { + return \array_key_exists($method, $this->methodAliases); + } + + /** + * Calls the real method for a given alias with the provided parameters. + * + * @param array $parameters + */ + protected function callMethodAlias(string $method, array $parameters): mixed + { + $alias = $this->resolveMethodAlias($method); + + if (!method_exists($this, $alias)) { + throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $alias)); + } + + return $this->$alias(...$parameters); + } +} diff --git a/src/Prime/Template/Engine.php b/src/Prime/Template/Engine.php deleted file mode 100644 index 157d459a..00000000 --- a/src/Prime/Template/Engine.php +++ /dev/null @@ -1,35 +0,0 @@ - - */ - -namespace Flasher\Prime\Template; - -final class Engine implements EngineInterface -{ - public function render($name, array $context = array()) - { - ob_start(); - - extract($context, \EXTR_SKIP); - - if (!file_exists($name)) { - $name = __DIR__.'/views/'.$name; - - if (!file_exists($name)) { - throw new \Exception(sprintf('Cannot find template "%s"', $name)); - } - } - - include $name; - - $output = ob_get_clean(); - if (false === $output) { - return ''; - } - - return ltrim($output); - } -} diff --git a/src/Prime/Template/EngineInterface.php b/src/Prime/Template/EngineInterface.php deleted file mode 100644 index c8ae5640..00000000 --- a/src/Prime/Template/EngineInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ - -namespace Flasher\Prime\Template; - -interface EngineInterface -{ - /** - * @param string $name - * @param array $context - * - * @return string - */ - public function render($name, array $context = array()); -} diff --git a/src/Prime/Template/PHPTemplateEngine.php b/src/Prime/Template/PHPTemplateEngine.php index de8ace05..9a667608 100644 --- a/src/Prime/Template/PHPTemplateEngine.php +++ b/src/Prime/Template/PHPTemplateEngine.php @@ -1,19 +1,17 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Template; final class PHPTemplateEngine implements TemplateEngineInterface { - /** - * {@inheritdoc} - */ - public function render($name, array $context = array()) + public function render(string $name, array $context = []): string { + if (!file_exists($name) || !is_readable($name)) { + throw new \InvalidArgumentException(sprintf('Template file "%s" does not exist or is not readable.', $name)); + } + ob_start(); extract($context, \EXTR_SKIP); @@ -21,6 +19,7 @@ final class PHPTemplateEngine implements TemplateEngineInterface include $name; $output = ob_get_clean(); + if (false === $output) { return ''; } diff --git a/src/Prime/Template/TemplateEngineInterface.php b/src/Prime/Template/TemplateEngineInterface.php index f386f6b7..ed751766 100644 --- a/src/Prime/Template/TemplateEngineInterface.php +++ b/src/Prime/Template/TemplateEngineInterface.php @@ -1,19 +1,13 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Template; interface TemplateEngineInterface { /** - * @param string $name * @param array $context - * - * @return string */ - public function render($name, array $context = array()); + public function render(string $name, array $context = []): string; } diff --git a/src/Prime/Test/Constraint/Notification.php b/src/Prime/Test/Constraint/Notification.php new file mode 100644 index 00000000..5b53aa08 --- /dev/null +++ b/src/Prime/Test/Constraint/Notification.php @@ -0,0 +1,104 @@ + $expectedOptions expected options array + * @param string|null $expectedTitle expected title of the notification + */ + public function __construct( + private readonly string $expectedType, + private readonly ?string $expectedMessage = null, + private readonly array $expectedOptions = [], + private readonly ?string $expectedTitle = null, + ) { + } + + public function toString(): string + { + $details = [ + sprintf('type: "%s"', $this->expectedType), + ]; + + if (null !== $this->expectedMessage) { + $details[] = sprintf('message: "%s"', $this->expectedMessage); + } + + if (null !== $this->expectedTitle) { + $details[] = sprintf('title: "%s"', $this->expectedTitle); + } + + if (!empty($this->expectedOptions)) { + $details[] = 'options: ['.json_encode($this->expectedOptions).']'; + } + + return 'contains a notification with '.implode(', ', $details); + } + + /** + * @param NotificationEvents $other + */ + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + foreach ($other->getNotifications() as $notification) { + if ($this->isNotificationMatching($notification)) { + return true; + } + } + + return false; + } + + private function isNotificationMatching(NotificationInterface $notification): bool + { + return $notification->getType() === $this->expectedType + && (null === $this->expectedMessage || $notification->getMessage() === $this->expectedMessage) + && (null === $this->expectedTitle || $notification->getTitle() === $this->expectedTitle) + && (empty($this->expectedOptions) || array_intersect_assoc($this->expectedOptions, $notification->getOptions()) === $this->expectedOptions); + } + + /** + * @param NotificationEvents $other + */ + protected function failureDescription(mixed $other): string + { + $foundNotifications = array_map(function (NotificationInterface $notification) { + return sprintf( + 'type: "%s", title: "%s", message: "%s", options: [%s]', + $notification->getType(), + $notification->getTitle(), + $notification->getMessage(), + json_encode($notification->getOptions()), + ); + }, $other->getNotifications()); + + if (empty($foundNotifications)) { + $foundNotifications[] = 'No notifications found'; + } + + return sprintf( + 'Failed asserting that NotificationEvents %s. Found: [%s].', + $this->toString(), + implode('; ', $foundNotifications) + ); + } +} diff --git a/src/Prime/Test/Constraint/NotificationCount.php b/src/Prime/Test/Constraint/NotificationCount.php new file mode 100644 index 00000000..4709930a --- /dev/null +++ b/src/Prime/Test/Constraint/NotificationCount.php @@ -0,0 +1,62 @@ +expectedValue); + } + + /** + * Evaluates if the given NotificationEvents object matches the expected notification count. + * + * @param NotificationEvents $other an instance of NotificationEvents to evaluate + * + * @return bool returns true if the actual notification count matches the expected count + */ + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + return $this->expectedValue === $this->countNotifications($other); + } + + /** + * Provides a more detailed and understandable failure description. + * + * @param NotificationEvents $other the evaluated NotificationEvents instance + * + * @return string returns a detailed failure description + */ + protected function failureDescription(mixed $other): string + { + $actualCount = $this->countNotifications($other); + + return sprintf('Expected the notification count to be %d, but got %d instead.', $this->expectedValue, $actualCount); + } + + /** + * Counts the notifications in the given NotificationEvents object. + * + * @param NotificationEvents $events the NotificationEvents instance to count notifications from + * + * @return int returns the count of notifications + */ + private function countNotifications(NotificationEvents $events): int + { + return \count($events->getNotifications()); + } +} diff --git a/src/Prime/Test/Constraint/NotificationMessage.php b/src/Prime/Test/Constraint/NotificationMessage.php new file mode 100644 index 00000000..1b3e39b7 --- /dev/null +++ b/src/Prime/Test/Constraint/NotificationMessage.php @@ -0,0 +1,63 @@ +expectedMessage); + } + + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + foreach ($other->getNotifications() as $notification) { + if (str_contains($notification->getMessage(), $this->expectedMessage)) { + return true; + } + } + + return false; + } + + protected function failureDescription(mixed $other): string + { + if (!$other instanceof NotificationEvents) { + return 'Expected an instance of NotificationEvents but received a different type.'; + } + + $foundMessages = array_map(function (NotificationInterface $notification) { + return sprintf('"%s"', $notification->getMessage()); + }, $other->getNotifications()); + + if (empty($foundMessages)) { + return sprintf( + 'Expected to find a notification with a message containing "%s", but no notifications were found.', + $this->expectedMessage + ); + } + + return sprintf( + 'Expected to find a notification with a message containing "%s". Found messages: %s.', + $this->expectedMessage, + implode(', ', $foundMessages) + ); + } +} diff --git a/src/Prime/Test/Constraint/NotificationOption.php b/src/Prime/Test/Constraint/NotificationOption.php new file mode 100644 index 00000000..f7140532 --- /dev/null +++ b/src/Prime/Test/Constraint/NotificationOption.php @@ -0,0 +1,71 @@ +expectedKey); + + if ($this->expectedValue) { + $description .= sprintf(' having the value "%s"', json_encode($this->expectedValue)); + } + + return $description; + } + + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + foreach ($other->getNotifications() as $notification) { + if ($this->isOptionMatching($notification)) { + return true; + } + } + + return false; + } + + private function isOptionMatching(NotificationInterface $notification): bool + { + $options = $notification->getOptions(); + + return isset($options[$this->expectedKey]) && $options[$this->expectedKey] === $this->expectedValue; + } + + protected function failureDescription(mixed $other): string + { + $actualOptions = []; + if ($other instanceof NotificationEvents) { + foreach ($other->getNotifications() as $notification) { + $actualOptions[] = json_encode($notification->getOptions()); + } + } + + $actualOptionsString = implode('; ', $actualOptions) ?: 'none found'; + $expectation = $this->toString(); + + return "Failed asserting that NotificationEvents $expectation. Actual options: [$actualOptionsString]."; + } +} diff --git a/src/Prime/Test/Constraint/NotificationOptions.php b/src/Prime/Test/Constraint/NotificationOptions.php new file mode 100644 index 00000000..077f9972 --- /dev/null +++ b/src/Prime/Test/Constraint/NotificationOptions.php @@ -0,0 +1,59 @@ + $expectedOptions the expected options + */ + public function __construct(private readonly array $expectedOptions) + { + } + + public function toString(): string + { + return 'contains a notification with options matching '.json_encode($this->expectedOptions, \JSON_PRETTY_PRINT); + } + + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + foreach ($other->getNotifications() as $notification) { + if (!array_diff_assoc($this->expectedOptions, $notification->getOptions())) { + return true; + } + } + + return false; + } + + protected function failureDescription(mixed $other): string + { + $actualOptions = []; + if ($other instanceof NotificationEvents) { + foreach ($other->getNotifications() as $notification) { + $actualOptions[] = json_encode($notification->getOptions()); + } + } + + $actualOptionsString = implode('; ', $actualOptions) ?: 'none found'; + + return sprintf( + 'Failed asserting that NotificationEvents %s. Actual options in notifications: [%s].', + $this->toString(), + $actualOptionsString + ); + } +} diff --git a/src/Prime/Test/Constraint/NotificationTitle.php b/src/Prime/Test/Constraint/NotificationTitle.php new file mode 100644 index 00000000..d977d58b --- /dev/null +++ b/src/Prime/Test/Constraint/NotificationTitle.php @@ -0,0 +1,66 @@ +expectedTitle); + } + + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + foreach ($other->getNotifications() as $notification) { + if (str_contains($notification->getTitle(), $this->expectedTitle)) { + return true; + } + } + + return false; + } + + protected function failureDescription(mixed $other): string + { + if (!$other instanceof NotificationEvents) { + return 'Expected an instance of NotificationEvents but received a different type.'; + } + + $foundTitles = array_map(function (NotificationInterface $notification) { + return sprintf('"%s"', $notification->getTitle()); + }, $other->getNotifications()); + + if (empty($foundTitles)) { + return sprintf( + 'Expected to find a notification with a title containing "%s", but no notifications were found.', + $this->expectedTitle + ); + } + + return sprintf( + 'Expected to find a notification with a title containing "%s". Found titles: %s.', + $this->expectedTitle, + implode(', ', $foundTitles) + ); + } +} diff --git a/src/Prime/Test/Constraint/NotificationType.php b/src/Prime/Test/Constraint/NotificationType.php new file mode 100644 index 00000000..e59b4752 --- /dev/null +++ b/src/Prime/Test/Constraint/NotificationType.php @@ -0,0 +1,74 @@ +expectedType); + } + + /** + * Evaluates the constraint for the parameter $other. + * If $other is not an instance of NotificationEvents, the method will return false. + * + * @param NotificationEvents $other value or object to evaluate + * + * @return bool true if the constraint is met, false otherwise + */ + protected function matches(mixed $other): bool + { + if (!$other instanceof NotificationEvents) { + return false; + } + + foreach ($other->getNotifications() as $notification) { + if ($notification->getType() === $this->expectedType) { + return true; + } + } + + return false; + } + + /** + * Returns a custom failure description for when the constraint is not met. + * + * @param NotificationEvents $other evaluated object or value + * + * @return string the failure description + */ + protected function failureDescription(mixed $other): string + { + $actualTypes = array_map(function (NotificationInterface $notification) { + return $notification->getType(); + }, $other->getNotifications()); + + $uniqueTypes = array_unique($actualTypes); + $typesList = implode(', ', $uniqueTypes); + + return sprintf( + 'Expected the NotificationEvents to contain a notification of type "%s", but found types: %s.', + $this->expectedType, + $typesList ?: 'none' + ); + } +} diff --git a/src/Prime/Test/FlasherAssert.php b/src/Prime/Test/FlasherAssert.php new file mode 100644 index 00000000..609957a2 --- /dev/null +++ b/src/Prime/Test/FlasherAssert.php @@ -0,0 +1,416 @@ +hasNotifications('Custom error message if no notifications found.'); + * ``` + * + * @return self an instance of the FlasherAssert class to allow for method chaining + */ + public static function that(): self + { + return new self(); + } + + /** + * Asserts the presence of at least one notification in the system. + * This assertion passes if the notification system has logged any notifications, regardless of their specific attributes. + * + * @param string $message a custom message to display if the assertion fails + * + * @return self returns itself to allow method chaining + */ + public static function hasNotifications(string $message = 'Expected at least one notification to exist.'): self + { + return self::fluent(static fn () => Assert::assertNotEmpty(self::getNotificationEvents()->getNotifications(), $message)); + } + + /** + * Asserts that no notifications have been registered in the system. + * Useful for tests where the absence of notifications indicates a pass condition. + * + * @param string $message a custom message to display if the assertion fails + * + * @return self returns itself to allow method chaining + */ + public static function noNotifications(string $message = 'Expected no notifications to exist.'): self + { + return self::fluent(static fn () => Assert::assertEmpty(self::getNotificationEvents()->getNotifications(), $message)); + } + + /** + * Asserts the existence of a notification matching specific criteria including type, message, options, and title. + * A notification must match all provided criteria to satisfy the assertion. + * + * @param string $expectedType Expected notification type (e.g., 'success', 'error'). + * @param string|null $expectedMessage Expected message content. Null means the message is not considered. + * @param array $expectedOptions Expected options as an associative array. Empty array means options are not considered. + * @param string|null $expectedTitle Expected notification title. Null means the title is not considered. + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withNotification(string $expectedType, ?string $expectedMessage = null, array $expectedOptions = [], ?string $expectedTitle = null, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new Notification($expectedType, $expectedMessage, $expectedOptions, $expectedTitle), $message)); + } + + /** + * @alias of withNotification + * + * Asserts the existence of a notification matching specific criteria including type, message, options, and title. + * A notification must match all provided criteria to satisfy the assertion. + * + * @param string $expectedType Expected notification type (e.g., 'success', 'error'). + * @param string|null $expectedMessage Expected message content. Null means the message is not considered. + * @param array $expectedOptions Expected options as an associative array. Empty array means options are not considered. + * @param string|null $expectedTitle Expected notification title. Null means the title is not considered. + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function notification(string $expectedType, ?string $expectedMessage = null, array $expectedOptions = [], ?string $expectedTitle = null, string $message = ''): self + { + return self::withNotification($expectedType, $expectedMessage, $expectedOptions, $expectedTitle, $message); + } + + /** + * Asserts the total count of notifications matches an expected number. + * + * @param int $expectedCount expected number of notifications + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withCount(int $expectedCount, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationCount($expectedCount), $message)); + } + + /** + * @alias of withCount + * + * Asserts the total count of notifications matches an expected number. + * + * @param int $expectedCount expected number of notifications + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function count(int $expectedCount, string $message = ''): self + { + return self::withCount($expectedCount, $message); + } + + /** + * Asserts the existence of at least one notification of a specific type. + * + * @param string $expectedType expected notification type + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withType(string $expectedType, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationType($expectedType), $message)); + } + + /** + * @alias of withType + * + * Asserts the existence of at least one notification of a specific type. + * + * @param string $expectedType expected notification type + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function type(string $expectedType, string $message = ''): self + { + return self::withType($expectedType, $message); + } + + /** + * Asserts the presence of at least one 'success' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withSuccess(string $message = ''): self + { + return self::fluent(static fn () => self::type(Type::SUCCESS, $message)); + } + + /** + * @alias of withSuccess + * + * Asserts the presence of at least one 'success' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function success(string $message = ''): self + { + return self::withSuccess($message); + } + + /** + * Asserts the presence of at least one 'warning' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withWarning(string $message = ''): self + { + return self::fluent(static fn () => self::type(Type::WARNING, $message)); + } + + /** + * @alias of withWarning + * + * Asserts the presence of at least one 'warning' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function warning(string $message = ''): self + { + return self::withWarning($message); + } + + /** + * Asserts the presence of at least one 'error' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withError(string $message = ''): self + { + return self::fluent(static fn () => self::type(Type::ERROR, $message)); + } + + /** + * @alias of withError + * + * Asserts the presence of at least one 'error' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function error(string $message = ''): self + { + return self::withError($message); + } + + /** + * Asserts the presence of at least one 'info' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withInfo(string $message = ''): self + { + return self::fluent(static fn () => self::type(Type::INFO, $message)); + } + + /** + * @alias of withInfo + * + * Asserts the presence of at least one 'info' type notification. + * + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function info(string $message = ''): self + { + return self::withInfo($message); + } + + /** + * Asserts the presence of a notification with a specific title. + * + * @param string $expectedTitle expected notification title + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withTitle(string $expectedTitle, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationTitle($expectedTitle), $message)); + } + + /** + * @alias of withTitle + * + * Asserts the presence of a notification with a specific title. + * + * @param string $expectedTitle expected notification title + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function title(string $expectedTitle, string $message = ''): self + { + return self::withTitle($expectedTitle, $message); + } + + /** + * Asserts the presence of a notification with a specific message. + * + * @param string $expectedMessage expected notification message + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withMessage(string $expectedMessage, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationMessage($expectedMessage), $message)); + } + + /** + * @alias of withMessage + * + * Asserts the presence of a notification with a specific message. + * + * @param string $expectedMessage expected notification message + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function message(string $expectedMessage, string $message = ''): self + { + return self::withMessage($expectedMessage, $message); + } + + /** + * Asserts the presence of a notification with specific options. + * + * @param array $expectedOptions expected options as an associative array + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withOptions(array $expectedOptions, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationOptions($expectedOptions), $message)); + } + + /** + * @alias of withOptions + * + * Asserts the presence of a notification with specific options. + * + * @param array $expectedOptions expected options as an associative array + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function options(array $expectedOptions, string $message = ''): self + { + return self::withOptions($expectedOptions, $message); + } + + /** + * Asserts the presence of a notification with a specific option key and, optionally, a value. + * + * @param string $expectedKey expected option key + * @param mixed $expectedValue Expected value of the option. Null or omitted to skip value check. + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function withOption(string $expectedKey, mixed $expectedValue = null, string $message = ''): self + { + return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationOption($expectedKey, $expectedValue), $message)); + } + + /** + * @alias of withOption + * + * Asserts the presence of a notification with a specific option key and, optionally, a value. + * + * @param string $expectedKey expected option key + * @param mixed $expectedValue Expected value of the option. Null or omitted to skip value check. + * @param string $message custom failure message + * + * @return self returns itself to allow method chaining + */ + public static function option(string $expectedKey, mixed $expectedValue = null, string $message = ''): self + { + return self::withOption($expectedKey, $expectedValue, $message); + } + + /** + * A utility method used internally to wrap assertions and allow fluent interface chaining. + * Not intended for public use. + * + * @param callable $callback The assertion logic encapsulated in a callable function + * + * @return self returns itself to enable fluent chaining of methods + */ + private static function fluent(callable $callback): self + { + $callback(); + + return new self(); + } + + /** + * Fetches the NotificationEvents instance from the NotificationLoggerListener. + * This method simplifies the process of obtaining NotificationEvents, facilitating easier assertion writing in tests. + * + * @return NotificationEvents the NotificationEvents instance, allowing for further inspection or assertion of notification states + */ + public static function getNotificationEvents(): NotificationEvents + { + $container = FlasherContainer::getContainer(); + + if (!$container->has('flasher.notification_logger_listener')) { + return new NotificationEvents(); + } + + /** @var NotificationLoggerListener $listener */ + $listener = $container->get('flasher.notification_logger_listener'); + + return $listener->getEvents(); + } +} diff --git a/src/Prime/Translation/EchoTranslator.php b/src/Prime/Translation/EchoTranslator.php index 8cbbfd51..57247809 100644 --- a/src/Prime/Translation/EchoTranslator.php +++ b/src/Prime/Translation/EchoTranslator.php @@ -1,26 +1,20 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Translation; -final class EchoTranslator implements TranslatorInterface +/** + * In this implementation, it simply returns the identifier as is, without performing any actual translation. + */ +final readonly class EchoTranslator implements TranslatorInterface { - /** - * {@inheritDoc} - */ - public function translate($id, $parameters = array(), $locale = null) + public function translate(string $id, array $parameters = [], ?string $locale = null): string { return $id; } - /** - * {@inheritDoc} - */ - public function getLocale() + public function getLocale(): string { return 'en'; } diff --git a/src/Prime/Translation/Language.php b/src/Prime/Translation/Language.php index cce9f3c0..cca8d840 100644 --- a/src/Prime/Translation/Language.php +++ b/src/Prime/Translation/Language.php @@ -1,62 +1,67 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Translation; -final class Language +/** + * Provides utilities for determining the text direction (Left-to-Right or Right-to-Left) + * based on a given locale. This can be particularly useful for handling languages + * with different writing directions in internationalized applications. + */ +final readonly class Language { - const LTR = 'ltr'; - const RTL = 'rtl'; + public const LTR = 'ltr'; + + public const RTL = 'rtl'; /** - * @param string $locale + * Determines the text direction for a given locale. * - * @return string + * It uses the 'intl' PHP extension to get text direction from the ICU data. + * Defaults to Left-to-Right (LTR) if the 'intl' extension is not available, + * the locale is not found, or the text direction data is not available. + * + * @param string $locale the locale to check the text direction for + * + * @return string returns 'ltr' for Left-to-Right or 'rtl' for Right-to-Left text direction */ - public static function direction($locale) + public static function direction(string $locale): string { if (!\extension_loaded('intl')) { return self::LTR; } - $resource = \ResourceBundle::create($locale, 'ICUDATA', true); - if (null === $resource) { - return self::LTR; - } + $resource = \ResourceBundle::create($locale, 'ICUDATA', false); + $layout = $resource?->get('layout'); - $layout = $resource->get('layout'); if (!$layout instanceof \ResourceBundle) { return self::LTR; } - $characters = $layout->get('characters'); - if (!\is_string($characters)) { - return self::LTR; - } - - return 'right-to-left' === $characters ? self::RTL : self::LTR; + return 'right-to-left' === $layout->get('characters') ? self::RTL : self::LTR; } /** - * @param string $locale + * Checks if the given locale is Right-to-Left (RTL). * - * @return bool + * @param string $locale the locale to check + * + * @return bool returns true if the locale is RTL, false otherwise */ - public static function isRTL($locale) + public static function isRTL(string $locale): bool { return self::RTL === self::direction($locale); } /** - * @param string $locale + * Checks if the given locale is Left-to-Right (LTR). * - * @return bool + * @param string $locale the locale to check + * + * @return bool returns true if the locale is LTR, false otherwise */ - public static function isLTR($locale) + public static function isLTR(string $locale): bool { return self::LTR === self::direction($locale); } diff --git a/src/Prime/Translation/Language/Arabic.php b/src/Prime/Translation/Language/Arabic.php new file mode 100644 index 00000000..b183ada0 --- /dev/null +++ b/src/Prime/Translation/Language/Arabic.php @@ -0,0 +1,30 @@ + array of message keys and their Arabic translations + */ + public static function translations(): array + { + return [ + 'success' => 'نجاح', + 'error' => 'خطأ', + 'warning' => 'تحذير', + 'info' => 'معلومة', + + 'The resource was created' => 'تم إنشاء :resource', + 'The resource was updated' => 'تم تعديل :resource', + 'The resource was saved' => 'تم حفظ :resource', + 'The resource was deleted' => 'تم حذف :resource', + + 'resource' => 'الملف', + ]; + } +} diff --git a/src/Prime/Translation/Language/Chinese.php b/src/Prime/Translation/Language/Chinese.php new file mode 100644 index 00000000..0ca5ea75 --- /dev/null +++ b/src/Prime/Translation/Language/Chinese.php @@ -0,0 +1,30 @@ + array of message keys and their Chinese translations + */ + public static function translations(): array + { + return [ + 'success' => '成功', + 'error' => '错误', + 'warning' => '警告', + 'info' => '信息', + + 'The resource was created' => ':resource 已创建', + 'The resource was updated' => ':resource 已更新', + 'The resource was saved' => ':resource 已保存', + 'The resource was deleted' => ':resource 已删除', + + 'resource' => '资源', + ]; + } +} diff --git a/src/Prime/Translation/Language/English.php b/src/Prime/Translation/Language/English.php new file mode 100644 index 00000000..3487567d --- /dev/null +++ b/src/Prime/Translation/Language/English.php @@ -0,0 +1,30 @@ + array of message keys and their English translations + */ + public static function translations(): array + { + return [ + 'success' => 'Success', + 'error' => 'Error', + 'warning' => 'Warning', + 'info' => 'Info', + + 'The resource was created' => 'The :resource was created', + 'The resource was updated' => 'The :resource was updated', + 'The resource was saved' => 'The :resource was saved', + 'The resource was deleted' => 'The :resource was deleted', + + 'resource' => 'resource', + ]; + } +} diff --git a/src/Prime/Translation/Language/French.php b/src/Prime/Translation/Language/French.php new file mode 100644 index 00000000..e459e4b8 --- /dev/null +++ b/src/Prime/Translation/Language/French.php @@ -0,0 +1,30 @@ + array of message keys and their French translations + */ + public static function translations(): array + { + return [ + 'success' => 'Succès', + 'error' => 'Erreur', + 'warning' => 'Avertissement', + 'info' => 'Information', + + 'The resource was created' => 'La ressource :resource a été ajoutée', + 'The resource was updated' => 'La ressource :resource a été mise à jour', + 'The resource was saved' => 'La ressource :resource a été enregistrée', + 'The resource was deleted' => 'La ressource :resource a été supprimée', + + 'resource' => '', + ]; + } +} diff --git a/src/Prime/Translation/Language/German.php b/src/Prime/Translation/Language/German.php new file mode 100644 index 00000000..a03359bf --- /dev/null +++ b/src/Prime/Translation/Language/German.php @@ -0,0 +1,30 @@ + array of message keys and their German translations + */ + public static function translations(): array + { + return [ + 'success' => 'Erfolg', + 'error' => 'Fehler', + 'warning' => 'Warnung', + 'info' => 'Info', + + 'The resource was created' => 'Die Ressource :resource wurde erstellt', + 'The resource was updated' => 'Die Ressource :resource wurde aktualisiert', + 'The resource was saved' => 'Die Ressource :resource wurde gespeichert', + 'The resource was deleted' => 'Die Ressource :resource wurde gelöscht', + + 'resource' => 'Ressource', + ]; + } +} diff --git a/src/Prime/Translation/Language/Portuguese.php b/src/Prime/Translation/Language/Portuguese.php new file mode 100644 index 00000000..11ae496d --- /dev/null +++ b/src/Prime/Translation/Language/Portuguese.php @@ -0,0 +1,30 @@ + array of message keys and their Portuguese translations + */ + public static function translations(): array + { + return [ + 'success' => 'Sucesso', + 'error' => 'Erro', + 'warning' => 'Aviso', + 'info' => 'Informação', + + 'The resource was created' => 'O :resource foi criado', + 'The resource was updated' => 'O :resource foi atualizado', + 'The resource was saved' => 'O :resource foi salvo', + 'The resource was deleted' => 'O :resource foi deletado', + + 'resource' => 'recurso', + ]; + } +} diff --git a/src/Prime/Translation/Language/Russian.php b/src/Prime/Translation/Language/Russian.php new file mode 100644 index 00000000..b2ab0c9e --- /dev/null +++ b/src/Prime/Translation/Language/Russian.php @@ -0,0 +1,30 @@ + array of message keys and their Russian translations + */ + public static function translations(): array + { + return [ + 'success' => 'Успех', + 'error' => 'Ошибка', + 'warning' => 'Предупреждение', + 'info' => 'Информация', + + 'The resource was created' => ':resource был создан', + 'The resource was updated' => ':resource был обновлен', + 'The resource was saved' => ':resource был сохранен', + 'The resource was deleted' => ':resource был удален', + + 'resource' => 'ресурс', + ]; + } +} diff --git a/src/Prime/Translation/Language/Spanish.php b/src/Prime/Translation/Language/Spanish.php new file mode 100644 index 00000000..97e49e25 --- /dev/null +++ b/src/Prime/Translation/Language/Spanish.php @@ -0,0 +1,30 @@ + array of message keys and their Spanish translations + */ + public static function translations(): array + { + return [ + 'success' => 'Éxito', + 'error' => 'Error', + 'warning' => 'Advertencia', + 'info' => 'Información', + + 'The resource was created' => 'El :resource fue creado', + 'The resource was updated' => 'El :resource fue actualizado', + 'The resource was saved' => 'El :resource fue guardado', + 'The resource was deleted' => 'El :resource fue eliminado', + + 'resource' => 'recurso', + ]; + } +} diff --git a/src/Prime/Translation/Messages.php b/src/Prime/Translation/Messages.php index d4872b53..6f46d754 100644 --- a/src/Prime/Translation/Messages.php +++ b/src/Prime/Translation/Messages.php @@ -1,62 +1,40 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Translation; -final class Messages +use Flasher\Prime\Translation\Language\Arabic; +use Flasher\Prime\Translation\Language\Chinese; +use Flasher\Prime\Translation\Language\English; +use Flasher\Prime\Translation\Language\French; +use Flasher\Prime\Translation\Language\German; +use Flasher\Prime\Translation\Language\Portuguese; +use Flasher\Prime\Translation\Language\Russian; +use Flasher\Prime\Translation\Language\Spanish; + +/** + * This class provides a set of predefined message translations in various languages. + * It holds arrays of key-value pairs where keys are message identifiers and values + * are their respective translations. + */ +final readonly class Messages { /** - * @var array + * @return array */ - public static $ar = array( - 'success' => 'نجاح', - 'error' => 'خطأ', - 'warning' => 'تحذير', - 'info' => 'معلومة', - - 'The resource was created' => 'تم إنشاء :resource', - 'The resource was updated' => 'تم تعديل :resource', - 'The resource was saved' => 'تم حفظ :resource', - 'The resource was deleted' => 'تم حذف :resource', - - 'resource' => 'الملف', - ); - - /** - * @var array - */ - public static $en = array( - 'success' => 'Success', - 'error' => 'Error', - 'warning' => 'Warning', - 'info' => 'Info', - - 'The resource was created' => 'The :resource was created', - 'The resource was updated' => 'The :resource was updated', - 'The resource was saved' => 'The :resource was saved', - 'The resource was deleted' => 'The :resource was deleted', - - 'resource' => 'resource', - ); - - /** - * @var array - */ - public static $fr = array( - 'success' => 'Succès', - 'error' => 'Erreur', - 'warning' => 'Avertissement', - 'info' => 'Information', - - 'The resource was created' => 'La ressource :resource a été ajoutée', - 'The resource was updated' => 'La ressource :resource a été mise à jour', - 'The resource was saved' => 'La ressource :resource a été enregistrée', - 'The resource was deleted' => 'La ressource :resource a été supprimée', - - 'resource' => '', - ); + public static function get(string $language): array + { + return match ($language) { + 'ar' => Arabic::translations(), + 'de' => German::translations(), + 'en' => English::translations(), + 'es' => Spanish::translations(), + 'fr' => French::translations(), + 'pt' => Portuguese::translations(), + 'ru' => Russian::translations(), + 'zh' => Chinese::translations(), + default => [], + }; + } } diff --git a/src/Prime/Translation/ResourceInterface.php b/src/Prime/Translation/ResourceInterface.php index b2e768ac..af4161a2 100644 --- a/src/Prime/Translation/ResourceInterface.php +++ b/src/Prime/Translation/ResourceInterface.php @@ -1,21 +1,12 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Translation; interface ResourceInterface { - /** - * @return string - */ - public function getResourceType(); + public function getResourceType(): string; - /** - * @return string - */ - public function getResourceName(); + public function getResourceName(): string; } diff --git a/src/Prime/Translation/TranslatorInterface.php b/src/Prime/Translation/TranslatorInterface.php index 985f1d86..b605bafb 100644 --- a/src/Prime/Translation/TranslatorInterface.php +++ b/src/Prime/Translation/TranslatorInterface.php @@ -1,25 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\Prime\Translation; interface TranslatorInterface { /** - * @param string $id * @param array $parameters - * @param string|null $locale - * - * @return string */ - public function translate($id, $parameters = array(), $locale = null); + public function translate(string $id, array $parameters = [], ?string $locale = null): string; - /** - * @return string - */ - public function getLocale(); + public function getLocale(): string; } diff --git a/src/Prime/composer.json b/src/Prime/composer.json index e44b752c..34b46b2f 100644 --- a/src/Prime/composer.json +++ b/src/Prime/composer.json @@ -1,55 +1,57 @@ { "name": "php-flasher/flasher", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher Core - A powerful pure PHP library, dedicated to bringing elegant flash messages to your web applications. Whether it's Laravel or Symfony, PHPFlasher ensures seamless user feedback integration, boosting user engagement and enriching the overall experience. Built with an intuitive design, it caters to developers across the spectrum, offering a reliable, flexible solution that is also framework-agnostic. PHPFlasher Core is built for RTL and Dark Mode support, and even includes PHPStorm auto-complete feature for easy development.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2" + }, "autoload": { "psr-4": { "Flasher\\Prime\\": "" }, "files": [ + "functions.php", "helpers.php" ] }, "config": { "preferred-install": "dist", "sort-packages": true + }, + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } } } diff --git a/src/Prime/extension.neon b/src/Prime/extension.neon new file mode 100644 index 00000000..0a9d2b0c --- /dev/null +++ b/src/Prime/extension.neon @@ -0,0 +1,10 @@ +services: + - + class: Flasher\Prime\Phpstan\ReturnTypes\FlasherContainerDynamicStaticMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: Flasher\Prime\Phpstan\ReturnTypes\FlashHelperExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension diff --git a/src/Prime/functions.php b/src/Prime/functions.php new file mode 100644 index 00000000..baa66e94 --- /dev/null +++ b/src/Prime/functions.php @@ -0,0 +1,45 @@ + $options additional options for the flash message + * @param string|null $title the title of the flash message + * + * @return Envelope|FlasherInterface|NotificationFactoryInterface Returns an Envelope containing the message details when arguments are provided. + * Returns an instance of FlasherInterface or NotificationFactoryInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Flasher factory: $flasher = flash(); + * 2. With arguments - Create and return a flash message: + * flash('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); + */ + function flash(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|FlasherInterface|NotificationFactoryInterface + { + $factory = FlasherContainer::create('flasher'); + + if (0 === \func_num_args()) { + return $factory; + } + + return $factory->flash($type, $message, $options, $title); + } +} diff --git a/src/Prime/helpers.php b/src/Prime/helpers.php index c565a730..f86cb1e8 100644 --- a/src/Prime/helpers.php +++ b/src/Prime/helpers.php @@ -1,48 +1,44 @@ - */ +declare(strict_types=1); use Flasher\Prime\Container\FlasherContainer; +use Flasher\Prime\Factory\NotificationFactoryInterface; use Flasher\Prime\FlasherInterface; use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Stamp\StampInterface; +use Flasher\Prime\Notification\Type; if (!function_exists('flash')) { /** - * @param string $message - * @param string $type - * @param array $options - * @param StampInterface[] $stamps + * Creates a flash message or returns the Flasher factory. * - * @return Envelope|FlasherInterface + * This function serves a dual purpose: + * 1. When called with no arguments, it returns an instance of FlasherInterface or NotificationFactoryInterface. + * This allows for accessing various methods provided by the Flasher factory. + * 2. When called with arguments, it creates a flash message and returns an Envelope. + * This envelope contains the flash message details and can be used for further operations. + * + * @param string|null $message the message content of the flash message + * @param string $type The type of the message (e.g., success, error, warning, info). + * @param array $options additional options for the flash message + * @param string|null $title the title of the flash message + * + * @return Envelope|FlasherInterface|NotificationFactoryInterface Returns an Envelope containing the message details when arguments are provided. + * Returns an instance of FlasherInterface or NotificationFactoryInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Flasher factory: $flasher = flash(); + * 2. With arguments - Create and return a flash message: + * flash('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); */ - function flash($message = null, $type = 'success', array $options = array(), array $stamps = array()) + function flash(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|FlasherInterface|NotificationFactoryInterface { - /** @var FlasherInterface $factory */ $factory = FlasherContainer::create('flasher'); if (0 === func_num_args()) { return $factory; } - return $factory->with($stamps)->addFlash($type, $message, $options); - } -} - -if (!function_exists('flasher')) { - /** - * @param string $message - * @param string $type - * @param array $options - * @param StampInterface[] $stamps - * - * @return Envelope|FlasherInterface - */ - function flasher($message = null, $type = 'success', array $options = array(), array $stamps = array()) - { - return flash($message, $type, $options, $stamps); + return $factory->flash($type, $message, $options, $title); } } diff --git a/src/SweetAlert/Laravel/.github/FUNDING.yml b/src/SweetAlert/Laravel/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/SweetAlert/Laravel/.github/FUNDING.yml +++ b/src/SweetAlert/Laravel/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/SweetAlert/Laravel/.github/workflows/auto_closer.yaml b/src/SweetAlert/Laravel/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/SweetAlert/Laravel/.github/workflows/auto_closer.yaml +++ b/src/SweetAlert/Laravel/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/SweetAlert/Laravel/Facade/SweetAlert.php b/src/SweetAlert/Laravel/Facade/SweetAlert.php index 4af59edd..ee4343c0 100644 --- a/src/SweetAlert/Laravel/Facade/SweetAlert.php +++ b/src/SweetAlert/Laravel/Facade/SweetAlert.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\SweetAlert\Laravel\Facade; @@ -107,9 +104,9 @@ use Illuminate\Support\Facades\Facade; * @method static SweetAlertBuilder inputValidator(string $inputValidator) * @method static SweetAlertBuilder validationMessage(string $validationMessage) */ -class SweetAlert extends Facade +final class SweetAlert extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'flasher.sweetalert'; } diff --git a/src/SweetAlert/Laravel/FlasherSweetAlertServiceProvider.php b/src/SweetAlert/Laravel/FlasherSweetAlertServiceProvider.php index f71a8aac..e3d67479 100644 --- a/src/SweetAlert/Laravel/FlasherSweetAlertServiceProvider.php +++ b/src/SweetAlert/Laravel/FlasherSweetAlertServiceProvider.php @@ -1,39 +1,27 @@ - */ +declare(strict_types=1); namespace Flasher\SweetAlert\Laravel; -use Flasher\Laravel\Support\ServiceProvider; +use Flasher\Laravel\Support\PluginServiceProvider; use Flasher\Prime\EventDispatcher\EventDispatcherInterface; use Flasher\SweetAlert\Prime\SweetAlertPlugin; use Livewire\LivewireManager; -final class FlasherSweetAlertServiceProvider extends ServiceProvider +final class FlasherSweetAlertServiceProvider extends PluginServiceProvider { - /** - * {@inheritDoc} - */ - public function createPlugin() + public function createPlugin(): SweetAlertPlugin { return new SweetAlertPlugin(); } - /** - * {@inheritDoc} - */ - protected function afterBoot() + protected function afterBoot(): void { $this->registerLivewireListener(); } - /** - * @return void - */ - private function registerLivewireListener() + private function registerLivewireListener(): void { if (!$this->app->bound('livewire')) { return; @@ -44,8 +32,8 @@ final class FlasherSweetAlertServiceProvider extends ServiceProvider return; } - $this->app->extend('flasher.event_dispatcher', function (EventDispatcherInterface $dispatcher) { - $dispatcher->addSubscriber(new LivewireListener()); + $this->app->extend('flasher.event_dispatcher', static function (EventDispatcherInterface $dispatcher) { + $dispatcher->addListener(new LivewireListener()); return $dispatcher; }); diff --git a/src/SweetAlert/Laravel/LICENSE b/src/SweetAlert/Laravel/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/SweetAlert/Laravel/LICENSE +++ b/src/SweetAlert/Laravel/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/SweetAlert/Laravel/LivewireListener.php b/src/SweetAlert/Laravel/LivewireListener.php index dfb057c8..7a937ad9 100644 --- a/src/SweetAlert/Laravel/LivewireListener.php +++ b/src/SweetAlert/Laravel/LivewireListener.php @@ -1,21 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\SweetAlert\Laravel; use Flasher\Prime\EventDispatcher\Event\ResponseEvent; -use Flasher\Prime\EventDispatcher\EventListener\EventSubscriberInterface; +use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface; -final class LivewireListener implements EventSubscriberInterface +final readonly class LivewireListener implements EventListenerInterface { - /** - * @return void - */ - public function __invoke(ResponseEvent $event) + public function __invoke(ResponseEvent $event): void { if ('html' !== $event->getPresenter()) { return; @@ -26,37 +20,46 @@ final class LivewireListener implements EventSubscriberInterface return; } - if (false === strripos($response, ' JAVASCRIPT; @@ -64,8 +67,8 @@ JAVASCRIPT; $event->setResponse($response); } - public static function getSubscribedEvents() + public function getSubscribedEvents(): string|array { - return 'Flasher\Prime\EventDispatcher\Event\ResponseEvent'; + return ResponseEvent::class; } } diff --git a/src/SweetAlert/Laravel/README.md b/src/SweetAlert/Laravel/README.md index 70a05eb4..cd352ed2 100644 --- a/src/SweetAlert/Laravel/README.md +++ b/src/SweetAlert/Laravel/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/SweetAlert/Laravel/Resources/config.php b/src/SweetAlert/Laravel/Resources/config.php deleted file mode 100644 index b5bec044..00000000 --- a/src/SweetAlert/Laravel/Resources/config.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -return array( - 'scripts' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-sweetalert@1.3.2/dist/flasher-sweetalert.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-sweetalert.min.js', - ), - ), - 'styles' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-sweetalert@1.3.2/dist/flasher-sweetalert.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-sweetalert.min.css', - ), - ), -); diff --git a/src/SweetAlert/Laravel/composer.json b/src/SweetAlert/Laravel/composer.json index 9e49ecde..4e4c1f26 100644 --- a/src/SweetAlert/Laravel/composer.json +++ b/src/SweetAlert/Laravel/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-sweetalert-laravel", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-laravel": "^1.15.14", - "php-flasher/flasher-sweetalert": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-laravel": "^2.0", + "php-flasher/flasher-sweetalert": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\SweetAlert\\Laravel\\": "" @@ -53,12 +47,12 @@ }, "extra": { "laravel": { - "aliases": { - "SweetAlert": "Flasher\\SweetAlert\\Laravel\\Facade\\SweetAlert" - }, "providers": [ "Flasher\\SweetAlert\\Laravel\\FlasherSweetAlertServiceProvider" - ] + ], + "aliases": { + "SweetAlert": "Flasher\\SweetAlert\\Laravel\\Facade\\SweetAlert" + } } } } diff --git a/src/SweetAlert/Prime/.github/FUNDING.yml b/src/SweetAlert/Prime/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/SweetAlert/Prime/.github/FUNDING.yml +++ b/src/SweetAlert/Prime/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/SweetAlert/Prime/.github/workflows/auto_closer.yaml b/src/SweetAlert/Prime/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/SweetAlert/Prime/.github/workflows/auto_closer.yaml +++ b/src/SweetAlert/Prime/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/SweetAlert/Prime/.phpstorm.meta.php b/src/SweetAlert/Prime/.phpstorm.meta.php index a9e41208..163438cc 100644 --- a/src/SweetAlert/Prime/.phpstorm.meta.php +++ b/src/SweetAlert/Prime/.phpstorm.meta.php @@ -3,6 +3,8 @@ namespace PHPSTORM_META; expectedArguments(\sweetalert(), 1, 'success', 'error', 'info', 'warning'); +expectedArguments(\Flasher\SweetAlert\Prime\sweetalert(), 1, 'success', 'error', 'info', 'warning'); + expectedArguments(\Flasher\SweetAlert\Prime\SweetAlertBuilder::icon(), 0, 'warning', 'error', 'success', 'info', 'question'); expectedArguments(\Flasher\SweetAlert\Prime\SweetAlertBuilder::showClass(), 0, 'popup', 'backdrop', 'icon'); expectedArguments(\Flasher\SweetAlert\Prime\SweetAlertBuilder::hideClass(), 0, 'popup', 'backdrop', 'icon'); @@ -12,10 +14,6 @@ expectedArguments(\Flasher\SweetAlert\Prime\SweetAlertBuilder::toast(), 1, 'top' expectedArguments(\Flasher\SweetAlert\Prime\SweetAlertBuilder::grow(), 0, 'row', 'column', 'fullscreen', false); expectedArguments(\Flasher\SweetAlert\Prime\SweetAlertBuilder::customClass(), 0, 'container', 'popup', 'header', 'title', 'closeButton', 'icon', 'image', 'content', 'input', 'inputLabel', 'validationMessage', 'actions', 'confirmButton', 'denyButton', 'cancelButton', 'loader', 'footer'); -override(\Flasher\Prime\FlasherInterface::create(), map([ - 'sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class -])); +override(\Flasher\Prime\FlasherInterface::use(), map(['sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertInterface::class])); +override(\Flasher\Prime\Container\FlasherContainer::create(), map(['flasher.sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertInterface::class])); -override(\Flasher\Prime\FlasherInterface::using(), map([ - 'sweetalert' => \Flasher\SweetAlert\Prime\SweetAlertFactory::class -])); diff --git a/src/SweetAlert/Prime/LICENSE b/src/SweetAlert/Prime/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/SweetAlert/Prime/LICENSE +++ b/src/SweetAlert/Prime/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/SweetAlert/Prime/README.md b/src/SweetAlert/Prime/README.md index 70a05eb4..cd352ed2 100644 --- a/src/SweetAlert/Prime/README.md +++ b/src/SweetAlert/Prime/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
Younes KHOUBZA
Younes KHOUBZA

💻 📖 🚧
Younes ENNAJI
Younes ENNAJI

💻 📖 🚧
Salma Mourad
Salma Mourad

💵
Nashwan Abdullah
Nashwan Abdullah

💵
Arvid de Jong
Arvid de Jong

💵
- + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

Made with ❤️ by Younes KHOUBZA

+

Made with ❤️ by Younes ENNAJI

diff --git a/src/SweetAlert/Prime/Resources/assets/flasher-sweetalert.min.css b/src/SweetAlert/Prime/Resources/assets/flasher-sweetalert.min.css deleted file mode 100644 index 437fb962..00000000 --- a/src/SweetAlert/Prime/Resources/assets/flasher-sweetalert.min.css +++ /dev/null @@ -1 +0,0 @@ -.swal2-popup.swal2-toast{background:#fff;box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);box-sizing:border-box;grid-column:1/4!important;grid-row:1/4!important;grid-template-columns:min-content auto min-content;overflow-y:hidden;padding:1em;pointer-events:all}.swal2-popup.swal2-toast>*{grid-column:2}.swal2-popup.swal2-toast .swal2-title{font-size:1em;margin:.5em 1em;padding:0;text-align:initial}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{font-size:1em;height:2em;margin:.5em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{font-size:.8em;margin:.5em 0 0;padding:.5em 0 0}.swal2-popup.swal2-toast .swal2-close{align-self:center;font-size:2em;grid-column:3/3;grid-row:1/99;height:.8em;margin:0;width:.8em}.swal2-popup.swal2-toast .swal2-html-container{font-size:1em;margin:.5em 1em;overflow:initial;padding:0;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-loader{align-self:center;grid-column:1;grid-row:1/99;height:2em;margin:.25em;width:2em}.swal2-popup.swal2-toast .swal2-icon{align-self:center;grid-column:1;grid-row:1/99;height:2em;margin:0 .5em 0 0;min-width:2em;width:2em}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{align-items:center;display:flex;font-size:1.8em;font-weight:700}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{height:2em;width:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{height:auto;justify-content:flex-start;margin:.5em 0 0;padding:0 .5em}.swal2-popup.swal2-toast .swal2-styled{font-size:1em;margin:.25em .5em;padding:.4em .6em}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{border-radius:50%;height:3em;position:absolute;transform:rotate(45deg);width:1.6em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{border-radius:4em 0 0 4em;left:-.5em;top:-.8em;transform:rotate(-45deg);transform-origin:2em 2em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{border-radius:0 4em 4em 0;left:.9375em;top:-.25em;transform-origin:0 1.5em}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{height:2em;width:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{height:2.6875em;left:.4375em;top:0;width:.4375em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{left:.1875em;top:1.125em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{right:.1875em;top:.9375em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}div:where(.swal2-container){-webkit-overflow-scrolling:touch;box-sizing:border-box;display:grid;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content,auto) minmax(min-content,auto) minmax(min-content,auto);height:100%;inset:0;overflow-x:hidden;padding:.625em;position:fixed;transition:background-color .1s;z-index:1060}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:rgba(0,0,0,.4)}div:where(.swal2-container).swal2-backdrop-hide{background:transparent!important}div:where(.swal2-container).swal2-bottom-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-top-start{grid-template-columns:minmax(0,1fr) auto auto}div:where(.swal2-container).swal2-bottom,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-top{grid-template-columns:auto minmax(0,1fr) auto}div:where(.swal2-container).swal2-bottom-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-top-end{grid-template-columns:auto auto minmax(0,1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{align-self:start;grid-column:2;justify-self:center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{align-self:start;grid-column:3;justify-self:end}div:where(.swal2-container).swal2-center-left>.swal2-popup,div:where(.swal2-container).swal2-center-start>.swal2-popup{align-self:center;grid-row:2}div:where(.swal2-container).swal2-center>.swal2-popup{align-self:center;grid-column:2;grid-row:2;justify-self:center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{align-self:center;grid-column:3;grid-row:2;justify-self:end}div:where(.swal2-container).swal2-bottom-left>.swal2-popup,div:where(.swal2-container).swal2-bottom-start>.swal2-popup{align-self:end;grid-column:1;grid-row:3}div:where(.swal2-container).swal2-bottom>.swal2-popup{align-self:end;grid-column:2;grid-row:3;justify-self:center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{align-self:end;grid-column:3;grid-row:3;justify-self:end}div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup,div:where(.swal2-container).swal2-grow-row>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{align-self:stretch;grid-row:1/4}div:where(.swal2-container).swal2-no-transition{transition:none!important}div:where(.swal2-container) div:where(.swal2-popup){background:#fff;border:none;border-radius:5px;box-sizing:border-box;color:#545454;display:none;font-family:inherit;font-size:1rem;grid-template-columns:minmax(0,100%);max-width:100%;padding:0 0 1.25em;position:relative;width:32em}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) h2:where(.swal2-title){word-wrap:break-word;color:inherit;font-size:1.875em;font-weight:600;margin:0;max-width:100%;padding:.8em 1em 0;position:relative;text-align:center;text-transform:none}div:where(.swal2-container) div:where(.swal2-actions){align-items:center;box-sizing:border-box;display:flex;flex-wrap:wrap;justify-content:center;margin:1.25em auto 0;padding:0;width:auto;z-index:1}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}div:where(.swal2-container) div:where(.swal2-loader){align-items:center;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-color:#2778c4 transparent;border-radius:100%;border-style:solid;border-width:.25em;display:none;height:2.2em;justify-content:center;margin:0 1.875em;width:2.2em}div:where(.swal2-container) button:where(.swal2-styled){box-shadow:0 0 0 3px transparent;font-weight:500;margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled).swal2-confirm{background:initial;background-color:#7066e0;border:0;border-radius:.25em;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled).swal2-confirm:focus{box-shadow:0 0 0 3px rgba(112,102,224,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-deny{background:initial;background-color:#dc3741;border:0;border-radius:.25em;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled).swal2-deny:focus{box-shadow:0 0 0 3px rgba(220,55,65,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-cancel{background:initial;background-color:#6e7881;border:0;border-radius:.25em;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled).swal2-cancel:focus{box-shadow:0 0 0 3px hsla(208,8%,47%,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-default-outline:focus{box-shadow:0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-styled):focus{outline:none}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){border-top:1px solid #eee;color:inherit;font-size:1em;justify-content:center;margin:1em 0 0;padding:1em 1em 0}div:where(.swal2-container) .swal2-timer-progress-bar-container{border-bottom-left-radius:5px;border-bottom-right-radius:5px;bottom:0;grid-column:auto!important;left:0;overflow:hidden;position:absolute;right:0}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){background:rgba(0,0,0,.2);height:.25em;width:100%}div:where(.swal2-container) img:where(.swal2-image){margin:2em auto 1em;max-width:100%}div:where(.swal2-container) button:where(.swal2-close){align-items:center;background:transparent;border:none;border-radius:5px;color:#ccc;cursor:pointer;font-family:monospace;font-size:2.5em;height:1.2em;justify-content:center;justify-self:end;margin-bottom:-1.2em;margin-right:0;margin-top:0;overflow:hidden;padding:0;transition:color .1s,box-shadow .1s;width:1.2em;z-index:2}div:where(.swal2-container) button:where(.swal2-close):hover{background:transparent;color:#f27474;transform:none}div:where(.swal2-container) button:where(.swal2-close):focus{box-shadow:inset 0 0 0 3px rgba(100,150,200,.5);outline:none}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) .swal2-html-container{word-wrap:break-word;color:inherit;font-size:1.125em;font-weight:400;justify-content:center;line-height:normal;margin:1em 1.6em .3em;overflow:auto;padding:0;text-align:center;word-break:break-word;z-index:1}div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) label:where(.swal2-checkbox),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) textarea:where(.swal2-textarea){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) textarea:where(.swal2-textarea){background:transparent;border:1px solid #d9d9d9;border-radius:.1875em;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px transparent;box-sizing:border-box;color:inherit;font-size:1.125em;transition:border-color .1s,box-shadow .1s;width:auto}div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:1px solid #b4dbed;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5);outline:none}div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{background:#fff;margin:1em 2em 3px}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{color:inherit;font-weight:600;text-align:center;width:20%}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{font-size:1.125em;height:2.625em;line-height:2.625em;padding:0}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{background:transparent;font-size:1.125em;margin-left:auto;margin-right:auto;width:75%}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{background:transparent;color:inherit;font-size:1.125em;max-width:100%;min-width:50%;padding:.375em .625em}div:where(.swal2-container) .swal2-checkbox,div:where(.swal2-container) .swal2-radio{align-items:center;background:#fff;color:inherit;justify-content:center}div:where(.swal2-container) .swal2-checkbox label,div:where(.swal2-container) .swal2-radio label{font-size:1.125em;margin:0 .6em}div:where(.swal2-container) .swal2-checkbox input,div:where(.swal2-container) .swal2-radio input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;background:#f0f0f0;color:#666;font-size:1em;font-weight:300;justify-content:center;margin:1em 0 0;overflow:hidden;padding:.625em}div:where(.swal2-container) div:where(.swal2-validation-message):before{background-color:#f27474;border-radius:50%;color:#fff;content:"!";display:inline-block;font-weight:600;height:1.5em;line-height:1.5em;margin:0 .625em;min-width:1.5em;text-align:center;width:1.5em}div:where(.swal2-container) div:where(.swal2-icon){border:.25em solid #000;border-radius:50%;box-sizing:content-box;cursor:default;font-family:inherit;height:5em;justify-content:center;line-height:5em;margin:2.5em auto .6em;position:relative;user-select:none;width:5em}div:where(.swal2-container) div:where(.swal2-icon) .swal2-icon-content{align-items:center;display:flex;font-size:3.75em}div:where(.swal2-container) div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-container) div:where(.swal2-icon).swal2-error .swal2-x-mark{flex-grow:1;position:relative}div:where(.swal2-container) div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{background-color:#f27474;border-radius:.125em;display:block;height:.3125em;position:absolute;top:2.3125em;width:2.9375em}div:where(.swal2-container) div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-container) div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-container) div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-container) div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-container) div:where(.swal2-icon).swal2-warning{border-color:#facea8;color:#f8bb86}div:where(.swal2-container) div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-container) div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-container) div:where(.swal2-icon).swal2-info{border-color:#9de0f6;color:#3fc3ee}div:where(.swal2-container) div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-container) div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-container) div:where(.swal2-icon).swal2-question{border-color:#c9dae1;color:#87adbd}div:where(.swal2-container) div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-container) div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-container) div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-container) div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{border-radius:50%;height:7.5em;position:absolute;transform:rotate(45deg);width:3.75em}div:where(.swal2-container) div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{border-radius:7.5em 0 0 7.5em;left:-2.0635em;top:-.4375em;transform:rotate(-45deg);transform-origin:3.75em 3.75em}div:where(.swal2-container) div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{border-radius:0 7.5em 7.5em 0;left:1.875em;top:-.6875em;transform:rotate(-45deg);transform-origin:0 3.75em}div:where(.swal2-container) div:where(.swal2-icon).swal2-success .swal2-success-ring{border:.25em solid hsla(98,55%,69%,.3);border-radius:50%;box-sizing:content-box;height:100%;left:-.25em;position:absolute;top:-.25em;width:100%;z-index:2}div:where(.swal2-container) div:where(.swal2-icon).swal2-success .swal2-success-fix{height:5.625em;left:1.625em;position:absolute;top:.5em;transform:rotate(-45deg);width:.4375em;z-index:1}div:where(.swal2-container) div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{background-color:#a5dc86;border-radius:.125em;display:block;height:.3125em;position:absolute;z-index:2}div:where(.swal2-container) div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{left:.8125em;top:2.875em;transform:rotate(45deg);width:1.5625em}div:where(.swal2-container) div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{right:.5em;top:2.375em;transform:rotate(-45deg);width:2.9375em}div:where(.swal2-container) div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-container) div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-container) div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}div:where(.swal2-container) .swal2-progress-steps{align-items:center;background:transparent;flex-wrap:wrap;font-weight:600;margin:1.25em auto;max-width:100%;padding:0}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{background:#2778c4;border-radius:2em;color:#fff;flex-shrink:0;height:2em;line-height:2em;text-align:center;width:2em;z-index:20}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{background:#2778c4;flex-shrink:0;height:.4em;margin:0 -1px;width:2.5em;z-index:10}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:swal2-show .3s}.swal2-hide{animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{height:50px;overflow:scroll;position:absolute;top:-9999px;width:50px}.swal2-rtl .swal2-close{margin-left:0;margin-right:0}.swal2-rtl .swal2-timer-progress-bar{left:auto;right:0}@keyframes swal2-toast-show{0%{transform:translateY(-.625em) rotate(2deg)}33%{transform:translateY(0) rotate(-2deg)}66%{transform:translateY(.3125em) rotate(2deg)}to{transform:translateY(0) rotate(0deg)}}@keyframes swal2-toast-hide{to{opacity:0;transform:rotate(1deg)}}@keyframes swal2-toast-animate-success-line-tip{0%{left:.0625em;top:.5625em;width:0}54%{left:.125em;top:.125em;width:0}70%{left:-.25em;top:.625em;width:1.625em}84%{left:.75em;top:1.0625em;width:.5em}to{left:.1875em;top:1.125em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{right:1.375em;top:1.625em;width:0}65%{right:.9375em;top:1.25em;width:0}84%{right:0;top:.9375em;width:1.125em}to{right:.1875em;top:.9375em;width:1.375em}}@keyframes swal2-show{0%{transform:scale(.7)}45%{transform:scale(1.05)}80%{transform:scale(.95)}to{transform:scale(1)}}@keyframes swal2-hide{0%{opacity:1;transform:scale(1)}to{opacity:0;transform:scale(.5)}}@keyframes swal2-animate-success-line-tip{0%{left:.0625em;top:1.1875em;width:0}54%{left:.125em;top:1.0625em;width:0}70%{left:-.375em;top:2.1875em;width:3.125em}84%{left:1.3125em;top:3em;width:1.0625em}to{left:.8125em;top:2.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{right:2.875em;top:3.375em;width:0}65%{right:2.875em;top:3.375em;width:0}84%{right:0;top:2.1875em;width:3.4375em}to{right:.5em;top:2.375em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}to{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;opacity:0;transform:scale(.4)}50%{margin-top:1.625em;opacity:0;transform:scale(.4)}80%{margin-top:-.375em;transform:scale(1.15)}to{margin-top:0;opacity:1;transform:scale(1)}}@keyframes swal2-animate-error-icon{0%{opacity:0;transform:rotateX(100deg)}to{opacity:1;transform:rotateX(0deg)}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-1turn)}to{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{opacity:0;transform:rotate(45deg)}25%{opacity:.4;transform:rotate(-25deg)}50%{opacity:.8;transform:rotate(15deg)}75%{opacity:1;transform:rotate(-5deg)}to{opacity:1;transform:rotateX(0)}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto!important}body.swal2-no-backdrop .swal2-container{background-color:transparent!important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static!important}}body.swal2-toast-shown .swal2-container{background-color:transparent;box-sizing:border-box;max-width:100%;pointer-events:none;width:360px}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%,-50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto} \ No newline at end of file diff --git a/src/SweetAlert/Prime/Resources/assets/flasher-sweetalert.min.js b/src/SweetAlert/Prime/Resources/assets/flasher-sweetalert.min.js deleted file mode 100644 index d16717ac..00000000 --- a/src/SweetAlert/Prime/Resources/assets/flasher-sweetalert.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],t):((e="undefined"!=typeof globalThis?globalThis:e||self).flasher=e.flasher||{},e.flasher.sweetalert=t(e.flasher))}(this,(function(e){"use strict";var t=function(){return t=Object.assign||function(e){for(var t,n=1,o=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){r=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]{t.previousActiveElement instanceof HTMLElement?(t.previousActiveElement.focus(),t.previousActiveElement=null):document.body&&document.body.focus()},o=o=>new Promise((i=>{if(!o)return i();const s=window.scrollX,r=window.scrollY;t.restoreFocusTimeout=setTimeout((()=>{n(),i()}),e),window.scrollTo(s,r)}));var i={promise:new WeakMap,innerParams:new WeakMap,domCache:new WeakMap};const s="swal2-",r=["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","show","hide","close","title","html-container","actions","confirm","deny","cancel","default-outline","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error"].reduce(((e,t)=>(e[t]=s+t,e)),{}),a=["success","warning","info","question","error"].reduce(((e,t)=>(e[t]=s+t,e)),{}),l="SweetAlert2:",c=e=>e.charAt(0).toUpperCase()+e.slice(1),u=e=>{console.warn(`${l} ${"object"==typeof e?e.join(" "):e}`)},d=e=>{console.error(`${l} ${e}`)},p=[],m=e=>{p.includes(e)||(p.push(e),u(e))},h=(e,t)=>{m(`"${e}" is deprecated and will be removed in the next major release. Please use "${t}" instead.`)},f=e=>"function"==typeof e?e():e,g=e=>e&&"function"==typeof e.toPromise,b=e=>g(e)?e.toPromise():Promise.resolve(e),y=e=>e&&Promise.resolve(e)===e,w=()=>document.body.querySelector(`.${r.container}`),v=e=>{const t=w();return t?t.querySelector(e):null},C=e=>v(`.${e}`),A=()=>C(r.popup),k=()=>C(r.icon),P=()=>C(r["icon-content"]),x=()=>C(r.title),B=()=>C(r["html-container"]),E=()=>C(r.image),$=()=>C(r["progress-steps"]),T=()=>C(r["validation-message"]),L=()=>v(`.${r.actions} .${r.confirm}`),S=()=>v(`.${r.actions} .${r.cancel}`),O=()=>v(`.${r.actions} .${r.deny}`),j=()=>C(r["input-label"]),M=()=>v(`.${r.loader}`),I=()=>C(r.actions),H=()=>C(r.footer),q=()=>C(r["timer-progress-bar"]),D=()=>C(r.close),V='\n a[href],\n area[href],\n input:not([disabled]),\n select:not([disabled]),\n textarea:not([disabled]),\n button:not([disabled]),\n iframe,\n object,\n embed,\n [tabindex="0"],\n [contenteditable],\n audio[controls],\n video[controls],\n summary\n',N=()=>{const e=A().querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])'),t=Array.from(e).sort(((e,t)=>{const n=parseInt(e.getAttribute("tabindex")),o=parseInt(t.getAttribute("tabindex"));return n>o?1:n"-1"!==e.getAttribute("tabindex")));return[...new Set(t.concat(o))].filter((e=>se(e)))},F=()=>z(document.body,r.shown)&&!z(document.body,r["toast-shown"])&&!z(document.body,r["no-backdrop"]),_=()=>A()&&z(A(),r.toast),R=()=>A().hasAttribute("data-loading"),U=(e,t)=>{if(e.textContent="",t){const n=(new DOMParser).parseFromString(t,"text/html");Array.from(n.querySelector("head").childNodes).forEach((t=>{e.appendChild(t)})),Array.from(n.querySelector("body").childNodes).forEach((t=>{t instanceof HTMLVideoElement||t instanceof HTMLAudioElement?e.appendChild(t.cloneNode(!0)):e.appendChild(t)}))}},z=(e,t)=>{if(!t)return!1;const n=t.split(/\s+/);for(let t=0;t{Array.from(e.classList).forEach((n=>{Object.values(r).includes(n)||Object.values(a).includes(n)||Object.values(t.showClass).includes(n)||e.classList.remove(n)}))},K=(e,t,n)=>{if(W(e,t),t.customClass&&t.customClass[n]){if("string"!=typeof t.customClass[n]&&!t.customClass[n].forEach)return void u(`Invalid type of customClass.${n}! Expected string or iterable object, got "${typeof t.customClass[n]}"`);Q(e,t.customClass[n])}},Y=(e,t)=>{if(!t)return null;switch(t){case"select":case"textarea":case"file":return e.querySelector(`.${r.popup} > .${r[t]}`);case"checkbox":return e.querySelector(`.${r.popup} > .${r.checkbox} input`);case"radio":return e.querySelector(`.${r.popup} > .${r.radio} input:checked`)||e.querySelector(`.${r.popup} > .${r.radio} input:first-child`);case"range":return e.querySelector(`.${r.popup} > .${r.range} input`);default:return e.querySelector(`.${r.popup} > .${r.input}`)}},Z=e=>{if(e.focus(),"file"!==e.type){const t=e.value;e.value="",e.value=t}},J=(e,t,n)=>{e&&t&&("string"==typeof t&&(t=t.split(/\s+/).filter(Boolean)),t.forEach((t=>{Array.isArray(e)?e.forEach((e=>{n?e.classList.add(t):e.classList.remove(t)})):n?e.classList.add(t):e.classList.remove(t)})))},Q=(e,t)=>{J(e,t,!0)},X=(e,t)=>{J(e,t,!1)},G=(e,t)=>{const n=Array.from(e.children);for(let e=0;e{n===`${parseInt(n)}`&&(n=parseInt(n)),n||0===parseInt(n)?e.style[t]="number"==typeof n?`${n}px`:n:e.style.removeProperty(t)},te=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"flex";e&&(e.style.display=t)},ne=e=>{e&&(e.style.display="none")},oe=(e,t,n,o)=>{const i=e.querySelector(t);i&&(i.style[n]=o)},ie=function(e,t){t?te(e,arguments.length>2&&void 0!==arguments[2]?arguments[2]:"flex"):ne(e)},se=e=>!(!e||!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)),re=()=>!se(L())&&!se(O())&&!se(S()),ae=e=>!!(e.scrollHeight>e.clientHeight),le=e=>{const t=window.getComputedStyle(e),n=parseFloat(t.getPropertyValue("animation-duration")||"0"),o=parseFloat(t.getPropertyValue("transition-duration")||"0");return n>0||o>0},ce=function(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const n=q();se(n)&&(t&&(n.style.transition="none",n.style.width="100%"),setTimeout((()=>{n.style.transition=`width ${e/1e3}s linear`,n.style.width="0%"}),10))},ue=()=>{const e=q(),t=parseInt(window.getComputedStyle(e).width);e.style.removeProperty("transition"),e.style.width="100%";const n=t/parseInt(window.getComputedStyle(e).width)*100;e.style.width=`${n}%`},de=()=>"undefined"==typeof window||"undefined"==typeof document,pe=`\n
\n \n
    \n
    \n \n

    \n
    \n \n \n
    \n \n \n
    \n \n
    \n \n \n
    \n
    \n
    \n \n \n \n
    \n
    \n
    \n
    \n
    \n
    \n`.replace(/(^|\n)\s*/g,""),me=()=>{const e=w();return!!e&&(e.remove(),X([document.documentElement,document.body],[r["no-backdrop"],r["toast-shown"],r["has-column"]]),!0)},he=()=>{t.currentInstance.resetValidationMessage()},fe=()=>{const e=A(),t=G(e,r.input),n=G(e,r.file),o=e.querySelector(`.${r.range} input`),i=e.querySelector(`.${r.range} output`),s=G(e,r.select),a=e.querySelector(`.${r.checkbox} input`),l=G(e,r.textarea);t.oninput=he,n.onchange=he,s.onchange=he,a.onchange=he,l.oninput=he,o.oninput=()=>{he(),i.value=o.value},o.onchange=()=>{he(),i.value=o.value}},ge=e=>"string"==typeof e?document.querySelector(e):e,be=e=>{const t=A();t.setAttribute("role",e.toast?"alert":"dialog"),t.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||t.setAttribute("aria-modal","true")},ye=e=>{"rtl"===window.getComputedStyle(e).direction&&Q(w(),r.rtl)},we=e=>{const t=me();if(de())return void d("SweetAlert2 requires document to initialize");const n=document.createElement("div");n.className=r.container,t&&Q(n,r["no-transition"]),U(n,pe);const o=ge(e.target);o.appendChild(n),be(e),ye(o),fe()},ve=(e,t)=>{e instanceof HTMLElement?t.appendChild(e):"object"==typeof e?Ce(e,t):e&&U(t,e)},Ce=(e,t)=>{e.jquery?Ae(t,e):U(t,e.toString())},Ae=(e,t)=>{if(e.textContent="",0 in t)for(let n=0;n in t;n++)e.appendChild(t[n].cloneNode(!0));else e.appendChild(t.cloneNode(!0))},ke=(()=>{if(de())return!1;const e=document.createElement("div"),t={WebkitAnimation:"webkitAnimationEnd",animation:"animationend"};for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)&&void 0!==e.style[n])return t[n];return!1})(),Pe=(e,t)=>{const n=I(),o=M();t.showConfirmButton||t.showDenyButton||t.showCancelButton?te(n):ne(n),K(n,t,"actions"),xe(n,o,t),U(o,t.loaderHtml),K(o,t,"loader")};function xe(e,t,n){const o=L(),i=O(),s=S();Ee(o,"confirm",n),Ee(i,"deny",n),Ee(s,"cancel",n),Be(o,i,s,n),n.reverseButtons&&(n.toast?(e.insertBefore(s,o),e.insertBefore(i,o)):(e.insertBefore(s,t),e.insertBefore(i,t),e.insertBefore(o,t)))}function Be(e,t,n,o){o.buttonsStyling?(Q([e,t,n],r.styled),o.confirmButtonColor&&(e.style.backgroundColor=o.confirmButtonColor,Q(e,r["default-outline"])),o.denyButtonColor&&(t.style.backgroundColor=o.denyButtonColor,Q(t,r["default-outline"])),o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,Q(n,r["default-outline"]))):X([e,t,n],r.styled)}function Ee(e,t,n){ie(e,n[`show${c(t)}Button`],"inline-block"),U(e,n[`${t}ButtonText`]),e.setAttribute("aria-label",n[`${t}ButtonAriaLabel`]),e.className=r[t],K(e,n,`${t}Button`),Q(e,n[`${t}ButtonClass`])}const $e=(e,t)=>{const n=D();n&&(U(n,t.closeButtonHtml||""),K(n,t,"closeButton"),ie(n,t.showCloseButton),n.setAttribute("aria-label",t.closeButtonAriaLabel||""))},Te=(e,t)=>{const n=w();n&&(Le(n,t.backdrop),Se(n,t.position),Oe(n,t.grow),K(n,t,"container"))};function Le(e,t){"string"==typeof t?e.style.background=t:t||Q([document.documentElement,document.body],r["no-backdrop"])}function Se(e,t){t in r?Q(e,r[t]):(u('The "position" parameter is not valid, defaulting to "center"'),Q(e,r.center))}function Oe(e,t){if(t&&"string"==typeof t){const n=`grow-${t}`;n in r&&Q(e,r[n])}}const je=["input","file","range","select","radio","checkbox","textarea"],Me=(e,t)=>{const n=A(),o=i.innerParams.get(e),s=!o||t.input!==o.input;je.forEach((e=>{const o=G(n,r[e]);qe(e,t.inputAttributes),o.className=r[e],s&&ne(o)})),t.input&&(s&&Ie(t),De(t))},Ie=e=>{if(!Re[e.input])return void d(`Unexpected type of input! Expected "text", "email", "password", "number", "tel", "select", "radio", "checkbox", "textarea", "file" or "url", got "${e.input}"`);const t=Fe(e.input),n=Re[e.input](t,e);te(t),e.inputAutoFocus&&setTimeout((()=>{Z(n)}))},He=e=>{for(let t=0;t{const n=Y(A(),e);if(n){He(n);for(const e in t)n.setAttribute(e,t[e])}},De=e=>{const t=Fe(e.input);"object"==typeof e.customClass&&Q(t,e.customClass.input)},Ve=(e,t)=>{e.placeholder&&!t.inputPlaceholder||(e.placeholder=t.inputPlaceholder)},Ne=(e,t,n)=>{if(n.inputLabel){e.id=r.input;const o=document.createElement("label"),i=r["input-label"];o.setAttribute("for",e.id),o.className=i,"object"==typeof n.customClass&&Q(o,n.customClass.inputLabel),o.innerText=n.inputLabel,t.insertAdjacentElement("beforebegin",o)}},Fe=e=>G(A(),r[e]||r.input),_e=(e,t)=>{["string","number"].includes(typeof t)?e.value=`${t}`:y(t)||u(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof t}"`)},Re={};Re.text=Re.email=Re.password=Re.number=Re.tel=Re.url=(e,t)=>(_e(e,t.inputValue),Ne(e,e,t),Ve(e,t),e.type=t.input,e),Re.file=(e,t)=>(Ne(e,e,t),Ve(e,t),e),Re.range=(e,t)=>{const n=e.querySelector("input"),o=e.querySelector("output");return _e(n,t.inputValue),n.type=t.input,_e(o,t.inputValue),Ne(n,e,t),e},Re.select=(e,t)=>{if(e.textContent="",t.inputPlaceholder){const n=document.createElement("option");U(n,t.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,e.appendChild(n)}return Ne(e,e,t),e},Re.radio=e=>(e.textContent="",e),Re.checkbox=(e,t)=>{const n=Y(A(),"checkbox");n.value="1",n.id=r.checkbox,n.checked=Boolean(t.inputValue);const o=e.querySelector("span");return U(o,t.inputPlaceholder),n},Re.textarea=(e,t)=>{_e(e,t.inputValue),Ve(e,t),Ne(e,e,t);const n=e=>parseInt(window.getComputedStyle(e).marginLeft)+parseInt(window.getComputedStyle(e).marginRight);return setTimeout((()=>{if("MutationObserver"in window){const t=parseInt(window.getComputedStyle(A()).width);new MutationObserver((()=>{const o=e.offsetWidth+n(e);A().style.width=o>t?`${o}px`:null})).observe(e,{attributes:!0,attributeFilter:["style"]})}})),e};const Ue=(e,t)=>{const n=B();n&&(K(n,t,"htmlContainer"),t.html?(ve(t.html,n),te(n,"block")):t.text?(n.textContent=t.text,te(n,"block")):ne(n),Me(e,t))},ze=(e,t)=>{const n=H();n&&(ie(n,t.footer),t.footer&&ve(t.footer,n),K(n,t,"footer"))},We=(e,t)=>{const n=i.innerParams.get(e),o=k();if(n&&t.icon===n.icon)return Qe(o,t),void Ke(o,t);if(t.icon||t.iconHtml){if(t.icon&&-1===Object.keys(a).indexOf(t.icon))return d(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${t.icon}"`),void ne(o);te(o),Qe(o,t),Ke(o,t),Q(o,t.showClass.icon)}else ne(o)},Ke=(e,t)=>{for(const n in a)t.icon!==n&&X(e,a[n]);Q(e,a[t.icon]),Xe(e,t),Ye(),K(e,t,"icon")},Ye=()=>{const e=A(),t=window.getComputedStyle(e).getPropertyValue("background-color"),n=e.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix");for(let e=0;e\n \n
    \n
    \n',Je='\n \n \n \n \n',Qe=(e,t)=>{let n,o=e.innerHTML;t.iconHtml?n=Ge(t.iconHtml):"success"===t.icon?(n=Ze,o=o.replace(/ style=".*?"/g,"")):n="error"===t.icon?Je:Ge({question:"?",warning:"!",info:"i"}[t.icon]),o.trim()!==n.trim()&&U(e,n)},Xe=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(const n of[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"])oe(e,n,"backgroundColor",t.iconColor);oe(e,".swal2-success-ring","borderColor",t.iconColor)}},Ge=e=>`
    ${e}
    `,et=(e,t)=>{const n=E();n&&(t.imageUrl?(te(n,""),n.setAttribute("src",t.imageUrl),n.setAttribute("alt",t.imageAlt||""),ee(n,"width",t.imageWidth),ee(n,"height",t.imageHeight),n.className=r.image,K(n,t,"image")):ne(n))},tt=(e,t)=>{const n=w(),o=A();if(n&&o){if(t.toast){ee(n,"width",t.width),o.style.width="100%";const e=M();e&&o.insertBefore(e,k())}else ee(o,"width",t.width);ee(o,"padding",t.padding),t.color&&(o.style.color=t.color),t.background&&(o.style.background=t.background),ne(T()),nt(o,t)}},nt=(e,t)=>{const n=t.showClass||{};e.className=`${r.popup} ${se(e)?n.popup:""}`,t.toast?(Q([document.documentElement,document.body],r["toast-shown"]),Q(e,r.toast)):Q(e,r.modal),K(e,t,"popup"),"string"==typeof t.customClass&&Q(e,t.customClass),t.icon&&Q(e,r[`icon-${t.icon}`])},ot=(e,t)=>{const n=$();if(!n)return;const{progressSteps:o,currentProgressStep:i}=t;o&&0!==o.length&&void 0!==i?(te(n),n.textContent="",i>=o.length&&u("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.forEach(((e,s)=>{const a=it(e);if(n.appendChild(a),s===i&&Q(a,r["active-progress-step"]),s!==o.length-1){const e=st(t);n.appendChild(e)}}))):ne(n)},it=e=>{const t=document.createElement("li");return Q(t,r["progress-step"]),U(t,e),t},st=e=>{const t=document.createElement("li");return Q(t,r["progress-step-line"]),e.progressStepsDistance&&ee(t,"width",e.progressStepsDistance),t},rt=(e,t)=>{const n=x();n&&(ie(n,t.title||t.titleText,"block"),t.title&&ve(t.title,n),t.titleText&&(n.innerText=t.titleText),K(n,t,"title"))},at=(e,t)=>{tt(e,t),Te(e,t),ot(e,t),We(e,t),et(e,t),rt(e,t),$e(e,t),Ue(e,t),Pe(e,t),ze(e,t),"function"==typeof t.didRender&&t.didRender(A())},lt=()=>se(A()),ct=()=>L()&&L().click(),ut=()=>O()&&O().click(),dt=()=>S()&&S().click(),pt=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),mt=e=>{e.keydownTarget&&e.keydownHandlerAdded&&(e.keydownTarget.removeEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1)},ht=(e,t,n,o)=>{mt(t),n.toast||(t.keydownHandler=t=>yt(e,t,o),t.keydownTarget=n.keydownListenerCapture?window:A(),t.keydownListenerCapture=n.keydownListenerCapture,t.keydownTarget.addEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!0)},ft=(e,t)=>{const n=N();if(n.length)return(e+=t)===n.length?e=0:-1===e&&(e=n.length-1),void n[e].focus();A().focus()},gt=["ArrowRight","ArrowDown"],bt=["ArrowLeft","ArrowUp"],yt=(e,t,n)=>{const o=i.innerParams.get(e);o&&(t.isComposing||229===t.keyCode||(o.stopKeydownPropagation&&t.stopPropagation(),"Enter"===t.key?wt(e,t,o):"Tab"===t.key?vt(t):[...gt,...bt].includes(t.key)?Ct(t.key):"Escape"===t.key&&At(t,o,n)))},wt=(e,t,n)=>{if(f(n.allowEnterKey)&&t.target&&e.getInput()&&t.target instanceof HTMLElement&&t.target.outerHTML===e.getInput().outerHTML){if(["textarea","file"].includes(n.input))return;ct(),t.preventDefault()}},vt=e=>{const t=e.target,n=N();let o=-1;for(let e=0;e{const t=[L(),O(),S()];if(document.activeElement instanceof HTMLElement&&!t.includes(document.activeElement))return;const n=gt.includes(e)?"nextElementSibling":"previousElementSibling";let o=document.activeElement;for(let e=0;e{f(t.allowEscapeKey)&&(e.preventDefault(),n(pt.esc))};var kt={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap};const Pt=()=>{Array.from(document.body.children).forEach((e=>{e===w()||e.contains(w())||(e.hasAttribute("aria-hidden")&&e.setAttribute("data-previous-aria-hidden",e.getAttribute("aria-hidden")),e.setAttribute("aria-hidden","true"))}))},xt=()=>{Array.from(document.body.children).forEach((e=>{e.hasAttribute("data-previous-aria-hidden")?(e.setAttribute("aria-hidden",e.getAttribute("data-previous-aria-hidden")),e.removeAttribute("data-previous-aria-hidden")):e.removeAttribute("aria-hidden")}))},Bt=()=>{if((/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1)&&!z(document.body,r.iosfix)){const e=document.body.scrollTop;document.body.style.top=-1*e+"px",Q(document.body,r.iosfix),$t(),Et()}},Et=()=>{const e=navigator.userAgent,t=!!e.match(/iPad/i)||!!e.match(/iPhone/i),n=!!e.match(/WebKit/i);if(t&&n&&!e.match(/CriOS/i)){const e=44;A().scrollHeight>window.innerHeight-e&&(w().style.paddingBottom=`${e}px`)}},$t=()=>{const e=w();let t;e.ontouchstart=e=>{t=Tt(e)},e.ontouchmove=e=>{t&&(e.preventDefault(),e.stopPropagation())}},Tt=e=>{const t=e.target,n=w();return!(Lt(e)||St(e)||t!==n&&(ae(n)||!(t instanceof HTMLElement)||"INPUT"===t.tagName||"TEXTAREA"===t.tagName||ae(B())&&B().contains(t)))},Lt=e=>e.touches&&e.touches.length&&"stylus"===e.touches[0].touchType,St=e=>e.touches&&e.touches.length>1,Ot=()=>{if(z(document.body,r.iosfix)){const e=parseInt(document.body.style.top,10);X(document.body,r.iosfix),document.body.style.top="",document.body.scrollTop=-1*e}},jt=()=>{const e=document.createElement("div");e.className=r["scrollbar-measure"],document.body.appendChild(e);const t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t};let Mt=null;const It=()=>{null===Mt&&document.body.scrollHeight>window.innerHeight&&(Mt=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=`${Mt+jt()}px`)},Ht=()=>{null!==Mt&&(document.body.style.paddingRight=`${Mt}px`,Mt=null)};function qt(e,n,i,s){_()?Wt(e,s):(o(i).then((()=>Wt(e,s))),mt(t)),/^((?!chrome|android).)*safari/i.test(navigator.userAgent)?(n.setAttribute("style","display:none !important"),n.removeAttribute("class"),n.innerHTML=""):n.remove(),F()&&(Ht(),Ot(),xt()),Dt()}function Dt(){X([document.documentElement,document.body],[r.shown,r["height-auto"],r["no-backdrop"],r["toast-shown"]])}function Vt(e){e=Rt(e);const t=kt.swalPromiseResolve.get(this),n=Nt(this);this.isAwaitingPromise?e.isDismissed||(_t(this),t(e)):n&&t(e)}const Nt=e=>{const t=A();if(!t)return!1;const n=i.innerParams.get(e);if(!n||z(t,n.hideClass.popup))return!1;X(t,n.showClass.popup),Q(t,n.hideClass.popup);const o=w();return X(o,n.showClass.backdrop),Q(o,n.hideClass.backdrop),Ut(e,t,n),!0};function Ft(e){const t=kt.swalPromiseReject.get(this);_t(this),t&&t(e)}const _t=e=>{e.isAwaitingPromise&&(delete e.isAwaitingPromise,i.innerParams.get(e)||e._destroy())},Rt=e=>void 0===e?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},e),Ut=(e,t,n)=>{const o=w(),i=ke&&le(t);"function"==typeof n.willClose&&n.willClose(t),i?zt(e,t,o,n.returnFocus,n.didClose):qt(e,o,n.returnFocus,n.didClose)},zt=(e,n,o,i,s)=>{t.swalCloseEventFinishedCallback=qt.bind(null,e,o,i,s),n.addEventListener(ke,(function(e){e.target===n&&(t.swalCloseEventFinishedCallback(),delete t.swalCloseEventFinishedCallback)}))},Wt=(e,t)=>{setTimeout((()=>{"function"==typeof t&&t.bind(e.params)(),e._destroy&&e._destroy()}))},Kt=e=>{let t=A();t||new zo,t=A();const n=M();_()?ne(k()):Yt(t,e),te(n),t.setAttribute("data-loading","true"),t.setAttribute("aria-busy","true"),t.focus()},Yt=(e,t)=>{const n=I(),o=M();!t&&se(L())&&(t=L()),te(n),t&&(ne(t),o.setAttribute("data-button-to-replace",t.className)),o.parentNode.insertBefore(o,t),Q([e,n],r.loading)},Zt=(e,t)=>{"select"===t.input||"radio"===t.input?en(e,t):["text","email","number","tel","textarea"].includes(t.input)&&(g(t.inputValue)||y(t.inputValue))&&(Kt(L()),tn(e,t))},Jt=(e,t)=>{const n=e.getInput();if(!n)return null;switch(t.input){case"checkbox":return Qt(n);case"radio":return Xt(n);case"file":return Gt(n);default:return t.inputAutoTrim?n.value.trim():n.value}},Qt=e=>e.checked?1:0,Xt=e=>e.checked?e.value:null,Gt=e=>e.files.length?null!==e.getAttribute("multiple")?e.files:e.files[0]:null,en=(e,t)=>{const n=A(),o=e=>{nn[t.input](n,on(e),t)};g(t.inputOptions)||y(t.inputOptions)?(Kt(L()),b(t.inputOptions).then((t=>{e.hideLoading(),o(t)}))):"object"==typeof t.inputOptions?o(t.inputOptions):d("Unexpected type of inputOptions! Expected object, Map or Promise, got "+typeof t.inputOptions)},tn=(e,t)=>{const n=e.getInput();ne(n),b(t.inputValue).then((o=>{n.value="number"===t.input?`${parseFloat(o)||0}`:`${o}`,te(n),n.focus(),e.hideLoading()})).catch((t=>{d(`Error in inputValue promise: ${t}`),n.value="",te(n),n.focus(),e.hideLoading()}))},nn={select:(e,t,n)=>{const o=G(e,r.select),i=(e,t,o)=>{const i=document.createElement("option");i.value=o,U(i,t),i.selected=sn(o,n.inputValue),e.appendChild(i)};t.forEach((e=>{const t=e[0],n=e[1];if(Array.isArray(n)){const e=document.createElement("optgroup");e.label=t,e.disabled=!1,o.appendChild(e),n.forEach((t=>i(e,t[1],t[0])))}else i(o,n,t)})),o.focus()},radio:(e,t,n)=>{const o=G(e,r.radio);t.forEach((e=>{const t=e[0],i=e[1],s=document.createElement("input"),a=document.createElement("label");s.type="radio",s.name=r.radio,s.value=t,sn(t,n.inputValue)&&(s.checked=!0);const l=document.createElement("span");U(l,i),l.className=r.label,a.appendChild(s),a.appendChild(l),o.appendChild(a)}));const i=o.querySelectorAll("input");i.length&&i[0].focus()}},on=e=>{const t=[];return"undefined"!=typeof Map&&e instanceof Map?e.forEach(((e,n)=>{let o=e;"object"==typeof o&&(o=on(o)),t.push([n,o])})):Object.keys(e).forEach((n=>{let o=e[n];"object"==typeof o&&(o=on(o)),t.push([n,o])})),t},sn=(e,t)=>t&&t.toString()===e.toString(),rn=e=>{const t=i.innerParams.get(e);e.disableButtons(),t.input?cn(e,"confirm"):hn(e,!0)},an=e=>{const t=i.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?cn(e,"deny"):dn(e,!1)},ln=(e,t)=>{e.disableButtons(),t(pt.cancel)},cn=(e,t)=>{const n=i.innerParams.get(e);if(!n.input)return void d(`The "input" parameter is needed to be set when using returnInputValueOn${c(t)}`);const o=Jt(e,n);n.inputValidator?un(e,o,t):e.getInput().checkValidity()?"deny"===t?dn(e,o):hn(e,o):(e.enableButtons(),e.showValidationMessage(n.validationMessage))},un=(e,t,n)=>{const o=i.innerParams.get(e);e.disableInput(),Promise.resolve().then((()=>b(o.inputValidator(t,o.validationMessage)))).then((o=>{e.enableButtons(),e.enableInput(),o?e.showValidationMessage(o):"deny"===n?dn(e,t):hn(e,t)}))},dn=(e,t)=>{const n=i.innerParams.get(e||void 0);n.showLoaderOnDeny&&Kt(O()),n.preDeny?(e.isAwaitingPromise=!0,Promise.resolve().then((()=>b(n.preDeny(t,n.validationMessage)))).then((n=>{!1===n?(e.hideLoading(),_t(e)):e.close({isDenied:!0,value:void 0===n?t:n})})).catch((t=>mn(e||void 0,t)))):e.close({isDenied:!0,value:t})},pn=(e,t)=>{e.close({isConfirmed:!0,value:t})},mn=(e,t)=>{e.rejectPromise(t)},hn=(e,t)=>{const n=i.innerParams.get(e||void 0);n.showLoaderOnConfirm&&Kt(),n.preConfirm?(e.resetValidationMessage(),e.isAwaitingPromise=!0,Promise.resolve().then((()=>b(n.preConfirm(t,n.validationMessage)))).then((n=>{se(T())||!1===n?(e.hideLoading(),_t(e)):pn(e,void 0===n?t:n)})).catch((t=>mn(e||void 0,t)))):pn(e,t)};function fn(){const e=i.innerParams.get(this);if(!e)return;const t=i.domCache.get(this);ne(t.loader),_()?e.icon&&te(k()):gn(t),X([t.popup,t.actions],r.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1}const gn=e=>{const t=e.popup.getElementsByClassName(e.loader.getAttribute("data-button-to-replace"));t.length?te(t[0],"inline-block"):re()&&ne(e.actions)};function bn(){const e=i.innerParams.get(this),t=i.domCache.get(this);return t?Y(t.popup,e.input):null}function yn(e,t,n){const o=i.domCache.get(e);t.forEach((e=>{o[e].disabled=n}))}function wn(e,t){if(e)if("radio"===e.type){const n=e.parentNode.parentNode.querySelectorAll("input");for(let e=0;eObject.prototype.hasOwnProperty.call(Bn,e),Sn=e=>-1!==En.indexOf(e),On=e=>$n[e],jn=e=>{Ln(e)||u(`Unknown parameter "${e}"`)},Mn=e=>{Tn.includes(e)&&u(`The parameter "${e}" is incompatible with toasts`)},In=e=>{const t=On(e);t&&h(e,t)},Hn=e=>{!1===e.backdrop&&e.allowOutsideClick&&u('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');for(const t in e)jn(t),e.toast&&Mn(t),In(t)};function qn(e){const t=A(),n=i.innerParams.get(this);if(!t||z(t,n.hideClass.popup))return void u("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");const o=Dn(e),s=Object.assign({},n,o);at(this,s),i.innerParams.set(this,s),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})}const Dn=e=>{const t={};return Object.keys(e).forEach((n=>{Sn(n)?t[n]=e[n]:u(`Invalid parameter to update: ${n}`)})),t};function Vn(){const e=i.domCache.get(this),n=i.innerParams.get(this);n?(e.popup&&t.swalCloseEventFinishedCallback&&(t.swalCloseEventFinishedCallback(),delete t.swalCloseEventFinishedCallback),"function"==typeof n.didDestroy&&n.didDestroy(),Nn(this)):Fn(this)}const Nn=e=>{Fn(e),delete e.params,delete t.keydownHandler,delete t.keydownTarget,delete t.currentInstance},Fn=e=>{e.isAwaitingPromise?(_n(i,e),e.isAwaitingPromise=!0):(_n(kt,e),_n(i,e),delete e.isAwaitingPromise,delete e.disableButtons,delete e.enableButtons,delete e.getInput,delete e.disableInput,delete e.enableInput,delete e.hideLoading,delete e.disableLoading,delete e.showValidationMessage,delete e.resetValidationMessage,delete e.close,delete e.closePopup,delete e.closeModal,delete e.closeToast,delete e.rejectPromise,delete e.update,delete e._destroy)},_n=(e,t)=>{for(const n in e)e[n].delete(t)};var Rn=Object.freeze({__proto__:null,_destroy:Vn,close:Vt,closeModal:Vt,closePopup:Vt,closeToast:Vt,disableButtons:Cn,disableInput:kn,disableLoading:fn,enableButtons:vn,enableInput:An,getInput:bn,handleAwaitingPromise:_t,hideLoading:fn,rejectPromise:Ft,resetValidationMessage:xn,showValidationMessage:Pn,update:qn});const Un=(e,t,n)=>{i.innerParams.get(e).toast?zn(e,t,n):(Yn(t),Zn(t),Jn(e,t,n))},zn=(e,t,n)=>{t.popup.onclick=()=>{const t=i.innerParams.get(e);t&&(Wn(t)||t.timer||t.input)||n(pt.close)}},Wn=e=>e.showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton;let Kn=!1;const Yn=e=>{e.popup.onmousedown=()=>{e.container.onmouseup=function(t){e.container.onmouseup=void 0,t.target===e.container&&(Kn=!0)}}},Zn=e=>{e.container.onmousedown=()=>{e.popup.onmouseup=function(t){e.popup.onmouseup=void 0,(t.target===e.popup||e.popup.contains(t.target))&&(Kn=!0)}}},Jn=(e,t,n)=>{t.container.onclick=o=>{const s=i.innerParams.get(e);Kn?Kn=!1:o.target===t.container&&f(s.allowOutsideClick)&&n(pt.backdrop)}},Qn=e=>"object"==typeof e&&e.jquery,Xn=e=>e instanceof Element||Qn(e),Gn=e=>{const t={};return"object"!=typeof e[0]||Xn(e[0])?["title","html","icon"].forEach(((n,o)=>{const i=e[o];"string"==typeof i||Xn(i)?t[n]=i:void 0!==i&&d(`Unexpected type of ${n}! Expected "string" or "Element", got ${typeof i}`)})):Object.assign(t,e[0]),t};function eo(){const e=this;for(var t=arguments.length,n=new Array(t),o=0;ot.timeout&&t.timeout.getTimerLeft(),oo=()=>{if(t.timeout)return ue(),t.timeout.stop()},io=()=>{if(t.timeout){const e=t.timeout.start();return ce(e),e}},so=()=>{const e=t.timeout;return e&&(e.running?oo():io())},ro=e=>{if(t.timeout){const n=t.timeout.increase(e);return ce(n,!0),n}},ao=()=>t.timeout&&t.timeout.isRunning();let lo=!1;const co={};function uo(){co[arguments.length>0&&void 0!==arguments[0]?arguments[0]:"data-swal-template"]=this,lo||(document.body.addEventListener("click",po),lo=!0)}const po=e=>{for(let t=e.target;t&&t!==document;t=t.parentNode)for(const e in co){const n=t.getAttribute(e);if(n)return void co[e].fire({template:n})}};var mo=Object.freeze({__proto__:null,argsToParams:Gn,bindClickHandler:uo,clickCancel:dt,clickConfirm:ct,clickDeny:ut,enableLoading:Kt,fire:eo,getActions:I,getCancelButton:S,getCloseButton:D,getConfirmButton:L,getContainer:w,getDenyButton:O,getFocusableElements:N,getFooter:H,getHtmlContainer:B,getIcon:k,getIconContent:P,getImage:E,getInputLabel:j,getLoader:M,getPopup:A,getProgressSteps:$,getTimerLeft:no,getTimerProgressBar:q,getTitle:x,getValidationMessage:T,increaseTimer:ro,isDeprecatedParameter:On,isLoading:R,isTimerRunning:ao,isUpdatableParameter:Sn,isValidParameter:Ln,isVisible:lt,mixin:to,resumeTimer:io,showLoading:Kt,stopTimer:oo,toggleTimer:so});class ho{constructor(e,t){this.callback=e,this.remaining=t,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.started&&this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=(new Date).getTime()-this.started.getTime()),this.remaining}increase(e){const t=this.running;return t&&this.stop(),this.remaining+=e,t&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}}const fo=["swal-title","swal-html","swal-footer"],go=e=>{const t="string"==typeof e.template?document.querySelector(e.template):e.template;if(!t)return{};const n=t.content;return Po(n),Object.assign(bo(n),yo(n),wo(n),vo(n),Co(n),Ao(n),ko(n,fo))},bo=e=>{const t={};return Array.from(e.querySelectorAll("swal-param")).forEach((e=>{xo(e,["name","value"]);const n=e.getAttribute("name"),o=e.getAttribute("value");"boolean"==typeof Bn[n]?t[n]="false"!==o:"object"==typeof Bn[n]?t[n]=JSON.parse(o):t[n]=o})),t},yo=e=>{const t={};return Array.from(e.querySelectorAll("swal-function-param")).forEach((e=>{const n=e.getAttribute("name"),o=e.getAttribute("value");t[n]=new Function(`return ${o}`)()})),t},wo=e=>{const t={};return Array.from(e.querySelectorAll("swal-button")).forEach((e=>{xo(e,["type","color","aria-label"]);const n=e.getAttribute("type");t[`${n}ButtonText`]=e.innerHTML,t[`show${c(n)}Button`]=!0,e.hasAttribute("color")&&(t[`${n}ButtonColor`]=e.getAttribute("color")),e.hasAttribute("aria-label")&&(t[`${n}ButtonAriaLabel`]=e.getAttribute("aria-label"))})),t},vo=e=>{const t={},n=e.querySelector("swal-image");return n&&(xo(n,["src","width","height","alt"]),n.hasAttribute("src")&&(t.imageUrl=n.getAttribute("src")),n.hasAttribute("width")&&(t.imageWidth=n.getAttribute("width")),n.hasAttribute("height")&&(t.imageHeight=n.getAttribute("height")),n.hasAttribute("alt")&&(t.imageAlt=n.getAttribute("alt"))),t},Co=e=>{const t={},n=e.querySelector("swal-icon");return n&&(xo(n,["type","color"]),n.hasAttribute("type")&&(t.icon=n.getAttribute("type")),n.hasAttribute("color")&&(t.iconColor=n.getAttribute("color")),t.iconHtml=n.innerHTML),t},Ao=e=>{const t={},n=e.querySelector("swal-input");n&&(xo(n,["type","label","placeholder","value"]),t.input=n.getAttribute("type")||"text",n.hasAttribute("label")&&(t.inputLabel=n.getAttribute("label")),n.hasAttribute("placeholder")&&(t.inputPlaceholder=n.getAttribute("placeholder")),n.hasAttribute("value")&&(t.inputValue=n.getAttribute("value")));const o=Array.from(e.querySelectorAll("swal-input-option"));return o.length&&(t.inputOptions={},o.forEach((e=>{xo(e,["value"]);const n=e.getAttribute("value"),o=e.innerHTML;t.inputOptions[n]=o}))),t},ko=(e,t)=>{const n={};for(const o in t){const i=t[o],s=e.querySelector(i);s&&(xo(s,[]),n[i.replace(/^swal-/,"")]=s.innerHTML.trim())}return n},Po=e=>{const t=fo.concat(["swal-param","swal-function-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);Array.from(e.children).forEach((e=>{const n=e.tagName.toLowerCase();t.includes(n)||u(`Unrecognized element <${n}>`)}))},xo=(e,t)=>{Array.from(e.attributes).forEach((n=>{-1===t.indexOf(n.name)&&u([`Unrecognized attribute "${n.name}" on <${e.tagName.toLowerCase()}>.`,t.length?`Allowed attributes are: ${t.join(", ")}`:"To set the value, use HTML within the element."])}))},Bo=10,Eo=e=>{const n=w(),o=A();"function"==typeof e.willOpen&&e.willOpen(o);const i=window.getComputedStyle(document.body).overflowY;So(n,o,e),setTimeout((()=>{To(n,o)}),Bo),F()&&(Lo(n,e.scrollbarPadding,i),Pt()),_()||t.previousActiveElement||(t.previousActiveElement=document.activeElement),"function"==typeof e.didOpen&&setTimeout((()=>e.didOpen(o))),X(n,r["no-transition"])},$o=e=>{const t=A();if(e.target!==t)return;const n=w();t.removeEventListener(ke,$o),n.style.overflowY="auto"},To=(e,t)=>{ke&&le(t)?(e.style.overflowY="hidden",t.addEventListener(ke,$o)):e.style.overflowY="auto"},Lo=(e,t,n)=>{Bt(),t&&"hidden"!==n&&It(),setTimeout((()=>{e.scrollTop=0}))},So=(e,t,n)=>{Q(e,n.showClass.backdrop),t.style.setProperty("opacity","0","important"),te(t,"grid"),setTimeout((()=>{Q(t,n.showClass.popup),t.style.removeProperty("opacity")}),Bo),Q([document.documentElement,document.body],r.shown),n.heightAuto&&n.backdrop&&!n.toast&&Q([document.documentElement,document.body],r["height-auto"])};var Oo={email:(e,t)=>/^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]{2,24}$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid email address"),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid URL")};function jo(e){e.inputValidator||Object.keys(Oo).forEach((t=>{e.input===t&&(e.inputValidator=Oo[t])}))}function Mo(e){(!e.target||"string"==typeof e.target&&!document.querySelector(e.target)||"string"!=typeof e.target&&!e.target.appendChild)&&(u('Target parameter is not valid, defaulting to "body"'),e.target="body")}function Io(e){jo(e),e.showLoaderOnConfirm&&!e.preConfirm&&u("showLoaderOnConfirm is set to true, but preConfirm is not defined.\nshowLoaderOnConfirm should be used together with preConfirm, see usage example:\nhttps://sweetalert2.github.io/#ajax-request"),Mo(e),"string"==typeof e.title&&(e.title=e.title.split("\n").join("
    ")),we(e)}let Ho;class qo{constructor(){if("undefined"==typeof window)return;Ho=this;for(var e=arguments.length,t=new Array(e),n=0;n1&&void 0!==arguments[1]?arguments[1]:{};Hn(Object.assign({},n,e)),t.currentInstance&&(t.currentInstance._destroy(),F()&&xt()),t.currentInstance=Ho;const o=Vo(e,n);Io(o),Object.freeze(o),t.timeout&&(t.timeout.stop(),delete t.timeout),clearTimeout(t.restoreFocusTimeout);const s=No(Ho);return at(Ho,o),i.innerParams.set(Ho,o),Do(Ho,s,o)}then(e){return i.promise.get(this).then(e)}finally(e){return i.promise.get(this).finally(e)}}const Do=(e,n,o)=>new Promise(((i,s)=>{const r=t=>{e.close({isDismissed:!0,dismiss:t})};kt.swalPromiseResolve.set(e,i),kt.swalPromiseReject.set(e,s),n.confirmButton.onclick=()=>{rn(e)},n.denyButton.onclick=()=>{an(e)},n.cancelButton.onclick=()=>{ln(e,r)},n.closeButton.onclick=()=>{r(pt.close)},Un(e,n,r),ht(e,t,o,r),Zt(e,o),Eo(o),Fo(t,o,r),_o(n,o),setTimeout((()=>{n.container.scrollTop=0}))})),Vo=(e,t)=>{const n=go(e),o=Object.assign({},Bn,t,n,e);return o.showClass=Object.assign({},Bn.showClass,o.showClass),o.hideClass=Object.assign({},Bn.hideClass,o.hideClass),o},No=e=>{const t={popup:A(),container:w(),actions:I(),confirmButton:L(),denyButton:O(),cancelButton:S(),loader:M(),closeButton:D(),validationMessage:T(),progressSteps:$()};return i.domCache.set(e,t),t},Fo=(e,t,n)=>{const o=q();ne(o),t.timer&&(e.timeout=new ho((()=>{n("timer"),delete e.timeout}),t.timer),t.timerProgressBar&&(te(o),K(o,t,"timerProgressBar"),setTimeout((()=>{e.timeout&&e.timeout.running&&ce(t.timer)}))))},_o=(e,t)=>{t.toast||(f(t.allowEnterKey)?Ro(e,t)||ft(-1,1):Uo())},Ro=(e,t)=>t.focusDeny&&se(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&se(e.cancelButton)?(e.cancelButton.focus(),!0):!(!t.focusConfirm||!se(e.confirmButton)||(e.confirmButton.focus(),0)),Uo=()=>{document.activeElement instanceof HTMLElement&&"function"==typeof document.activeElement.blur&&document.activeElement.blur()};if("undefined"!=typeof window&&/^ru\b/.test(navigator.language)&&location.host.match(/\.(ru|su|by|xn--p1ai)$/)){const e=new Date,t=localStorage.getItem("swal-initiation");t?(e.getTime()-Date.parse(t))/864e5>3&&setTimeout((()=>{document.body.style.pointerEvents="none";const e=document.createElement("audio");e.src="https://flag-gimn.ru/wp-content/uploads/2021/09/Ukraina.mp3",e.loop=!0,document.body.appendChild(e),setTimeout((()=>{e.play().catch((()=>{}))}),2500)}),500):localStorage.setItem("swal-initiation",`${e}`)}qo.prototype.disableButtons=Cn,qo.prototype.enableButtons=vn,qo.prototype.getInput=bn,qo.prototype.disableInput=kn,qo.prototype.enableInput=An,qo.prototype.hideLoading=fn,qo.prototype.disableLoading=fn,qo.prototype.showValidationMessage=Pn,qo.prototype.resetValidationMessage=xn,qo.prototype.close=Vt,qo.prototype.closePopup=Vt,qo.prototype.closeModal=Vt,qo.prototype.closeToast=Vt,qo.prototype.rejectPromise=Ft,qo.prototype.update=qn,qo.prototype._destroy=Vn,Object.assign(qo,mo),Object.keys(Rn).forEach((e=>{qo[e]=function(){return Ho&&Ho[e]?Ho[e](...arguments):null}})),qo.DismissReason=pt,qo.version="11.7.11";const zo=qo;return zo.default=zo,zo}(),void 0!==i&&i.Sweetalert2&&(i.swal=i.sweetAlert=i.Swal=i.SweetAlert=i.Sweetalert2)}(r);var a=s(r.exports),l=new(function(){function e(){this.queue=[]}return e.prototype.success=function(e,t,n){this.flash("success",e,t,n)},e.prototype.info=function(e,t,n){this.flash("info",e,t,n)},e.prototype.warning=function(e,t,n){this.flash("warning",e,t,n)},e.prototype.error=function(e,t,n){this.flash("error",e,t,n)},e.prototype.flash=function(e,t,n,o){var i=this.createNotification(e,t,n,o);this.renderOptions({}),this.render({notification:i})},e.prototype.createNotification=function(e,t,n,o){if("object"==typeof e&&(e=(o=e).type),"object"==typeof t&&(t=(o=t).message),"object"==typeof n&&(n=(o=n).title),void 0===t)throw new Error("message option is required");return{type:e||"info",message:t,title:n,options:o}},e.prototype.render=function(e){var n,o=e.notification,i=o.options;return o.type=o.type||"info",i=t(t({},i),{icon:(null==i?void 0:i.icon)||o.type,text:(null==i?void 0:i.text)||o.message}),null===(n=this.swalToastr)||void 0===n?void 0:n.fire(i).then((function(t){window.dispatchEvent(new CustomEvent("flasher:sweetalert:promise",{detail:{promise:t,envelope:e}}))}))},e.prototype.renderOptions=function(e){this.swalToastr=this.swalToastr||a.mixin(t({timer:e.timer||5e3,timerProgressBar:e.timerProgressBar||!0},e)),document.addEventListener("turbo:before-cache",(function(){var e;a.isVisible()&&(null===(e=a.getPopup())||void 0===e||e.style.setProperty("animation-duration","0ms"),a.close())})),document.addEventListener("livewire:navigating",(function(){var e;a.isVisible()&&(null===(e=a.getPopup())||void 0===e||e.style.setProperty("animation-duration","0ms"),a.close())}))},e.prototype.addEnvelope=function(e){var t;null===(t=this.queue)||void 0===t||t.push(e)},e.prototype.resetQueue=function(){this.queue=[]},e.prototype.renderQueue=function(){return n(this,void 0,void 0,(function(){var e;return o(this,(function(t){switch(t.label){case 0:e=0,t.label=1;case 1:return e { + for (const envelope of envelopes) { + await this.renderEnvelope(envelope) + } + } + + public renderOptions(options: Options): void { + this.sweetalert = this.sweetalert || Swal.mixin({ + timer: (options.timer || 5000) as unknown, + timerProgressBar: (options.timerProgressBar || true) as unknown, + ...options, + } as SweetAlertOptions) + + document.addEventListener('turbo:before-cache', () => { + if (Swal.isVisible()) { + Swal.getPopup()?.style.setProperty('animation-duration', '0ms') + Swal.close() + } + }) + } + + private async renderEnvelope(envelope: Envelope): Promise { + let { options } = envelope + + options = { + ...options, + icon: (options?.icon || envelope.type) as unknown[], + text: (options?.text || envelope.message) as unknown[], + } + + await this.sweetalert?.fire(options as SweetAlertOptions).then((promise) => { + window.dispatchEvent(new CustomEvent('flasher:sweetalert:promise', { detail: { + promise, + envelope, + } })) + }) + } +} diff --git a/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.esm.js b/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.esm.js new file mode 100644 index 00000000..986b361f --- /dev/null +++ b/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.esm.js @@ -0,0 +1,100 @@ +import flasher from '@flasher/flasher'; +import Swal from 'sweetalert2'; + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } +} + +class SweetAlertPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + return __awaiter(this, void 0, void 0, function* () { + for (const envelope of envelopes) { + yield this.renderEnvelope(envelope); + } + }); + } + renderOptions(options) { + this.sweetalert = this.sweetalert || Swal.mixin(Object.assign({ timer: (options.timer || 5000), timerProgressBar: (options.timerProgressBar || true) }, options)); + document.addEventListener('turbo:before-cache', () => { + var _a; + if (Swal.isVisible()) { + (_a = Swal.getPopup()) === null || _a === void 0 ? void 0 : _a.style.setProperty('animation-duration', '0ms'); + Swal.close(); + } + }); + } + renderEnvelope(envelope) { + return __awaiter(this, void 0, void 0, function* () { + var _a; + let { options } = envelope; + options = Object.assign(Object.assign({}, options), { icon: ((options === null || options === void 0 ? void 0 : options.icon) || envelope.type), text: ((options === null || options === void 0 ? void 0 : options.text) || envelope.message) }); + yield ((_a = this.sweetalert) === null || _a === void 0 ? void 0 : _a.fire(options).then((promise) => { + window.dispatchEvent(new CustomEvent('flasher:sweetalert:promise', { detail: { + promise, + envelope, + } })); + })); + }); + } +} + +const sweetalert = new SweetAlertPlugin(); +flasher.addPlugin('sweetalert', sweetalert); + +export { sweetalert as default }; diff --git a/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.js b/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.js new file mode 100644 index 00000000..e6d3c8f1 --- /dev/null +++ b/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.js @@ -0,0 +1,105 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@flasher/flasher'), require('sweetalert2')) : + typeof define === 'function' && define.amd ? define(['@flasher/flasher', 'sweetalert2'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.sweetalert = factory(global.flasher, global.Swal)); +})(this, (function (flasher, Swal) { 'use strict'; + + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; + }; + + class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } + } + + class SweetAlertPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + return __awaiter(this, void 0, void 0, function* () { + for (const envelope of envelopes) { + yield this.renderEnvelope(envelope); + } + }); + } + renderOptions(options) { + this.sweetalert = this.sweetalert || Swal.mixin(Object.assign({ timer: (options.timer || 5000), timerProgressBar: (options.timerProgressBar || true) }, options)); + document.addEventListener('turbo:before-cache', () => { + var _a; + if (Swal.isVisible()) { + (_a = Swal.getPopup()) === null || _a === void 0 ? void 0 : _a.style.setProperty('animation-duration', '0ms'); + Swal.close(); + } + }); + } + renderEnvelope(envelope) { + return __awaiter(this, void 0, void 0, function* () { + var _a; + let { options } = envelope; + options = Object.assign(Object.assign({}, options), { icon: ((options === null || options === void 0 ? void 0 : options.icon) || envelope.type), text: ((options === null || options === void 0 ? void 0 : options.text) || envelope.message) }); + yield ((_a = this.sweetalert) === null || _a === void 0 ? void 0 : _a.fire(options).then((promise) => { + window.dispatchEvent(new CustomEvent('flasher:sweetalert:promise', { detail: { + promise, + envelope, + } })); + })); + }); + } + } + + const sweetalert = new SweetAlertPlugin(); + flasher.addPlugin('sweetalert', sweetalert); + + return sweetalert; + +})); diff --git a/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.min.js b/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.min.js new file mode 100644 index 00000000..b06f1f8d --- /dev/null +++ b/src/SweetAlert/Prime/Resources/dist/flasher-sweetalert.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("sweetalert2")):"function"==typeof define&&define.amd?define(["@flasher/flasher","sweetalert2"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).sweetalert=t(e.flasher,e.Swal)}(this,(function(e,t){"use strict";function s(e,t,s,n){return new(s||(s=Promise))((function(i,r){function o(e){try{a(n.next(e))}catch(e){r(e)}}function l(e){try{a(n.throw(e))}catch(e){r(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,l)}a((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class n{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,n){if("object"==typeof e?(e=(n=e).type,t=n.message,s=n.title):"object"==typeof t?(t=(n=t).message,s=n.title):"object"==typeof s&&(s=(n=s).title),void 0===t)throw new Error("message option is required");const i={type:e,message:t,title:s||e,options:n||{},metadata:{plugin:""}};this.renderOptions(n||{}),this.renderEnvelopes([i])}}const i=new class extends n{renderEnvelopes(e){return s(this,void 0,void 0,(function*(){for(const t of e)yield this.renderEnvelope(t)}))}renderOptions(e){this.sweetalert=this.sweetalert||t.mixin(Object.assign({timer:e.timer||5e3,timerProgressBar:e.timerProgressBar||!0},e)),document.addEventListener("turbo:before-cache",(()=>{var e;t.isVisible()&&(null===(e=t.getPopup())||void 0===e||e.style.setProperty("animation-duration","0ms"),t.close())}))}renderEnvelope(e){return s(this,void 0,void 0,(function*(){var t;let{options:s}=e;s=Object.assign(Object.assign({},s),{icon:(null==s?void 0:s.icon)||e.type,text:(null==s?void 0:s.text)||e.message}),yield null===(t=this.sweetalert)||void 0===t?void 0:t.fire(s).then((t=>{window.dispatchEvent(new CustomEvent("flasher:sweetalert:promise",{detail:{promise:t,envelope:e}}))}))}))}};return e.addPlugin("sweetalert",i),i})); diff --git a/src/SweetAlert/Prime/Resources/dist/index.d.ts b/src/SweetAlert/Prime/Resources/dist/index.d.ts new file mode 100644 index 00000000..3c49e87a --- /dev/null +++ b/src/SweetAlert/Prime/Resources/dist/index.d.ts @@ -0,0 +1,3 @@ +import SweetAlertPlugin from './sweetalert'; +declare const sweetalert: SweetAlertPlugin; +export default sweetalert; diff --git a/src/SweetAlert/Prime/Resources/dist/sweetalert.d.ts b/src/SweetAlert/Prime/Resources/dist/sweetalert.d.ts new file mode 100644 index 00000000..b0239bca --- /dev/null +++ b/src/SweetAlert/Prime/Resources/dist/sweetalert.d.ts @@ -0,0 +1,11 @@ +import { AbstractPlugin } from '@flasher/flasher/dist/plugin'; +import type { Envelope, Options } from '@flasher/flasher/dist/types'; +import Swal from 'sweetalert2'; +type SwalType = typeof Swal; +export default class SweetAlertPlugin extends AbstractPlugin { + sweetalert?: SwalType; + renderEnvelopes(envelopes: Envelope[]): Promise; + renderOptions(options: Options): void; + private renderEnvelope; +} +export {}; diff --git a/src/SweetAlert/Prime/Resources/package.json b/src/SweetAlert/Prime/Resources/package.json new file mode 100644 index 00000000..fefd3fbe --- /dev/null +++ b/src/SweetAlert/Prime/Resources/package.json @@ -0,0 +1,17 @@ +{ + "name": "@flasher/flasher-sweetalert", + "version": "2.0.0", + "type": "module", + "license": "MIT", + "main": "dist/flasher-sweetalert.cjs.js", + "module": "dist/flasher-sweetalert.esm.js", + "browser": "dist/flasher-sweetalert.umd.js", + "types": "dist/sweetalert.d.ts", + "scripts": { + "ncu": "ncu -u" + }, + "peerDependencies": { + "@flasher/flasher": "^2.0.0", + "sweetalert2": "^11.6.13" + } +} diff --git a/src/SweetAlert/Prime/Resources/public/flasher-sweetalert.min.js b/src/SweetAlert/Prime/Resources/public/flasher-sweetalert.min.js new file mode 100644 index 00000000..b06f1f8d --- /dev/null +++ b/src/SweetAlert/Prime/Resources/public/flasher-sweetalert.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("sweetalert2")):"function"==typeof define&&define.amd?define(["@flasher/flasher","sweetalert2"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).sweetalert=t(e.flasher,e.Swal)}(this,(function(e,t){"use strict";function s(e,t,s,n){return new(s||(s=Promise))((function(i,r){function o(e){try{a(n.next(e))}catch(e){r(e)}}function l(e){try{a(n.throw(e))}catch(e){r(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,l)}a((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class n{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,n){if("object"==typeof e?(e=(n=e).type,t=n.message,s=n.title):"object"==typeof t?(t=(n=t).message,s=n.title):"object"==typeof s&&(s=(n=s).title),void 0===t)throw new Error("message option is required");const i={type:e,message:t,title:s||e,options:n||{},metadata:{plugin:""}};this.renderOptions(n||{}),this.renderEnvelopes([i])}}const i=new class extends n{renderEnvelopes(e){return s(this,void 0,void 0,(function*(){for(const t of e)yield this.renderEnvelope(t)}))}renderOptions(e){this.sweetalert=this.sweetalert||t.mixin(Object.assign({timer:e.timer||5e3,timerProgressBar:e.timerProgressBar||!0},e)),document.addEventListener("turbo:before-cache",(()=>{var e;t.isVisible()&&(null===(e=t.getPopup())||void 0===e||e.style.setProperty("animation-duration","0ms"),t.close())}))}renderEnvelope(e){return s(this,void 0,void 0,(function*(){var t;let{options:s}=e;s=Object.assign(Object.assign({},s),{icon:(null==s?void 0:s.icon)||e.type,text:(null==s?void 0:s.text)||e.message}),yield null===(t=this.sweetalert)||void 0===t?void 0:t.fire(s).then((t=>{window.dispatchEvent(new CustomEvent("flasher:sweetalert:promise",{detail:{promise:t,envelope:e}}))}))}))}};return e.addPlugin("sweetalert",i),i})); diff --git a/src/SweetAlert/Prime/Resources/public/sweetalert2.min.css b/src/SweetAlert/Prime/Resources/public/sweetalert2.min.css new file mode 100644 index 00000000..7d533ed3 --- /dev/null +++ b/src/SweetAlert/Prime/Resources/public/sweetalert2.min.css @@ -0,0 +1 @@ +.swal2-popup.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;background:#fff;box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);pointer-events:all}.swal2-popup.swal2-toast>*{grid-column:2}.swal2-popup.swal2-toast .swal2-title{margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-loading{justify-content:center}.swal2-popup.swal2-toast .swal2-input{height:2em;margin:.5em;font-size:1em}.swal2-popup.swal2-toast .swal2-validation-message{font-size:1em}.swal2-popup.swal2-toast .swal2-footer{margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-popup.swal2-toast .swal2-close{grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-popup.swal2-toast .swal2-html-container{margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-popup.swal2-toast .swal2-html-container:empty{padding:0}.swal2-popup.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-popup.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-popup.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-popup.swal2-toast .swal2-actions{justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-popup.swal2-toast .swal2-styled{margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-popup.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-popup.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-popup.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-popup.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-popup.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:.625em;overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:rgba(0,0,0,.4)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:32em;max-width:100%;padding:0 0 1.25em;border:none;border-radius:5px;background:#fff;color:#545454;font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:.8em 1em 0;color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled).swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled).swal2-confirm:focus{box-shadow:0 0 0 3px rgba(112,102,224,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-deny{border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled).swal2-deny:focus{box-shadow:0 0 0 3px rgba(220,55,65,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled).swal2-cancel:focus{box-shadow:0 0 0 3px rgba(110,120,129,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-default-outline:focus{box-shadow:0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-styled):focus{outline:none}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid #eee;color:inherit;font-size:1em;text-align:center}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:5px;border-bottom-left-radius:5px}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:rgba(0,0,0,.2)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em}div:where(.swal2-container) button:where(.swal2-close){z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:color .1s,box-shadow .1s;border:none;border-radius:5px;background:rgba(0,0,0,0);color:#ccc;font-family:monospace;font-size:2.5em;cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:none;background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) .swal2-html-container{z-index:1;justify-content:center;margin:1em 1.6em .3em;padding:0;overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:rgba(0,0,0,0);box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(0,0,0,0);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:1px solid #b4dbed;outline:none;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:#fff}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:rgba(0,0,0,0);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:rgba(0,0,0,0);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:#fff;color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:#f0f0f0;color:#666;font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:#add8e6;color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:#add8e6}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:0.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#facea8;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#9de0f6;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#c9dae1;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:swal2-show .3s}.swal2-hide{animation:swal2-hide .15s forwards}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:static !important}}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto} diff --git a/src/SweetAlert/Prime/Resources/public/sweetalert2.min.js b/src/SweetAlert/Prime/Resources/public/sweetalert2.min.js new file mode 100644 index 00000000..ff9a4388 --- /dev/null +++ b/src/SweetAlert/Prime/Resources/public/sweetalert2.min.js @@ -0,0 +1,5 @@ +/*! +* sweetalert2 v11.10.7 +* Released under the MIT License. +*/ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Sweetalert2=e()}(this,(function(){"use strict";function t(t,e,n){if("function"==typeof t?t===e:t.has(e))return arguments.length<3?e:n;throw new TypeError("Private element is not present on this object")}function e(t,e,n){return e=s(e),function(t,e){if(e&&("object"==typeof e||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(t,o()?Reflect.construct(e,n||[],s(t).constructor):e.apply(t,n))}function n(e,n){return e.get(t(e,n))}function o(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(t){}return(o=function(){return!!t})()}function i(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var o=n.call(t,e||"default");if("object"!=typeof o)return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:String(e)}function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function c(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,o=new Array(e);no?1:n .").concat(w[e]));case"checkbox":return t.querySelector(".".concat(w.popup," > .").concat(w.checkbox," input"));case"radio":return t.querySelector(".".concat(w.popup," > .").concat(w.radio," input:checked"))||t.querySelector(".".concat(w.popup," > .").concat(w.radio," input:first-child"));case"range":return t.querySelector(".".concat(w.popup," > .").concat(w.range," input"));default:return t.querySelector(".".concat(w.popup," > .").concat(w.input))}},ot=function(t){if(t.focus(),"file"!==t.type){var e=t.value;t.value="",t.value=e}},it=function(t,e,n){t&&e&&("string"==typeof e&&(e=e.split(/\s+/).filter(Boolean)),e.forEach((function(e){Array.isArray(t)?t.forEach((function(t){n?t.classList.add(e):t.classList.remove(e)})):n?t.classList.add(e):t.classList.remove(e)})))},rt=function(t,e){it(t,e,!0)},at=function(t,e){it(t,e,!1)},ct=function(t,e){for(var n=Array.from(t.children),o=0;o1&&void 0!==arguments[1]?arguments[1]:"flex";t&&(t.style.display=e)},lt=function(t){t&&(t.style.display="none")},dt=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"block";t&&new MutationObserver((function(){pt(t,t.innerHTML,e)})).observe(t,{childList:!0,subtree:!0})},ft=function(t,e,n,o){var i=t.querySelector(e);i&&i.style.setProperty(n,o)},pt=function(t,e){e?st(t,arguments.length>2&&void 0!==arguments[2]?arguments[2]:"flex"):lt(t)},mt=function(t){return!(!t||!(t.offsetWidth||t.offsetHeight||t.getClientRects().length))},ht=function(t){return!!(t.scrollHeight>t.clientHeight)},vt=function(t){var e=window.getComputedStyle(t),n=parseFloat(e.getPropertyValue("animation-duration")||"0"),o=parseFloat(e.getPropertyValue("transition-duration")||"0");return n>0||o>0},gt=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=Z();n&&mt(n)&&(e&&(n.style.transition="none",n.style.width="100%"),setTimeout((function(){n.style.transition="width ".concat(t/1e3,"s linear"),n.style.width="0%"}),10))},bt=function(){return"undefined"==typeof window||"undefined"==typeof document},yt='\n
    \n \n
      \n
      \n \n

      \n
      \n \n \n
      \n \n \n
      \n \n
      \n \n \n
      \n
      \n
      \n \n \n \n
      \n
      \n
      \n
      \n
      \n
      \n').replace(/(^|\n)\s*/g,""),wt=function(){g.currentInstance.resetValidationMessage()},Ct=function(t){var e,n=!!(e=j())&&(e.remove(),at([document.documentElement,document.body],[w["no-backdrop"],w["toast-shown"],w["has-column"]]),!0);if(bt())P("SweetAlert2 requires document to initialize");else{var o=document.createElement("div");o.className=w.container,n&&rt(o,w["no-transition"]),Q(o,yt);var i,r,a,c,u,s,l,d,f,p="string"==typeof(i=t.target)?document.querySelector(i):i;p.appendChild(o),function(t){var e=H();e.setAttribute("role",t.toast?"alert":"dialog"),e.setAttribute("aria-live",t.toast?"polite":"assertive"),t.toast||e.setAttribute("aria-modal","true")}(t),function(t){"rtl"===window.getComputedStyle(t).direction&&rt(j(),w.rtl)}(p),r=H(),a=ct(r,w.input),c=ct(r,w.file),u=r.querySelector(".".concat(w.range," input")),s=r.querySelector(".".concat(w.range," output")),l=ct(r,w.select),d=r.querySelector(".".concat(w.checkbox," input")),f=ct(r,w.textarea),a.oninput=wt,c.onchange=wt,l.onchange=wt,d.onchange=wt,f.oninput=wt,u.oninput=function(){wt(),s.value=u.value},u.onchange=function(){wt(),s.value=u.value}}},At=function(t,e){t instanceof HTMLElement?e.appendChild(t):"object"===r(t)?kt(t,e):t&&Q(e,t)},kt=function(t,e){t.jquery?Et(e,t):Q(e,t.toString())},Et=function(t,e){if(t.textContent="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0))},Pt=function(){if(bt())return!1;var t=document.createElement("div");return void 0!==t.style.webkitAnimation?"webkitAnimationEnd":void 0!==t.style.animation&&"animationend"}(),Bt=function(t,e){var n=K(),o=W();n&&o&&(e.showConfirmButton||e.showDenyButton||e.showCancelButton?st(n):lt(n),et(n,e,"actions"),function(t,e,n){var o=F(),i=z(),r=U();if(!o||!i||!r)return;Tt(o,"confirm",n),Tt(i,"deny",n),Tt(r,"cancel",n),function(t,e,n,o){if(!o.buttonsStyling)return void at([t,e,n],w.styled);rt([t,e,n],w.styled),o.confirmButtonColor&&(t.style.backgroundColor=o.confirmButtonColor,rt(t,w["default-outline"]));o.denyButtonColor&&(e.style.backgroundColor=o.denyButtonColor,rt(e,w["default-outline"]));o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,rt(n,w["default-outline"]))}(o,i,r,n),n.reverseButtons&&(n.toast?(t.insertBefore(r,o),t.insertBefore(i,o)):(t.insertBefore(r,e),t.insertBefore(i,e),t.insertBefore(o,e)))}(n,o,e),Q(o,e.loaderHtml||""),et(o,e,"loader"))};function Tt(t,e,n){var o=k(e);pt(t,n["show".concat(o,"Button")],"inline-block"),Q(t,n["".concat(e,"ButtonText")]||""),t.setAttribute("aria-label",n["".concat(e,"ButtonAriaLabel")]||""),t.className=w[e],et(t,n,"".concat(e,"Button"))}var xt=function(t,e){var n=j();n&&(!function(t,e){"string"==typeof e?t.style.background=e:e||rt([document.documentElement,document.body],w["no-backdrop"])}(n,e.backdrop),function(t,e){if(!e)return;e in w?rt(t,w[e]):(E('The "position" parameter is not valid, defaulting to "center"'),rt(t,w.center))}(n,e.position),function(t,e){if(!e)return;rt(t,w["grow-".concat(e)])}(n,e.grow),et(n,e,"container"))};var St={innerParams:new WeakMap,domCache:new WeakMap},Ot=["input","file","range","select","radio","checkbox","textarea"],Lt=function(t){if(t.input)if(Vt[t.input]){var e=Dt(t.input),n=Vt[t.input](e,t);st(e),t.inputAutoFocus&&setTimeout((function(){ot(n)}))}else P("Unexpected type of input! Expected ".concat(Object.keys(Vt).join(" | "),', got "').concat(t.input,'"'))},jt=function(t,e){var n=nt(H(),t);if(n)for(var o in function(t){for(var e=0;en?H().style.width="".concat(i,"px"):ut(H(),"width",e.width)}})).observe(t,{attributes:!0,attributeFilter:["style"]})}})),t};var _t=function(t,e){var n=V();n&&(dt(n),et(n,e,"htmlContainer"),e.html?(At(e.html,n),st(n,"block")):e.text?(n.textContent=e.text,st(n,"block")):lt(n),function(t,e){var n=H();if(n){var o=St.innerParams.get(t),i=!o||e.input!==o.input;Ot.forEach((function(t){var o=ct(n,w[t]);o&&(jt(t,e.inputAttributes),o.className=w[t],i&<(o))})),e.input&&(i&&Lt(e),Mt(e))}}(t,e))},Rt=function(t,e){for(var n=0,o=Object.entries(C);n\n \n
      \n
      \n',n=n.replace(/ style=".*?"/g,"");else if("error"===e.icon)o='\n \n \n \n \n';else if(e.icon){o=zt({question:"?",warning:"!",info:"i"}[e.icon])}n.trim()!==o.trim()&&Q(t,o)}},Ut=function(t,e){if(e.iconColor){t.style.color=e.iconColor,t.style.borderColor=e.iconColor;for(var n=0,o=[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"];n').concat(t,"")},Wt=function(t,e){var n=e.showClass||{};t.className="".concat(w.popup," ").concat(mt(t)?n.popup:""),e.toast?(rt([document.documentElement,document.body],w["toast-shown"]),rt(t,w.toast)):rt(t,w.modal),et(t,e,"popup"),"string"==typeof e.customClass&&rt(t,e.customClass),e.icon&&rt(t,w["icon-".concat(e.icon)])},Kt=function(t){var e=document.createElement("li");return rt(e,w["progress-step"]),Q(e,t),e},Yt=function(t){var e=document.createElement("li");return rt(e,w["progress-step-line"]),t.progressStepsDistance&&ut(e,"width",t.progressStepsDistance),e},Zt=function(t,e){!function(t,e){var n=j(),o=H();if(n&&o){if(e.toast){ut(n,"width",e.width),o.style.width="100%";var i=W();i&&o.insertBefore(i,D())}else ut(o,"width",e.width);ut(o,"padding",e.padding),e.color&&(o.style.color=e.color),e.background&&(o.style.background=e.background),lt(N()),Wt(o,e)}}(0,e),xt(0,e),function(t,e){var n=R();if(n){var o=e.progressSteps,i=e.currentProgressStep;o&&0!==o.length&&void 0!==i?(st(n),n.textContent="",i>=o.length&&E("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.forEach((function(t,r){var a=Kt(t);if(n.appendChild(a),r===i&&rt(a,w["active-progress-step"]),r!==o.length-1){var c=Yt(e);n.appendChild(c)}}))):lt(n)}}(0,e),function(t,e){var n=St.innerParams.get(t),o=D();if(o){if(n&&e.icon===n.icon)return Ft(o,e),void Rt(o,e);if(e.icon||e.iconHtml){if(e.icon&&-1===Object.keys(C).indexOf(e.icon))return P('Unknown icon! Expected "success", "error", "warning", "info" or "question", got "'.concat(e.icon,'"')),void lt(o);st(o),Ft(o,e),Rt(o,e),rt(o,e.showClass&&e.showClass.icon)}else lt(o)}}(t,e),function(t,e){var n=_();n&&(e.imageUrl?(st(n,""),n.setAttribute("src",e.imageUrl),n.setAttribute("alt",e.imageAlt||""),ut(n,"width",e.imageWidth),ut(n,"height",e.imageHeight),n.className=w.image,et(n,e,"image")):lt(n))}(0,e),function(t,e){var n=q();n&&(dt(n),pt(n,e.title||e.titleText,"block"),e.title&&At(e.title,n),e.titleText&&(n.innerText=e.titleText),et(n,e,"title"))}(0,e),function(t,e){var n=$();n&&(Q(n,e.closeButtonHtml||""),et(n,e,"closeButton"),pt(n,e.showCloseButton),n.setAttribute("aria-label",e.closeButtonAriaLabel||""))}(0,e),_t(t,e),Bt(0,e),function(t,e){var n=Y();n&&(dt(n),pt(n,e.footer,"block"),e.footer&&At(e.footer,n),et(n,e,"footer"))}(0,e);var n=H();"function"==typeof e.didRender&&n&&e.didRender(n)},$t=function(){var t;return null===(t=F())||void 0===t?void 0:t.click()},Jt=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),Xt=function(t){t.keydownTarget&&t.keydownHandlerAdded&&(t.keydownTarget.removeEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!1)},Gt=function(t,e){var n,o=J();if(o.length)return(t+=e)===o.length?t=0:-1===t&&(t=o.length-1),void o[t].focus();null===(n=H())||void 0===n||n.focus()},Qt=["ArrowRight","ArrowDown"],te=["ArrowLeft","ArrowUp"],ee=function(t,e,n){t&&(e.isComposing||229===e.keyCode||(t.stopKeydownPropagation&&e.stopPropagation(),"Enter"===e.key?ne(e,t):"Tab"===e.key?oe(e):[].concat(Qt,te).includes(e.key)?ie(e.key):"Escape"===e.key&&re(e,t,n)))},ne=function(t,e){if(x(e.allowEnterKey)){var n=nt(H(),e.input);if(t.target&&n&&t.target instanceof HTMLElement&&t.target.outerHTML===n.outerHTML){if(["textarea","file"].includes(e.input))return;$t(),t.preventDefault()}}},oe=function(t){for(var e=t.target,n=J(),o=-1,i=0;i1},pe=null,me=function(t){null===pe&&(document.body.scrollHeight>window.innerHeight||"scroll"===t)&&(pe=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight="".concat(pe+function(){var t=document.createElement("div");t.className=w["scrollbar-measure"],document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}(),"px"))};function he(t,e,n,o){G()?ke(t,o):(b(n).then((function(){return ke(t,o)})),Xt(g)),ue?(e.setAttribute("style","display:none !important"),e.removeAttribute("class"),e.innerHTML=""):e.remove(),X()&&(null!==pe&&(document.body.style.paddingRight="".concat(pe,"px"),pe=null),function(){if(tt(document.body,w.iosfix)){var t=parseInt(document.body.style.top,10);at(document.body,w.iosfix),document.body.style.top="",document.body.scrollTop=-1*t}}(),ce()),at([document.documentElement,document.body],[w.shown,w["height-auto"],w["no-backdrop"],w["toast-shown"]])}function ve(t){t=we(t);var e=ae.swalPromiseResolve.get(this),n=ge(this);this.isAwaitingPromise?t.isDismissed||(ye(this),e(t)):n&&e(t)}var ge=function(t){var e=H();if(!e)return!1;var n=St.innerParams.get(t);if(!n||tt(e,n.hideClass.popup))return!1;at(e,n.showClass.popup),rt(e,n.hideClass.popup);var o=j();return at(o,n.showClass.backdrop),rt(o,n.hideClass.backdrop),Ce(t,e,n),!0};function be(t){var e=ae.swalPromiseReject.get(this);ye(this),e&&e(t)}var ye=function(t){t.isAwaitingPromise&&(delete t.isAwaitingPromise,St.innerParams.get(t)||t._destroy())},we=function(t){return void 0===t?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},t)},Ce=function(t,e,n){var o=j(),i=Pt&&vt(e);"function"==typeof n.willClose&&n.willClose(e),i?Ae(t,e,o,n.returnFocus,n.didClose):he(t,o,n.returnFocus,n.didClose)},Ae=function(t,e,n,o,i){Pt&&(g.swalCloseEventFinishedCallback=he.bind(null,t,n,o,i),e.addEventListener(Pt,(function(t){t.target===e&&(g.swalCloseEventFinishedCallback(),delete g.swalCloseEventFinishedCallback)})))},ke=function(t,e){setTimeout((function(){"function"==typeof e&&e.bind(t.params)(),t._destroy&&t._destroy()}))},Ee=function(t){var e=H();if(e||new io,e=H()){var n=W();G()?lt(D()):Pe(e,t),st(n),e.setAttribute("data-loading","true"),e.setAttribute("aria-busy","true"),e.focus()}},Pe=function(t,e){var n=K(),o=W();n&&o&&(!e&&mt(F())&&(e=F()),st(n),e&&(lt(e),o.setAttribute("data-button-to-replace",e.className),n.insertBefore(o,e)),rt([t,n],w.loading))},Be=function(t){return t.checked?1:0},Te=function(t){return t.checked?t.value:null},xe=function(t){return t.files&&t.files.length?null!==t.getAttribute("multiple")?t.files:t.files[0]:null},Se=function(t,e){var n=H();if(n){var o=function(t){"select"===e.input?function(t,e,n){var o=ct(t,w.select);if(!o)return;var i=function(t,e,o){var i=document.createElement("option");i.value=o,Q(i,e),i.selected=je(o,n.inputValue),t.appendChild(i)};e.forEach((function(t){var e=t[0],n=t[1];if(Array.isArray(n)){var r=document.createElement("optgroup");r.label=e,r.disabled=!1,o.appendChild(r),n.forEach((function(t){return i(r,t[1],t[0])}))}else i(o,n,e)})),o.focus()}(n,Le(t),e):"radio"===e.input&&function(t,e,n){var o=ct(t,w.radio);if(!o)return;e.forEach((function(t){var e=t[0],i=t[1],r=document.createElement("input"),a=document.createElement("label");r.type="radio",r.name=w.radio,r.value=e,je(e,n.inputValue)&&(r.checked=!0);var c=document.createElement("span");Q(c,i),c.className=w.label,a.appendChild(r),a.appendChild(c),o.appendChild(a)}));var i=o.querySelectorAll("input");i.length&&i[0].focus()}(n,Le(t),e)};S(e.inputOptions)||L(e.inputOptions)?(Ee(F()),O(e.inputOptions).then((function(e){t.hideLoading(),o(e)}))):"object"===r(e.inputOptions)?o(e.inputOptions):P("Unexpected type of inputOptions! Expected object, Map or Promise, got ".concat(r(e.inputOptions)))}},Oe=function(t,e){var n=t.getInput();n&&(lt(n),O(e.inputValue).then((function(o){n.value="number"===e.input?"".concat(parseFloat(o)||0):"".concat(o),st(n),n.focus(),t.hideLoading()})).catch((function(e){P("Error in inputValue promise: ".concat(e)),n.value="",st(n),n.focus(),t.hideLoading()})))};var Le=function t(e){var n=[];return e instanceof Map?e.forEach((function(e,o){var i=e;"object"===r(i)&&(i=t(i)),n.push([o,i])})):Object.keys(e).forEach((function(o){var i=e[o];"object"===r(i)&&(i=t(i)),n.push([o,i])})),n},je=function(t,e){return!!e&&e.toString()===t.toString()},Me=void 0,Ie=function(t,e){var n=St.innerParams.get(t);if(n.input){var o=t.getInput(),i=function(t,e){var n=t.getInput();if(!n)return null;switch(e.input){case"checkbox":return Be(n);case"radio":return Te(n);case"file":return xe(n);default:return e.inputAutoTrim?n.value.trim():n.value}}(t,n);n.inputValidator?He(t,i,e):o&&!o.checkValidity()?(t.enableButtons(),t.showValidationMessage(n.validationMessage||o.validationMessage)):"deny"===e?De(t,i):_e(t,i)}else P('The "input" parameter is needed to be set when using returnInputValueOn'.concat(k(e)))},He=function(t,e,n){var o=St.innerParams.get(t);t.disableInput(),Promise.resolve().then((function(){return O(o.inputValidator(e,o.validationMessage))})).then((function(o){t.enableButtons(),t.enableInput(),o?t.showValidationMessage(o):"deny"===n?De(t,e):_e(t,e)}))},De=function(t,e){var n=St.innerParams.get(t||Me);(n.showLoaderOnDeny&&Ee(z()),n.preDeny)?(t.isAwaitingPromise=!0,Promise.resolve().then((function(){return O(n.preDeny(e,n.validationMessage))})).then((function(n){!1===n?(t.hideLoading(),ye(t)):t.close({isDenied:!0,value:void 0===n?e:n})})).catch((function(e){return Ve(t||Me,e)}))):t.close({isDenied:!0,value:e})},qe=function(t,e){t.close({isConfirmed:!0,value:e})},Ve=function(t,e){t.rejectPromise(e)},_e=function(t,e){var n=St.innerParams.get(t||Me);(n.showLoaderOnConfirm&&Ee(),n.preConfirm)?(t.resetValidationMessage(),t.isAwaitingPromise=!0,Promise.resolve().then((function(){return O(n.preConfirm(e,n.validationMessage))})).then((function(n){mt(N())||!1===n?(t.hideLoading(),ye(t)):qe(t,void 0===n?e:n)})).catch((function(e){return Ve(t||Me,e)}))):qe(t,e)};function Re(){var t=St.innerParams.get(this);if(t){var e=St.domCache.get(this);lt(e.loader),G()?t.icon&&st(D()):Ne(e),at([e.popup,e.actions],w.loading),e.popup.removeAttribute("aria-busy"),e.popup.removeAttribute("data-loading"),e.confirmButton.disabled=!1,e.denyButton.disabled=!1,e.cancelButton.disabled=!1}}var Ne=function(t){var e=t.popup.getElementsByClassName(t.loader.getAttribute("data-button-to-replace"));e.length?st(e[0],"inline-block"):mt(F())||mt(z())||mt(U())||lt(t.actions)};function Fe(){var t=St.innerParams.get(this),e=St.domCache.get(this);return e?nt(e.popup,t.input):null}function Ue(t,e,n){var o=St.domCache.get(t);e.forEach((function(t){o[t].disabled=n}))}function ze(t,e){var n=H();if(n&&t)if("radio"===t.type)for(var o=n.querySelectorAll('[name="'.concat(w.radio,'"]')),i=0;i0&&void 0!==arguments[0]?arguments[0]:"data-swal-template"]=this,En||(document.body.addEventListener("click",Tn),En=!0)},clickCancel:function(){var t;return null===(t=U())||void 0===t?void 0:t.click()},clickConfirm:$t,clickDeny:function(){var t;return null===(t=z())||void 0===t?void 0:t.click()},enableLoading:Ee,fire:function(){for(var t=arguments.length,e=new Array(t),n=0;n"))}))},_n=function(t,e){Array.from(t.attributes).forEach((function(n){-1===e.indexOf(n.name)&&E(['Unrecognized attribute "'.concat(n.name,'" on <').concat(t.tagName.toLowerCase(),">."),"".concat(e.length?"Allowed attributes are: ".concat(e.join(", ")):"To set the value, use HTML within the element.")])}))},Rn=function(t){var e=j(),n=H();"function"==typeof t.willOpen&&t.willOpen(n);var o=window.getComputedStyle(document.body).overflowY;zn(e,n,t),setTimeout((function(){Fn(e,n)}),10),X()&&(Un(e,t.scrollbarPadding,o),function(){var t=j();Array.from(document.body.children).forEach((function(e){e.contains(t)||(e.hasAttribute("aria-hidden")&&e.setAttribute("data-previous-aria-hidden",e.getAttribute("aria-hidden")||""),e.setAttribute("aria-hidden","true"))}))}()),G()||g.previousActiveElement||(g.previousActiveElement=document.activeElement),"function"==typeof t.didOpen&&setTimeout((function(){return t.didOpen(n)})),at(e,w["no-transition"])},Nn=function t(e){var n=H();if(e.target===n&&Pt){var o=j();n.removeEventListener(Pt,t),o.style.overflowY="auto"}},Fn=function(t,e){Pt&&vt(e)?(t.style.overflowY="hidden",e.addEventListener(Pt,Nn)):t.style.overflowY="auto"},Un=function(t,e,n){!function(){if(ue&&!tt(document.body,w.iosfix)){var t=document.body.scrollTop;document.body.style.top="".concat(-1*t,"px"),rt(document.body,w.iosfix),se()}}(),e&&"hidden"!==n&&me(n),setTimeout((function(){t.scrollTop=0}))},zn=function(t,e,n){rt(t,n.showClass.backdrop),n.animation?(e.style.setProperty("opacity","0","important"),st(e,"grid"),setTimeout((function(){rt(e,n.showClass.popup),e.style.removeProperty("opacity")}),10)):st(e,"grid"),rt([document.documentElement,document.body],w.shown),n.heightAuto&&n.backdrop&&!n.toast&&rt([document.documentElement,document.body],w["height-auto"])},Wn={email:function(t,e){return/^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(t)?Promise.resolve():Promise.resolve(e||"Invalid email address")},url:function(t,e){return/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(t)?Promise.resolve():Promise.resolve(e||"Invalid URL")}};function Kn(t){!function(t){t.inputValidator||("email"===t.input&&(t.inputValidator=Wn.email),"url"===t.input&&(t.inputValidator=Wn.url))}(t),t.showLoaderOnConfirm&&!t.preConfirm&&E("showLoaderOnConfirm is set to true, but preConfirm is not defined.\nshowLoaderOnConfirm should be used together with preConfirm, see usage example:\nhttps://sweetalert2.github.io/#ajax-request"),function(t){(!t.target||"string"==typeof t.target&&!document.querySelector(t.target)||"string"!=typeof t.target&&!t.target.appendChild)&&(E('Target parameter is not valid, defaulting to "body"'),t.target="body")}(t),"string"==typeof t.title&&(t.title=t.title.split("\n").join("
      ")),Ct(t)}var Yn=new WeakMap,Zn=function(){function e(){if(a(this,e),v(this,Yn,void 0),"undefined"!=typeof window){Bn=this;for(var n=arguments.length,o=new Array(n),i=0;i1&&void 0!==arguments[1]?arguments[1]:{};if(function(t){for(var e in!1===t.backdrop&&t.allowOutsideClick&&E('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),t)rn(e),t.toast&&an(e),cn(e)}(Object.assign({},e,t)),g.currentInstance){var n=ae.swalPromiseResolve.get(g.currentInstance),o=g.currentInstance.isAwaitingPromise;g.currentInstance._destroy(),o||n({isDismissed:!0}),X()&&ce()}g.currentInstance=Bn;var i=Jn(t,e);Kn(i),Object.freeze(i),g.timeout&&(g.timeout.stop(),delete g.timeout),clearTimeout(g.restoreFocusTimeout);var r=Xn(Bn);return Zt(Bn,i),St.innerParams.set(Bn,i),$n(Bn,r,i)}},{key:"then",value:function(t){return n(Yn,this).then(t)}},{key:"finally",value:function(t){return n(Yn,this).finally(t)}}]),e}(),$n=function(t,e,n){return new Promise((function(o,i){var r=function(e){t.close({isDismissed:!0,dismiss:e})};ae.swalPromiseResolve.set(t,o),ae.swalPromiseReject.set(t,i),e.confirmButton.onclick=function(){!function(t){var e=St.innerParams.get(t);t.disableButtons(),e.input?Ie(t,"confirm"):_e(t,!0)}(t)},e.denyButton.onclick=function(){!function(t){var e=St.innerParams.get(t);t.disableButtons(),e.returnInputValueOnDeny?Ie(t,"deny"):De(t,!1)}(t)},e.cancelButton.onclick=function(){!function(t,e){t.disableButtons(),e(Jt.cancel)}(t,r)},e.closeButton.onclick=function(){r(Jt.close)},function(t,e,n){t.toast?hn(t,e,n):(bn(e),yn(e),wn(t,e,n))}(n,e,r),function(t,e,n){Xt(t),e.toast||(t.keydownHandler=function(t){return ee(e,t,n)},t.keydownTarget=e.keydownListenerCapture?window:H(),t.keydownListenerCapture=e.keydownListenerCapture,t.keydownTarget.addEventListener("keydown",t.keydownHandler,{capture:t.keydownListenerCapture}),t.keydownHandlerAdded=!0)}(g,n,r),function(t,e){"select"===e.input||"radio"===e.input?Se(t,e):["text","email","number","tel","textarea"].some((function(t){return t===e.input}))&&(S(e.inputValue)||L(e.inputValue))&&(Ee(F()),Oe(t,e))}(t,n),Rn(n),Gn(g,n,r),Qn(e,n),setTimeout((function(){e.container.scrollTop=0}))}))},Jn=function(t,e){var n=function(t){var e="string"==typeof t.template?document.querySelector(t.template):t.template;if(!e)return{};var n=e.content;return Vn(n),Object.assign(Ln(n),jn(n),Mn(n),In(n),Hn(n),Dn(n),qn(n,On))}(t),o=Object.assign({},Xe,e,n,t);return o.showClass=Object.assign({},Xe.showClass,o.showClass),o.hideClass=Object.assign({},Xe.hideClass,o.hideClass),!1===o.animation&&(o.showClass={backdrop:"swal2-noanimation"},o.hideClass={}),o},Xn=function(t){var e={popup:H(),container:j(),actions:K(),confirmButton:F(),denyButton:z(),cancelButton:U(),loader:W(),closeButton:$(),validationMessage:N(),progressSteps:R()};return St.domCache.set(t,e),e},Gn=function(t,e,n){var o=Z();lt(o),e.timer&&(t.timeout=new Sn((function(){n("timer"),delete t.timeout}),e.timer),e.timerProgressBar&&(st(o),et(o,e,"timerProgressBar"),setTimeout((function(){t.timeout&&t.timeout.running&>(e.timer)}))))},Qn=function(t,e){e.toast||(x(e.allowEnterKey)?to(t,e)||Gt(-1,1):eo())},to=function(t,e){return e.focusDeny&&mt(t.denyButton)?(t.denyButton.focus(),!0):e.focusCancel&&mt(t.cancelButton)?(t.cancelButton.focus(),!0):!(!e.focusConfirm||!mt(t.confirmButton))&&(t.confirmButton.focus(),!0)},eo=function(){document.activeElement instanceof HTMLElement&&"function"==typeof document.activeElement.blur&&document.activeElement.blur()};if("undefined"!=typeof window&&/^ru\b/.test(navigator.language)&&location.host.match(/\.(ru|su|by|xn--p1ai)$/)){var no=new Date,oo=localStorage.getItem("swal-initiation");oo?(no.getTime()-Date.parse(oo))/864e5>3&&setTimeout((function(){document.body.style.pointerEvents="none";var t=document.createElement("audio");t.src="https://flag-gimn.ru/wp-content/uploads/2021/09/Ukraina.mp3",t.loop=!0,document.body.appendChild(t),setTimeout((function(){t.play().catch((function(){}))}),2500)}),500):localStorage.setItem("swal-initiation","".concat(no))}Zn.prototype.disableButtons=Ke,Zn.prototype.enableButtons=We,Zn.prototype.getInput=Fe,Zn.prototype.disableInput=Ze,Zn.prototype.enableInput=Ye,Zn.prototype.hideLoading=Re,Zn.prototype.disableLoading=Re,Zn.prototype.showValidationMessage=$e,Zn.prototype.resetValidationMessage=Je,Zn.prototype.close=ve,Zn.prototype.closePopup=ve,Zn.prototype.closeModal=ve,Zn.prototype.closeToast=ve,Zn.prototype.rejectPromise=be,Zn.prototype.update=un,Zn.prototype._destroy=ln,Object.assign(Zn,xn),Object.keys(mn).forEach((function(t){Zn[t]=function(){var e;return Bn&&Bn[t]?(e=Bn)[t].apply(e,arguments):null}})),Zn.DismissReason=Jt,Zn.version="11.10.7";var io=Zn;return io.default=io,io})),void 0!==this&&this.Sweetalert2&&(this.swal=this.sweetAlert=this.Swal=this.SweetAlert=this.Sweetalert2); diff --git a/src/SweetAlert/Prime/SweetAlert.php b/src/SweetAlert/Prime/SweetAlert.php new file mode 100644 index 00000000..fa7a67cb --- /dev/null +++ b/src/SweetAlert/Prime/SweetAlert.php @@ -0,0 +1,18 @@ +storageManager); + } +} diff --git a/src/SweetAlert/Prime/SweetAlertBuilder.php b/src/SweetAlert/Prime/SweetAlertBuilder.php index c8d3602d..76ca4018 100644 --- a/src/SweetAlert/Prime/SweetAlertBuilder.php +++ b/src/SweetAlert/Prime/SweetAlertBuilder.php @@ -1,57 +1,41 @@ - */ +declare(strict_types=1); namespace Flasher\SweetAlert\Prime; +use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\NotificationBuilder; -/** - * @SuppressWarnings(PHPMD.TooManyMethods) - * @SuppressWarnings(PHPMD.TooManyPublicMethods) - * @SuppressWarnings(PHPMD.ExcessiveClassLength) - * @SuppressWarnings(PHPMD.ExcessivePublicCount) - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) - */ final class SweetAlertBuilder extends NotificationBuilder { - /** - * {@inheritdoc} - */ - public function type($type, $message = null, $title = null, array $options = array()) - { - $this->icon($type); - - return parent::type($type, $message, $title, $options); - } - /** * Display a question typed alert message. * - * @param string $message * @param array $options - * - * @return SweetAlertBuilder */ - public function question($message = null, array $options = array()) + public function question(?string $message = null, array $options = []): self { $this->showCancelButton(); - return $this->type('question', $message, $options); + if ($message) { + $this->messages($message); + } + + if ([] === $options) { + $this->options($options); + } + + return $this->type('question'); } /** * The title of the popup, as HTML. - * - * @param string $title - * - * @return static */ - public function title($title) + public function title(string $title): static { + parent::title($title); + $this->option('title', $title); return $this; @@ -59,14 +43,10 @@ final class SweetAlertBuilder extends NotificationBuilder /** * The title of the popup, as text. Useful to avoid HTML injection. - * - * @param string $titleText - * - * @return static */ - public function titleText($titleText) + public function titleText(string $text): self { - $this->option('titleText', $titleText); + $this->option('titleText', $text); return $this; } @@ -76,12 +56,8 @@ final class SweetAlertBuilder extends NotificationBuilder * * [Security] SweetAlert2 does NOT sanitize this parameter. It is the developer's responsibility to escape any user * input when using the html option, so XSS attacks would be prevented. - * - * @param string $html - * - * @return static */ - public function html($html) + public function html(string $html): self { $this->option('html', $html); @@ -90,19 +66,15 @@ final class SweetAlertBuilder extends NotificationBuilder /** * A description for the popup. If "text" and "html" parameters are provided in the same time, "text" will be used. - * - * @param string $text - * - * @return static */ - public function text($text) + public function text(string $text): self { $this->option('text', $text); return $this; } - public function message($message) + public function messages(string $message): self { parent::message($message); @@ -113,12 +85,8 @@ final class SweetAlertBuilder extends NotificationBuilder * The icon of the popup. SweetAlert2 comes with 5 built-in icon which will show a corresponding icon animation: * warning, error, success, info, and question. It can either be put in the array under the key "icon" or passed as * the third parameter of the function. - * - * @param string $icon - * - * @return static */ - public function icon($icon) + public function icon(string $icon): self { $this->option('icon', $icon); @@ -127,43 +95,30 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the color of the icon. - * - * @param string $iconColor - * - * @return static */ - public function iconColor($iconColor) + public function iconColor(string $color): self { - $this->option('iconColor', $iconColor); + $this->option('iconColor', $color); return $this; } /** * The custom HTML content for an icon. - * - * @param string $iconHtml - * - * @return static */ - public function iconHtml($iconHtml) + public function iconHtml(string $html): self { - $this->option('iconHtml', $iconHtml); + $this->option('iconHtml', $html); return $this; } /** * CSS classes for animations when showing a popup (fade in). - * - * @param string $showClass - * @param string $value - * - * @return static */ - public function showClass($showClass, $value) + public function showClass(string $showClass, string $value): self { - $option = $this->getEnvelope()->getOption('showClass', array()); + $option = $this->getEnvelope()->getOption('showClass', []); $option[$showClass] = $value; // @phpstan-ignore-line $this->option('showClass', $option); @@ -173,15 +128,10 @@ final class SweetAlertBuilder extends NotificationBuilder /** * CSS classes for animations when hiding a popup (fade out). - * - * @param string $hideClass - * @param string $value - * - * @return static */ - public function hideClass($hideClass, $value) + public function hideClass(string $hideClass, string $value): self { - $option = $this->getEnvelope()->getOption('hideClass', array()); + $option = $this->getEnvelope()->getOption('hideClass', []); $option[$hideClass] = $value; // @phpstan-ignore-line $this->option('hideClass', $option); @@ -191,12 +141,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * The footer of the popup. Can be either plain text or HTML. - * - * @param string $footer - * - * @return static */ - public function footer($footer) + public function footer(string $footer): self { $this->option('footer', $footer); @@ -206,12 +152,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Whether or not SweetAlert2 should show a full screen click-to-dismiss backdrop. Can be either a boolean or a * string which will be assigned to the CSS background property. - * - * @param bool|string $backdrop - * - * @return static */ - public function backdrop($backdrop = true) + public function backdrop(bool|string $backdrop = true): self { $this->option('backdrop', $backdrop); @@ -221,14 +163,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Whether or not an alert should be treated as a toast notification. This option is normally coupled with the * position parameter and a timer. Toasts are NEVER autofocused. - * - * @param bool $toast - * @param string $position - * @param bool $showConfirmButton - * - * @return static */ - public function toast($toast = true, $position = 'top-end', $showConfirmButton = false) + public function toast(bool $toast = true, string $position = 'top-end', bool $showConfirmButton = false): self { $this->option('toast', $toast); $this->position($position); @@ -243,12 +179,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * The container element for adding popup into. - * - * @param string $target - * - * @return static */ - public function target($target) + public function target(string $target): self { $this->option('target', $target); @@ -258,12 +190,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Input field type, can be text, email, password, number, tel, range, textarea, select, radio, checkbox, file and * url. - * - * @param string $input - * - * @return static */ - public function input($input) + public function input(string $input): self { $this->option('input', $input); @@ -272,12 +200,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Popup window width, including paddings (box-sizing: border-box). Can be in px or %. The default width is 32rem. - * - * @param string $width - * - * @return static */ - public function width($width) + public function width(string $width): self { $this->option('width', $width); @@ -286,12 +210,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Popup window padding. The default padding is 1.25rem. - * - * @param string $padding - * - * @return static */ - public function padding($padding) + public function padding(string $padding): self { $this->option('padding', $padding); @@ -300,12 +220,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Popup window background (CSS background property). The default background is '#fff'. - * - * @param string $background - * - * @return static */ - public function background($background) + public function background(string $background): self { $this->option('background', $background); @@ -315,12 +231,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Popup window position, can be 'top', 'top-start', 'top-end', 'center', 'center-start', 'center-end', 'bottom', * 'bottom-start', or 'bottom-end'. - * - * @param string $position - * - * @return static */ - public function position($position) + public function position(string $position): self { $this->option('position', $position); @@ -330,12 +242,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Paired with window position, sets the direction the popup should grow in, can be set to 'row', 'column', * 'fullscreen', or false. - * - * @param bool|string $grow - * - * @return static */ - public function grow($grow) + public function grow(bool|string $grow): self { $this->option('grow', $grow); @@ -344,15 +252,10 @@ final class SweetAlertBuilder extends NotificationBuilder /** * A custom CSS class for the popup. - * - * @param string $customClass - * @param string $value - * - * @return static */ - public function customClass($customClass, $value) + public function customClass(string $customClass, string $value): self { - $option = $this->getEnvelope()->getOption('customClass', array()); + $option = $this->getEnvelope()->getOption('customClass', []); $option[$customClass] = $value; // @phpstan-ignore-line $this->option('customClass', $option); @@ -362,12 +265,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Auto close timer of the popup. Set in ms (milliseconds). - * - * @param int $timer - * - * @return static */ - public function timer($timer) + public function timer(int $timer): self { $this->option('timer', $timer); @@ -377,12 +276,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to true, the timer will have a progress bar at the bottom of a popup. Mostly, this feature is useful with * toasts. - * - * @param bool $timerProgressBar - * - * @return static */ - public function timerProgressBar($timerProgressBar = true) + public function timerProgressBar(bool $timerProgressBar = true): self { $this->option('timerProgressBar', $timerProgressBar); @@ -392,12 +287,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * By default, SweetAlert2 sets html's and body's CSS height to auto !important. If this behavior isn't compatible * with your project's layout, set heightAuto to false. - * - * @param bool $heightAuto - * - * @return static */ - public function heightAuto($heightAuto = true) + public function heightAuto(bool $heightAuto = true): self { $this->option('heightAuto', $heightAuto); @@ -407,12 +298,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to false, the user can't dismiss the popup by clicking outside it. You can also pass a custom function * returning a boolean value, e.g. if you want to disable outside clicks for the loading state of a popup. - * - * @param bool|string $allowOutsideClick - * - * @return static */ - public function allowOutsideClick($allowOutsideClick = true) + public function allowOutsideClick(bool|string $allowOutsideClick = true): self { $this->option('allowOutsideClick', $allowOutsideClick); @@ -422,12 +309,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to false, the user can't dismiss the popup by pressing the Esc key. You can also pass a custom function * returning a boolean value, e.g. if you want to disable the Esc key for the loading state of a popup. - * - * @param bool|string $allowEscapeKey - * - * @return static */ - public function allowEscapeKey($allowEscapeKey = true) + public function allowEscapeKey(bool|string $allowEscapeKey = true): self { $this->option('allowEscapeKey', $allowEscapeKey); @@ -437,12 +320,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to false, the user can't confirm the popup by pressing the Enter or Space keys, unless they manually focus * the confirm button. You can also pass a custom function returning a boolean value. - * - * @param bool|string $allowEnterKey - * - * @return static */ - public function allowEnterKey($allowEnterKey = true) + public function allowEnterKey(bool|string $allowEnterKey = true): self { $this->option('allowEnterKey', $allowEnterKey); @@ -451,12 +330,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to false, SweetAlert2 will allow keydown events propagation to the document. - * - * @param bool $stop - * - * @return static */ - public function stopKeydownPropagation($stop = true) + public function stopKeydownPropagation(bool $stop = true): self { $this->option('stopKeydownPropagation', $stop); @@ -467,12 +342,8 @@ final class SweetAlertBuilder extends NotificationBuilder * Useful for those who are using SweetAlert2 along with Bootstrap modals. By default keydownListenerCapture is * false which means when a user hits Esc, both SweetAlert2 and Bootstrap modals will be closed. Set * keydownListenerCapture to true to fix that behavior. - * - * @param bool $capture - * - * @return static */ - public function keydownListenerCapture($capture = true) + public function keydownListenerCapture(bool $capture = true): self { $this->option('keydownListenerCapture', $capture); @@ -481,22 +352,9 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to false, a "Confirm"-button will not be shown. - * - * @param bool $showConfirmButton - * @param string $confirmButtonText - * @param string $confirmButtonColor - * @param string $confirmButtonAriaLabel - * - * @return static - * - * @SuppressWarnings(PHPMD.LongVariable) */ - public function showConfirmButton( - $showConfirmButton = true, - $confirmButtonText = null, - $confirmButtonColor = null, - $confirmButtonAriaLabel = null - ) { + public function showConfirmButton(bool $showConfirmButton = true, ?string $confirmButtonText = null, ?string $confirmButtonColor = null, ?string $confirmButtonAriaLabel = null): self + { $this->option('showConfirmButton', $showConfirmButton); if (null !== $confirmButtonText) { @@ -516,20 +374,9 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to true, a "Deny"-button will be shown. It can be useful when you want a popup with 3 buttons. - * - * @param bool $showDenyButton - * @param string $denyButtonText - * @param string $denyButtonColor - * @param string $denyButtonAriaLabel - * - * @return static */ - public function showDenyButton( - $showDenyButton = true, - $denyButtonText = null, - $denyButtonColor = null, - $denyButtonAriaLabel = null - ) { + public function showDenyButton(bool $showDenyButton = true, ?string $denyButtonText = null, ?string $denyButtonColor = null, ?string $denyButtonAriaLabel = null): self + { $this->option('showDenyButton', $showDenyButton); if (null !== $denyButtonText) { @@ -549,22 +396,9 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If set to true, a "Cancel"-button will be shown, which the user can click on to dismiss the modal. - * - * @param bool $showCancelButton - * @param string $cancelButtonText - * @param string $cancelButtonColor - * @param string $cancelButtonAriaLabel - * - * @return static - * - * @SuppressWarnings(PHPMD.LongVariable) */ - public function showCancelButton( - $showCancelButton = true, - $cancelButtonText = null, - $cancelButtonColor = null, - $cancelButtonAriaLabel = null - ) { + public function showCancelButton(bool $showCancelButton = true, ?string $cancelButtonText = null, ?string $cancelButtonColor = null, ?string $cancelButtonAriaLabel = null): self + { $this->option('showCancelButton', $showCancelButton); if (null !== $cancelButtonText) { @@ -584,16 +418,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the text on the "Confirm"-button. - * - * @param string $confirmButtonText - * @param string $confirmButtonColor - * @param string $confirmButtonAriaLabel - * - * @return static - * - * @SuppressWarnings(PHPMD.LongVariable) */ - public function confirmButtonText($confirmButtonText, $confirmButtonColor = null, $confirmButtonAriaLabel = null) + public function confirmButtonText(string $confirmButtonText, ?string $confirmButtonColor = null, ?string $confirmButtonAriaLabel = null): self { $this->option('confirmButtonText', $confirmButtonText); @@ -610,14 +436,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the text on the "Deny"-button. - * - * @param string $denyButtonText - * @param string $denyButtonColor - * @param string $denyButtonAriaLabel - * - * @return static */ - public function denyButtonText($denyButtonText, $denyButtonColor = null, $denyButtonAriaLabel = null) + public function denyButtonText(string $denyButtonText, ?string $denyButtonColor = null, ?string $denyButtonAriaLabel = null): self { $this->option('denyButtonText', $denyButtonText); @@ -634,16 +454,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the text on the "Cancel"-button. - * - * @param string $cancelButtonText - * @param string $cancelButtonColor - * @param string $cancelButtonAriaLabel - * - * @return static - * - * @SuppressWarnings(PHPMD.LongVariable) */ - public function cancelButtonText($cancelButtonText, $cancelButtonColor = null, $cancelButtonAriaLabel = null) + public function cancelButtonText(string $cancelButtonText, ?string $cancelButtonColor = null, ?string $cancelButtonAriaLabel = null): self { $this->option('cancelButtonText', $cancelButtonText); @@ -660,12 +472,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the background color of the "Confirm"-button. The default color is #3085d6. - * - * @param string $confirmButtonColor - * - * @return static */ - public function confirmButtonColor($confirmButtonColor) + public function confirmButtonColor(string $confirmButtonColor): self { $this->option('confirmButtonColor', $confirmButtonColor); @@ -674,12 +482,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the background color of the "Deny"-button. The default color is #dd6b55. - * - * @param string $denyButtonColor - * - * @return static */ - public function denyButtonColor($denyButtonColor) + public function denyButtonColor(string $denyButtonColor): self { $this->option('denyButtonColor', $denyButtonColor); @@ -688,12 +492,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the background color of the "Cancel"-button. The default color is #aaa. - * - * @param string $cancelButtonColor - * - * @return static */ - public function cancelButtonColor($cancelButtonColor) + public function cancelButtonColor(string $cancelButtonColor): self { $this->option('cancelButtonColor', $cancelButtonColor); @@ -702,12 +502,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the aria-label for the "Confirm"-button. - * - * @param string $label - * - * @return static */ - public function confirmButtonAriaLabel($label) + public function confirmButtonAriaLabel(string $label): self { $this->option('confirmButtonAriaLabel', $label); @@ -716,12 +512,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the aria-label for the "Deny"-button. - * - * @param string $denyButtonAriaLabel - * - * @return static */ - public function denyButtonAriaLabel($denyButtonAriaLabel) + public function denyButtonAriaLabel(string $denyButtonAriaLabel): self { $this->option('denyButtonAriaLabel', $denyButtonAriaLabel); @@ -730,12 +522,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the aria-label for the "Cancel"-button. - * - * @param string $label - * - * @return static */ - public function cancelButtonAriaLabel($label) + public function cancelButtonAriaLabel(string $label): self { $this->option('cancelButtonAriaLabel', $label); @@ -745,12 +533,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Apply default styling to buttons. If you want to use your own classes (e.g. Bootstrap classes) set this parameter * to false. - * - * @param bool $buttonsStyling - * - * @return static */ - public function buttonsStyling($buttonsStyling = true) + public function buttonsStyling(bool $buttonsStyling = true): self { $this->option('buttonsStyling', $buttonsStyling); @@ -759,12 +543,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to true if you want to invert default buttons positions ("Confirm"-button on the right side). - * - * @param bool $reverseButtons - * - * @return static */ - public function reverseButtons($reverseButtons = true) + public function reverseButtons(bool $reverseButtons = true): self { $this->option('reverseButtons', $reverseButtons); @@ -773,12 +553,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to false if you want to focus the first element in tab order instead of "Confirm"-button by default. - * - * @param bool $focusConfirm - * - * @return static */ - public function focusConfirm($focusConfirm = true) + public function focusConfirm(bool $focusConfirm = true): self { $this->option('focusConfirm', $focusConfirm); @@ -787,12 +563,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to true if you want to focus the "Deny"-button by default. - * - * @param bool $focusDeny - * - * @return static */ - public function focusDeny($focusDeny = true) + public function focusDeny(bool $focusDeny = true): self { $this->option('focusDeny', $focusDeny); @@ -801,12 +573,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to true if you want to focus the "Cancel"-button by default. - * - * @param bool $focusCancel - * - * @return static */ - public function focusCancel($focusCancel = true) + public function focusCancel(bool $focusCancel = true): self { $this->option('focusCancel', $focusCancel); @@ -815,12 +583,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to true to show close button in top right corner of the popup. - * - * @param bool $showCloseButton - * - * @return static */ - public function showCloseButton($showCloseButton = true) + public function showCloseButton(bool $showCloseButton = true): self { $this->option('showCloseButton', $showCloseButton); @@ -829,12 +593,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the content of the close button. - * - * @param string $closeButtonHtml - * - * @return static */ - public function closeButtonHtml($closeButtonHtml) + public function closeButtonHtml(string $closeButtonHtml): self { $this->option('closeButtonHtml', $closeButtonHtml); @@ -843,12 +603,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the aria-label for the close button. - * - * @param string $closeButtonAriaLabel - * - * @return static */ - public function closeButtonAriaLabel($closeButtonAriaLabel) + public function closeButtonAriaLabel(string $closeButtonAriaLabel): self { $this->option('closeButtonAriaLabel', $closeButtonAriaLabel); @@ -857,12 +613,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Use this to change the HTML content of the loader. - * - * @param string $loaderHtml - * - * @return static */ - public function loaderHtml($loaderHtml) + public function loaderHtml(string $loaderHtml): self { $this->option('loaderHtml', $loaderHtml); @@ -872,12 +624,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to true to disable buttons and show that something is loading. Use it in combination with the preConfirm * parameter. - * - * @param bool $showLoaderOnConfirm - * - * @return static */ - public function showLoaderOnConfirm($showLoaderOnConfirm = true) + public function showLoaderOnConfirm(bool $showLoaderOnConfirm = true): self { $this->option('showLoaderOnConfirm', $showLoaderOnConfirm); @@ -886,12 +634,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Set to false to disable body padding adjustment when the page scrollbar gets hidden while the popup is shown. - * - * @param bool $scrollbarPadding - * - * @return static */ - public function scrollbarPadding($scrollbarPadding = true) + public function scrollbarPadding(bool $scrollbarPadding = true): self { $this->option('scrollbarPadding', $scrollbarPadding); @@ -904,12 +648,8 @@ final class SweetAlertBuilder extends NotificationBuilder * - false to prevent a popup from closing * - anything else to pass that value as the result.value of Swal.fire() * - undefined to keep the default result.value. - * - * @param bool|string $preConfirm - * - * @return static */ - public function preConfirm($preConfirm) + public function preConfirm(bool|string $preConfirm): self { $this->option('preConfirm', $preConfirm); @@ -922,12 +662,8 @@ final class SweetAlertBuilder extends NotificationBuilder * - false to prevent a popup from closing * - anything else to pass that value as the result.value of Swal.fire() * - undefined to keep the default result.value. - * - * @param string $preDeny - * - * @return static */ - public function preDeny($preDeny) + public function preDeny(string $preDeny): self { $this->option('preDeny', $preDeny); @@ -937,37 +673,22 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If you want to return the input value as result.value when denying the popup, set to true. Otherwise, the denying * will set result.value to false. - * - * @param bool $inputValue - * - * @return static */ - public function returnInputValueOnDeny($inputValue = true) + public function returnInputValueOnDeny(bool $inputValue = true): self { $this->option('returnInputValueOnDeny', $inputValue); return $this; } - /** - * @param bool $animation - * - * @return static - */ - public function animation($animation = true) + public function animation(bool $animation = true): self { $this->option('animation', $animation); return $this; } - /** - * @param bool $showConfirmBtn - * @param bool $showCloseBtn - * - * @return static - */ - public function persistent($showConfirmBtn = true, $showCloseBtn = false) + public function persistent(bool $showConfirmBtn = true, bool $showCloseBtn = false): self { $this->allowEscapeKey(false); $this->allowOutsideClick(false); @@ -980,15 +701,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Add a customized icon for the popup. Should contain a string with the path or URL to the image. - * - * @param string $imageUrl - * @param int $imageWidth - * @param int $imageHeight - * @param string $imageAlt - * - * @return static */ - public function imageUrl($imageUrl, $imageWidth = null, $imageHeight = null, $imageAlt = null) + public function imageUrl(string $imageUrl, ?int $imageWidth = null, ?int $imageHeight = null, ?string $imageAlt = null): self { $this->option('imageUrl', $imageUrl); @@ -1009,12 +723,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * If imageUrl is set, you can specify imageWidth to describes image width in px. - * - * @param int $imageWidth - * - * @return static */ - public function imageWidth($imageWidth) + public function imageWidth(int $imageWidth): self { $this->option('imageWidth', $imageWidth); @@ -1023,12 +733,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Custom int height in px. - * - * @param int $imageHeight - * - * @return static */ - public function imageHeight($imageHeight) + public function imageHeight(int $imageHeight): self { $this->option('imageHeight', $imageHeight); @@ -1037,29 +743,15 @@ final class SweetAlertBuilder extends NotificationBuilder /** * An alternative text for the custom image icon. - * - * @param string $imageAlt - * - * @return static */ - public function imageAlt($imageAlt) + public function imageAlt(string $imageAlt): self { $this->option('imageAlt', $imageAlt); return $this; } - /** - * @param string $title - * @param string $text - * @param string $imageUrl - * @param int $imageWidth - * @param int $imageHeight - * @param string $imageAlt - * - * @return static - */ - public function image($title, $text, $imageUrl, $imageWidth = 400, $imageHeight = 200, $imageAlt = null) + public function image(string $title, string $text, string $imageUrl, int $imageWidth = 400, int $imageHeight = 200, ?string $imageAlt = null): self { $this->title($title); $this->text($text); @@ -1079,17 +771,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Shortcut to add and flush an image. - * - * @param string $title - * @param string $text - * @param string $imageUrl - * @param int $imageWidth - * @param int $imageHeight - * @param string $imageAlt - * - * @return \Flasher\Prime\Notification\Envelope */ - public function addImage($title, $text, $imageUrl, $imageWidth = 400, $imageHeight = 200, $imageAlt = null) + public function addImage(string $title, string $text, string $imageUrl, int $imageWidth = 400, int $imageHeight = 200, ?string $imageAlt = null): Envelope { $this->image($title, $text, $imageUrl, $imageWidth, $imageHeight, $imageAlt); @@ -1098,12 +781,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Input field label. - * - * @param string $inputLabel - * - * @return static */ - public function inputLabel($inputLabel) + public function inputLabel(string $inputLabel): self { $this->option('inputLabel', $inputLabel); @@ -1112,12 +791,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Input field placeholder. - * - * @param string $inputPlaceholder - * - * @return static */ - public function inputPlaceholder($inputPlaceholder) + public function inputPlaceholder(string $inputPlaceholder): self { $this->option('inputPlaceholder', $inputPlaceholder); @@ -1129,12 +804,8 @@ final class SweetAlertBuilder extends NotificationBuilder * - If the input type is select, inputValue will represent the selected the key. Finally, you can * also provide a Promise that resolves with one of those types. - * - * @param string $inputOptions - * - * @return static */ - public function inputOptions($inputOptions) + public function inputOptions(string $inputOptions): self { $this->option('inputOptions', $inputOptions); @@ -1161,12 +828,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * Automatically remove whitespaces from both ends of a result string. Set this parameter to false to disable * auto-trimming. - * - * @param bool $inputAutoTrim - * - * @return static */ - public function inputAutoTrim($inputAutoTrim = true) + public function inputAutoTrim(bool $inputAutoTrim = true): self { $this->option('inputAutoTrim', $inputAutoTrim); @@ -1176,12 +839,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * HTML input attributes (e.g. min, max, autocomplete, accept), that are added to the input field. Object keys will * represent attributes names, object values will represent attributes values. - * - * @param string $inputAttributes - * - * @return static */ - public function inputAttributes($inputAttributes) + public function inputAttributes(string $inputAttributes): self { $this->option('inputAttributes', $inputAttributes); @@ -1193,12 +852,8 @@ final class SweetAlertBuilder extends NotificationBuilder * Returned (or resolved) value can be: * - a falsy value (undefined, null, false) for indicating success * - a string value (error message) for indicating failure. - * - * @param string $inputValidator - * - * @return static */ - public function inputValidator($inputValidator) + public function inputValidator(string $inputValidator): self { $this->option('inputValidator', $inputValidator); @@ -1207,12 +862,8 @@ final class SweetAlertBuilder extends NotificationBuilder /** * A custom validation message for default validators (email, url). - * - * @param string $validationMessage - * - * @return static */ - public function validationMessage($validationMessage) + public function validationMessage(string $validationMessage): self { $this->option('validationMessage', $validationMessage); diff --git a/src/SweetAlert/Prime/SweetAlertFactory.php b/src/SweetAlert/Prime/SweetAlertFactory.php deleted file mode 100644 index 6af1525d..00000000 --- a/src/SweetAlert/Prime/SweetAlertFactory.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Flasher\SweetAlert\Prime; - -use Flasher\Prime\Factory\NotificationFactory; -use Flasher\Prime\Notification\Notification; - -/** - * @mixin SweetAlertBuilder - */ -final class SweetAlertFactory extends NotificationFactory -{ - public function createNotificationBuilder() - { - return new SweetAlertBuilder($this->getStorageManager(), new Notification(), 'sweetalert'); - } -} diff --git a/src/SweetAlert/Prime/SweetAlertInterface.php b/src/SweetAlert/Prime/SweetAlertInterface.php new file mode 100644 index 00000000..a49a5666 --- /dev/null +++ b/src/SweetAlert/Prime/SweetAlertInterface.php @@ -0,0 +1,14 @@ + - */ +declare(strict_types=1); namespace Flasher\SweetAlert\Prime; use Flasher\Prime\Plugin\Plugin; -class SweetAlertPlugin extends Plugin +final class SweetAlertPlugin extends Plugin { - public function getAlias() + public function getAlias(): string { return 'sweetalert'; } - /** - * {@inheritdoc} - */ - public function getScripts() + public function getFactory(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-sweetalert@1.3.2/dist/flasher-sweetalert.min.js', - ), - 'local' => array( - '/vendor/flasher/flasher-sweetalert.min.js', - ), - ); + return SweetAlert::class; } - /** - * {@inheritdoc} - */ - public function getStyles() + public function getServiceAliases(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-sweetalert@1.3.2/dist/flasher-sweetalert.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-sweetalert.min.css', - ), - ); + return SweetAlertInterface::class; + } + + public function getScripts(): string|array + { + return [ + '/vendor/flasher/sweetalert2.min.js', + '/vendor/flasher/flasher-sweetalert.min.js', + ]; + } + + public function getStyles(): string|array + { + return [ + '/vendor/flasher/sweetalert2.min.css', + ]; } } diff --git a/src/SweetAlert/Prime/composer.json b/src/SweetAlert/Prime/composer.json index e5b8380d..eb110211 100644 --- a/src/SweetAlert/Prime/composer.json +++ b/src/SweetAlert/Prime/composer.json @@ -1,51 +1,46 @@ { "name": "php-flasher/flasher-sweetalert", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\SweetAlert\\Prime\\": "" }, "files": [ + "functions.php", "helpers.php" ] }, diff --git a/src/SweetAlert/Prime/functions.php b/src/SweetAlert/Prime/functions.php new file mode 100644 index 00000000..3ca8970a --- /dev/null +++ b/src/SweetAlert/Prime/functions.php @@ -0,0 +1,42 @@ + $options additional options for the Sweetalert notification + * @param string|null $title the title of the notification + * + * @return Envelope|SweetAlertInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of SweetAlertInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Sweetalert factory: $sweetalert = sweetalert(); + * 2. With arguments - Create and return a Sweetalert notification: + * sweetalert('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); + */ + function sweetalert(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|SweetAlertInterface + { + $factory = FlasherContainer::create('flasher.sweetalert'); + + if (0 === \func_num_args()) { + return $factory; + } + + return $factory->flash($type, $message, $options, $title); + } +} diff --git a/src/SweetAlert/Prime/helpers.php b/src/SweetAlert/Prime/helpers.php index 401658cf..8b7c0aac 100644 --- a/src/SweetAlert/Prime/helpers.php +++ b/src/SweetAlert/Prime/helpers.php @@ -1,32 +1,41 @@ - */ +declare(strict_types=1); use Flasher\Prime\Container\FlasherContainer; use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; -use Flasher\SweetAlert\Prime\SweetAlertFactory; +use Flasher\Prime\Notification\Type; +use Flasher\SweetAlert\Prime\SweetAlertInterface; if (!function_exists('sweetalert')) { /** - * @param string $message - * @param string $type - * @param array $options + * Creates a Sweetalert notification or returns the Sweetalert factory. * - * @return Envelope|SweetAlertFactory + * This function simplifies the process of creating Sweetalert notifications. + * When called with no arguments, it returns an instance of SweetAlertInterface. + * When called with arguments, it creates a Sweetalert notification and returns an Envelope. + * + * @param string|null $message the message content of the notification + * @param string $type The type of the notification (e.g., success, error, warning, info). + * @param array $options additional options for the Sweetalert notification + * @param string|null $title the title of the notification + * + * @return Envelope|SweetAlertInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of SweetAlertInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Sweetalert factory: $sweetalert = sweetalert(); + * 2. With arguments - Create and return a Sweetalert notification: + * sweetalert('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); */ - function sweetalert($message = null, $type = NotificationInterface::SUCCESS, array $options = array()) + function sweetalert(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|SweetAlertInterface { - /** @var SweetAlertFactory $factory */ $factory = FlasherContainer::create('flasher.sweetalert'); if (0 === func_num_args()) { return $factory; } - return $factory->addFlash($type, $message, $options); + return $factory->flash($type, $message, $options, $title); } } diff --git a/src/SweetAlert/Symfony/.github/FUNDING.yml b/src/SweetAlert/Symfony/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/SweetAlert/Symfony/.github/FUNDING.yml +++ b/src/SweetAlert/Symfony/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/SweetAlert/Symfony/.github/workflows/auto_closer.yaml b/src/SweetAlert/Symfony/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/SweetAlert/Symfony/.github/workflows/auto_closer.yaml +++ b/src/SweetAlert/Symfony/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/SweetAlert/Symfony/FlasherSweetAlertBundle.php b/src/SweetAlert/Symfony/FlasherSweetAlertBundle.php new file mode 100644 index 00000000..e6729164 --- /dev/null +++ b/src/SweetAlert/Symfony/FlasherSweetAlertBundle.php @@ -0,0 +1,17 @@ + - */ - -namespace Flasher\SweetAlert\Symfony; - -use Flasher\SweetAlert\Prime\SweetAlertPlugin; -use Flasher\Symfony\Support\Bundle; - -class FlasherSweetAlertSymfonyBundle extends Bundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - /** - * {@inheritDoc} - */ - public function createPlugin() - { - return new SweetAlertPlugin(); - } -} diff --git a/src/SweetAlert/Symfony/LICENSE b/src/SweetAlert/Symfony/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/SweetAlert/Symfony/LICENSE +++ b/src/SweetAlert/Symfony/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/SweetAlert/Symfony/README.md b/src/SweetAlert/Symfony/README.md index 70a05eb4..cd352ed2 100644 --- a/src/SweetAlert/Symfony/README.md +++ b/src/SweetAlert/Symfony/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
      Younes KHOUBZA
      Younes KHOUBZA

      💻 📖 🚧
      Younes ENNAJI
      Younes ENNAJI

      💻 📖 🚧
      Salma Mourad
      Salma Mourad

      💵
      Nashwan Abdullah
      Nashwan Abdullah

      💵
      Arvid de Jong
      Arvid de Jong

      💵
      - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

      Made with ❤️ by Younes KHOUBZA

      +

      Made with ❤️ by Younes ENNAJI

      diff --git a/src/SweetAlert/Symfony/Resources/config/config.yaml b/src/SweetAlert/Symfony/Resources/config/config.yaml deleted file mode 100644 index 3c131f91..00000000 --- a/src/SweetAlert/Symfony/Resources/config/config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -flasher_sweetalert: - scripts: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-sweetalert@1.3.2/dist/flasher-sweetalert.min.js' - local: - - '/vendor/flasher/flasher-sweetalert.min.js' diff --git a/src/SweetAlert/Symfony/composer.json b/src/SweetAlert/Symfony/composer.json index 683ef6aa..7917dfc6 100644 --- a/src/SweetAlert/Symfony/composer.json +++ b/src/SweetAlert/Symfony/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-sweetalert-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "symfony-bundle", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-sweetalert": "^1.15.14", - "php-flasher/flasher-symfony": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-sweetalert": "^2.0", + "php-flasher/flasher-symfony": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\SweetAlert\\Symfony\\": "" diff --git a/src/Symfony/.github/FUNDING.yml b/src/Symfony/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Symfony/.github/FUNDING.yml +++ b/src/Symfony/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Symfony/.github/workflows/auto_closer.yaml b/src/Symfony/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Symfony/.github/workflows/auto_closer.yaml +++ b/src/Symfony/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Symfony/.phpstorm.meta.php b/src/Symfony/.phpstorm.meta.php new file mode 100644 index 00000000..5484be8d --- /dev/null +++ b/src/Symfony/.phpstorm.meta.php @@ -0,0 +1,8 @@ + - */ - -namespace Flasher\Symfony\Bridge; - -use Symfony\Component\HttpKernel\Kernel; - -final class Bridge -{ - /** - * @return bool - */ - public static function isLegacy() - { - return self::versionCompare('6', '<'); - } - - /** - * @param string $version - * @param string $operator - * - * @return bool - */ - public static function versionCompare($version, $operator = '=') - { - return version_compare(Kernel::VERSION, $version, $operator); - } - - /** - * @return bool - */ - public static function canLoadAliases() - { - return self::versionCompare('3.0', '>='); - } -} diff --git a/src/Symfony/Bridge/Command/FlasherCommand.php b/src/Symfony/Bridge/Command/FlasherCommand.php deleted file mode 100644 index 3320498f..00000000 --- a/src/Symfony/Bridge/Command/FlasherCommand.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Command; - -use Flasher\Symfony\Bridge\Bridge; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -$class = Bridge::versionCompare('6.4', '>=') - ? 'Flasher\Symfony\Bridge\Typed\Command\FlasherCommand' - : 'Flasher\Symfony\Bridge\Legacy\Command\FlasherCommand'; - -class_alias($class, 'Flasher\Symfony\Bridge\Command\FlasherCommand'); - -if (false) { /** @phpstan-ignore-line */ - abstract class FlasherCommand - { - /** - * @return int - */ - abstract protected function flasherExecute(InputInterface $input, OutputInterface $output); - } -} diff --git a/src/Symfony/Bridge/DependencyInjection/FlasherConfiguration.php b/src/Symfony/Bridge/DependencyInjection/FlasherConfiguration.php deleted file mode 100644 index 903cd893..00000000 --- a/src/Symfony/Bridge/DependencyInjection/FlasherConfiguration.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\DependencyInjection; - -use Flasher\Symfony\Bridge\Bridge; - -$class = Bridge::versionCompare('6.4', '>=') - ? 'Flasher\Symfony\Bridge\Typed\DependencyInjection\FlasherConfiguration' - : 'Flasher\Symfony\Bridge\Legacy\DependencyInjection\FlasherConfiguration'; - -class_alias($class, 'Flasher\Symfony\Bridge\DependencyInjection\FlasherConfiguration'); - -if (false) { /** @phpstan-ignore-line */ - abstract class FlasherConfiguration - { - /** - * @return string - */ - abstract protected function getFlasherConfigTreeBuilder(); - } -} diff --git a/src/Symfony/Bridge/DependencyInjection/FlasherExtension.php b/src/Symfony/Bridge/DependencyInjection/FlasherExtension.php deleted file mode 100644 index 2eec4ad4..00000000 --- a/src/Symfony/Bridge/DependencyInjection/FlasherExtension.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\DependencyInjection; - -use Flasher\Symfony\Bridge\Bridge; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; - -$class = Bridge::isLegacy() - ? 'Flasher\Symfony\Bridge\Legacy\DependencyInjection\FlasherExtension' - : 'Flasher\Symfony\Bridge\Typed\DependencyInjection\FlasherExtension'; - -class_alias($class, 'Flasher\Symfony\Bridge\DependencyInjection\FlasherExtension'); - -if (false) { /** @phpstan-ignore-line */ - abstract class FlasherExtension extends Extension - { - /** - * @return string - */ - abstract protected function getFlasherAlias(); - } -} diff --git a/src/Symfony/Bridge/FlasherBundle.php b/src/Symfony/Bridge/FlasherBundle.php deleted file mode 100644 index 89c2013e..00000000 --- a/src/Symfony/Bridge/FlasherBundle.php +++ /dev/null @@ -1,37 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; - -$class = Bridge::isLegacy() - ? 'Flasher\Symfony\Bridge\Legacy\FlasherBundle' - : 'Flasher\Symfony\Bridge\Typed\FlasherBundle'; - -class_alias($class, 'Flasher\Symfony\Bridge\FlasherBundle'); - -if (false) { /** @phpstan-ignore-line */ - abstract class FlasherBundle - { - /** - * @return void - */ - protected function flasherBuild(ContainerBuilder $container) - { - } - - /** - * @return ?ExtensionInterface - */ - protected function getFlasherContainerExtension() - { - return null; - } - } -} diff --git a/src/Symfony/Bridge/Legacy/Command/FlasherCommand.php b/src/Symfony/Bridge/Legacy/Command/FlasherCommand.php deleted file mode 100644 index 19ab6010..00000000 --- a/src/Symfony/Bridge/Legacy/Command/FlasherCommand.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Legacy\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -abstract class FlasherCommand extends Command -{ - protected function execute(InputInterface $input, OutputInterface $output) - { - return $this->flasherExecute($input, $output); - } - - /** - * @return int - */ - abstract protected function flasherExecute(InputInterface $input, OutputInterface $output); -} diff --git a/src/Symfony/Bridge/Legacy/DependencyInjection/FlasherConfiguration.php b/src/Symfony/Bridge/Legacy/DependencyInjection/FlasherConfiguration.php deleted file mode 100644 index ec43c696..00000000 --- a/src/Symfony/Bridge/Legacy/DependencyInjection/FlasherConfiguration.php +++ /dev/null @@ -1,24 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Legacy\DependencyInjection; - -use Symfony\Component\Config\Definition\Builder\TreeBuilder; -use Symfony\Component\Config\Definition\ConfigurationInterface; - -abstract class FlasherConfiguration implements ConfigurationInterface -{ - public function getConfigTreeBuilder() - { - return $this->getFlasherConfigTreeBuilder(); - } - - /** - * @return TreeBuilder - */ - abstract public function getFlasherConfigTreeBuilder(); -} diff --git a/src/Symfony/Bridge/Legacy/DependencyInjection/FlasherExtension.php b/src/Symfony/Bridge/Legacy/DependencyInjection/FlasherExtension.php deleted file mode 100644 index 77ccd90a..00000000 --- a/src/Symfony/Bridge/Legacy/DependencyInjection/FlasherExtension.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Legacy\DependencyInjection; - -use Symfony\Component\HttpKernel\DependencyInjection\Extension; - -abstract class FlasherExtension extends Extension -{ - /** - * {@inheritdoc} - */ - public function getAlias() - { - return $this->getFlasherAlias(); - } - - /** - * @return string - */ - abstract protected function getFlasherAlias(); -} diff --git a/src/Symfony/Bridge/Legacy/FlasherBundle.php b/src/Symfony/Bridge/Legacy/FlasherBundle.php deleted file mode 100644 index c71c846b..00000000 --- a/src/Symfony/Bridge/Legacy/FlasherBundle.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Legacy; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -use Symfony\Component\HttpKernel\Bundle\Bundle; - -abstract class FlasherBundle extends Bundle -{ - /** - * {@inheritdoc} - */ - public function build(ContainerBuilder $container) - { - $this->flasherBuild($container); - } - - /** - * {@inheritdoc} - */ - public function getContainerExtension() - { - return $this->getFlasherContainerExtension(); - } - - /** - * @return void - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - protected function flasherBuild(ContainerBuilder $container) - { - } - - /** - * @return ?ExtensionInterface - */ - abstract protected function getFlasherContainerExtension(); -} diff --git a/src/Symfony/Bridge/Legacy/Twig/FlasherTwigExtension.php b/src/Symfony/Bridge/Legacy/Twig/FlasherTwigExtension.php deleted file mode 100644 index e1bd20e1..00000000 --- a/src/Symfony/Bridge/Legacy/Twig/FlasherTwigExtension.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Legacy\Twig; - -use Twig\Extension\AbstractExtension; -use Twig\TwigFunction; - -abstract class FlasherTwigExtension extends AbstractExtension -{ - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return $this->getFlasherFunctions(); - } - - /** - * @return TwigFunction[] - */ - abstract protected function getFlasherFunctions(); -} diff --git a/src/Symfony/Bridge/Twig/FlasherTwigExtension.php b/src/Symfony/Bridge/Twig/FlasherTwigExtension.php deleted file mode 100644 index 7d3e6c0d..00000000 --- a/src/Symfony/Bridge/Twig/FlasherTwigExtension.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Twig; - -use Flasher\Symfony\Bridge\Bridge; -use Twig\TwigFunction; - -$class = Bridge::isLegacy() - ? 'Flasher\Symfony\Bridge\Legacy\Twig\FlasherTwigExtension' - : 'Flasher\Symfony\Bridge\Typed\Twig\FlasherTwigExtension'; - -class_alias($class, 'Flasher\Symfony\Bridge\Twig\FlasherTwigExtension'); - -if (false) { /** @phpstan-ignore-line */ - abstract class FlasherTwigExtension - { - /** - * @return TwigFunction[] - */ - abstract protected function getFlasherFunctions(); - } -} diff --git a/src/Symfony/Bridge/Typed/Command/FlasherCommand.php b/src/Symfony/Bridge/Typed/Command/FlasherCommand.php deleted file mode 100644 index 50e99ddb..00000000 --- a/src/Symfony/Bridge/Typed/Command/FlasherCommand.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Typed\Command; - -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -abstract class FlasherCommand extends Command -{ - protected function execute(InputInterface $input, OutputInterface $output): int - { - return $this->flasherExecute($input, $output); - } - - /** - * @return int - */ - abstract protected function flasherExecute(InputInterface $input, OutputInterface $output); -} diff --git a/src/Symfony/Bridge/Typed/DependencyInjection/FlasherConfiguration.php b/src/Symfony/Bridge/Typed/DependencyInjection/FlasherConfiguration.php deleted file mode 100644 index bca3f45d..00000000 --- a/src/Symfony/Bridge/Typed/DependencyInjection/FlasherConfiguration.php +++ /dev/null @@ -1,24 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Typed\DependencyInjection; - -use Symfony\Component\Config\Definition\Builder\TreeBuilder; -use Symfony\Component\Config\Definition\ConfigurationInterface; - -abstract class FlasherConfiguration implements ConfigurationInterface -{ - public function getConfigTreeBuilder(): TreeBuilder - { - return $this->getFlasherConfigTreeBuilder(); - } - - /** - * @return TreeBuilder - */ - abstract public function getFlasherConfigTreeBuilder(); -} diff --git a/src/Symfony/Bridge/Typed/DependencyInjection/FlasherExtension.php b/src/Symfony/Bridge/Typed/DependencyInjection/FlasherExtension.php deleted file mode 100644 index d0fc1bba..00000000 --- a/src/Symfony/Bridge/Typed/DependencyInjection/FlasherExtension.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Typed\DependencyInjection; - -use Symfony\Component\HttpKernel\DependencyInjection\Extension; - -abstract class FlasherExtension extends Extension -{ - /** - * {@inheritdoc} - */ - public function getAlias(): string - { - return $this->getFlasherAlias(); - } - - /** - * @return string - */ - abstract protected function getFlasherAlias(); -} diff --git a/src/Symfony/Bridge/Typed/FlasherBundle.php b/src/Symfony/Bridge/Typed/FlasherBundle.php deleted file mode 100644 index f259bf97..00000000 --- a/src/Symfony/Bridge/Typed/FlasherBundle.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Typed; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -use Symfony\Component\HttpKernel\Bundle\Bundle; - -abstract class FlasherBundle extends Bundle -{ - /** - * {@inheritdoc} - * - * @return void - */ - public function build(ContainerBuilder $container) - { - $this->flasherBuild($container); - } - - /** - * {@inheritdoc} - */ - public function getContainerExtension(): ?ExtensionInterface - { - return $this->getFlasherContainerExtension(); - } - - /** - * @return void - * - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - protected function flasherBuild(ContainerBuilder $container) - { - } - - /** - * @return ?ExtensionInterface - */ - abstract protected function getFlasherContainerExtension(); -} diff --git a/src/Symfony/Bridge/Typed/Twig/FlasherTwigExtension.php b/src/Symfony/Bridge/Typed/Twig/FlasherTwigExtension.php deleted file mode 100644 index a71547d6..00000000 --- a/src/Symfony/Bridge/Typed/Twig/FlasherTwigExtension.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Flasher\Symfony\Bridge\Typed\Twig; - -use Twig\Extension\AbstractExtension; - -abstract class FlasherTwigExtension extends AbstractExtension -{ - /** - * {@inheritdoc} - */ - public function getFunctions(): array - { - return $this->getFlasherFunctions(); - } - - /** - * @return array - */ - abstract protected function getFlasherFunctions(); -} diff --git a/src/Symfony/Command/InstallCommand.php b/src/Symfony/Command/InstallCommand.php index 65ff4e14..e3e9c006 100644 --- a/src/Symfony/Command/InstallCommand.php +++ b/src/Symfony/Command/InstallCommand.php @@ -1,40 +1,39 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\Command; +use Flasher\Prime\Asset\AssetManagerInterface; use Flasher\Prime\Plugin\PluginInterface; -use Flasher\Symfony\Bridge\Bridge; -use Flasher\Symfony\Bridge\Command\FlasherCommand; -use Flasher\Symfony\Support\Bundle; +use Flasher\Symfony\Support\PluginBundleInterface; +use Symfony\Bundle\FrameworkBundle\Console\Application; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\DependencyInjection\Container; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpKernel\KernelInterface; -class InstallCommand extends FlasherCommand +final class InstallCommand extends Command { - /** - * @return void - */ - protected function configure() + public function __construct(private readonly AssetManagerInterface $assetManager) + { + parent::__construct(); + } + + protected function configure(): void { $this ->setName('flasher:install') ->setDescription('Installs all PHPFlasher resources to the public and config directories.') - ->setHelp('The command copies PHPFlasher assets to public/vendor/flasher/ directory and config files to the config/packages/ directory without overwriting any existing config files.'); + ->setHelp('The command copies PHPFlasher assets to public/vendor/flasher/ directory and config files to the config/packages/ directory without overwriting any existing config files.') + ->addOption('config', 'c', InputOption::VALUE_NONE, 'Publish all config files to the config/packages/ directory.') + ->addOption('symlink', 's', InputOption::VALUE_NONE, 'Symlink PHPFlasher assets instead of copying them.'); } - /** - * @return int - */ - protected function flasherExecute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln(''); $output->writeln(' @@ -51,14 +50,36 @@ class InstallCommand extends FlasherCommand $output->writeln(' INFO Copying PHPFlasher resources...'); $output->writeln(''); + $application = $this->getApplication(); + if (!$application instanceof Application) { + return self::SUCCESS; + } + + $useSymlinks = (bool) $input->getOption('symlink'); + if ($useSymlinks) { + $output->writeln('Using symlinks to publish assets.'); + } else { + $output->writeln('Copying assets to the public directory.'); + } + + $publishConfig = (bool) $input->getOption('config'); + if ($publishConfig) { + $output->writeln('Publishing configuration files.'); + } + $publicDir = $this->getPublicDir().'/vendor/flasher/'; $configDir = $this->getConfigDir(); - $exitCode = 0; - /** @var KernelInterface $kernel */ - $kernel = $this->getApplication()->getKernel(); + $filesystem = new Filesystem(); + $filesystem->remove($publicDir); + $filesystem->mkdir($publicDir); + + $files = []; + $exitCode = self::SUCCESS; + + $kernel = $application->getKernel(); foreach ($kernel->getBundles() as $bundle) { - if (!$bundle instanceof Bundle) { + if (!$bundle instanceof PluginBundleInterface) { continue; } @@ -66,13 +87,16 @@ class InstallCommand extends FlasherCommand $configFile = $bundle->getConfigurationFile(); try { - $this->publishAssets($plugin, $publicDir); - $this->publishConfig($plugin, $configDir, $configFile); + $files[] = $this->publishAssets($plugin, $publicDir, $useSymlinks); + + if ($publishConfig) { + $this->publishConfig($plugin, $configDir, $configFile); + } $status = sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */); $output->writeln(sprintf(' %s %s', $status, $plugin->getAlias())); } catch (\Exception $e) { - $exitCode = 1; + $exitCode = self::FAILURE; $status = sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */); $output->writeln(sprintf(' %s %s %s', $status, $plugin->getAlias(), $e->getMessage())); } @@ -80,46 +104,60 @@ class InstallCommand extends FlasherCommand $output->writeln(''); - if (0 === $exitCode) { - $output->writeln(' SUCCESS PHPFlasher resources have been successfully installed.'); + if (self::SUCCESS === $exitCode) { + $message = 'PHPFlasher resources have been successfully installed.'; + if ($publishConfig) { + $message .= ' Configuration files have been published.'; + } + if ($useSymlinks) { + $message .= ' Assets were symlinked.'; + } + $output->writeln(" SUCCESS $message"); } else { $output->writeln(' ERROR An error occurred during the installation of PHPFlasher resources.'); } + $this->assetManager->createManifest(array_merge([], ...$files)); + $output->writeln(''); return $exitCode; } /** - * @param string|null $publicDir - * - * @return void + * @return string[] */ - private function publishAssets(PluginInterface $plugin, $publicDir) + private function publishAssets(PluginInterface $plugin, string $publicDir, bool $useSymlinks): array { - if (null === $publicDir) { - return; - } - $originDir = $plugin->getAssetsDir(); if (!is_dir($originDir)) { - return; + return []; } $filesystem = new Filesystem(); - $filesystem->mkdir($originDir, 0777); - $filesystem->mirror($originDir, $publicDir, Finder::create()->ignoreDotFiles(false)->in($originDir)); + $finder = new Finder(); + $finder->files()->in($originDir); + + $files = []; + + foreach ($finder as $file) { + $relativePath = trim(str_replace($originDir, '', $file->getRealPath()), \DIRECTORY_SEPARATOR); + $targetPath = $publicDir.$relativePath; + + if ($useSymlinks) { + $filesystem->symlink($file->getRealPath(), $targetPath); + } else { + $filesystem->copy($file->getRealPath(), $targetPath, true); + } + + $files[] = $targetPath; + } + + return $files; } - /** - * @param string|null $configDir - * @param string $configFile - * - * @return void - */ - private function publishConfig(PluginInterface $plugin, $configDir, $configFile) + private function publishConfig(PluginInterface $plugin, ?string $configDir, string $configFile): void { if (null === $configDir || !file_exists($configFile)) { return; @@ -134,15 +172,14 @@ class InstallCommand extends FlasherCommand $filesystem->copy($configFile, $target); } - /** - * @return string|null - */ - private function getPublicDir() + private function getPublicDir(): ?string { $projectDir = $this->getProjectDir(); + if (null === $projectDir) { + return null; + } - $publicDir = Bridge::versionCompare('4', '>=') ? '/public' : '/web'; - $publicDir = rtrim($projectDir, '/').$publicDir; + $publicDir = rtrim($projectDir, '/').'/public'; if (is_dir($publicDir)) { return $publicDir; @@ -151,15 +188,15 @@ class InstallCommand extends FlasherCommand return $this->getComposerDir('public-dir'); } - /** - * @return string|null - */ - private function getConfigDir() + private function getConfigDir(): ?string { $projectDir = $this->getProjectDir(); - $configDir = Bridge::versionCompare('4', '>=') ? '/config/packages/' : '/config'; - $configDir = rtrim($projectDir, '/').$configDir; + if (null === $projectDir) { + return null; + } + + $configDir = rtrim($projectDir, '/').'/config/packages/'; if (is_dir($configDir)) { return $configDir; @@ -168,34 +205,49 @@ class InstallCommand extends FlasherCommand return $this->getComposerDir('config-dir'); } - /** - * @return string - */ - private function getProjectDir() + private function getProjectDir(): ?string { - /** @var Container $container */ - $container = $this->getApplication()->getKernel()->getContainer(); + $kernel = $this->getKernel(); - return $container->hasParameter('kernel.project_dir') - ? $container->getParameter('kernel.project_dir') - : $container->getParameter('kernel.root_dir').'/../'; + if (null === $kernel) { + return null; + } + + $container = $kernel->getContainer(); + + $projectDir = $container->getParameter('kernel.project_dir'); + + return \is_string($projectDir) ? $projectDir : null; } - /** - * @return string|null - */ - private function getComposerDir($dir) + private function getComposerDir(string $dir): ?string { $projectDir = $this->getProjectDir(); + if (null === $projectDir) { + return null; + } + $composerFilePath = $projectDir.'/composer.json'; if (!file_exists($composerFilePath)) { return null; } - $composerConfig = json_decode(file_get_contents($composerFilePath), true); + /** @var array{extra: array{string, string}} $composerConfig */ + $composerConfig = json_decode(file_get_contents($composerFilePath) ?: '', true); - return isset($composerConfig['extra'][$dir]) ? $composerConfig['extra'][$dir] : null; + return $composerConfig['extra'][$dir] ?? null; + } + + private function getKernel(): ?KernelInterface + { + $application = $this->getApplication(); + + if (!$application instanceof Application) { + return null; + } + + return $application->getKernel(); } } diff --git a/src/Symfony/Component/FlasherComponent.php b/src/Symfony/Component/FlasherComponent.php new file mode 100644 index 00000000..b97d35d1 --- /dev/null +++ b/src/Symfony/Component/FlasherComponent.php @@ -0,0 +1,16 @@ + */ + public array $criteria = []; + + public string $presenter = 'html'; + + /** @var array */ + public array $context = []; +} diff --git a/src/Symfony/Container/SymfonyContainer.php b/src/Symfony/Container/SymfonyContainer.php deleted file mode 100644 index b46048df..00000000 --- a/src/Symfony/Container/SymfonyContainer.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ - -namespace Flasher\Symfony\Container; - -use Flasher\Prime\Container\ContainerInterface; -use Symfony\Component\DependencyInjection\ContainerInterface as BaseSymfonyContainer; - -final class SymfonyContainer implements ContainerInterface -{ - /** @var BaseSymfonyContainer */ - private $container; - - public function __construct(BaseSymfonyContainer $container) - { - $this->container = $container; - } - - /** - * {@inheritDoc} - */ - public function get($id) - { - return $this->container->get($id); - } -} diff --git a/src/Symfony/DependencyInjection/Compiler/EventListenerCompilerPass.php b/src/Symfony/DependencyInjection/Compiler/EventListenerCompilerPass.php new file mode 100644 index 00000000..3f90aa2c --- /dev/null +++ b/src/Symfony/DependencyInjection/Compiler/EventListenerCompilerPass.php @@ -0,0 +1,21 @@ +findDefinition('flasher.event_dispatcher'); + + foreach (array_keys($container->findTaggedServiceIds('flasher.event_listener')) as $id) { + $definition->addMethodCall('addListener', [new Reference($id)]); + } + } +} diff --git a/src/Symfony/DependencyInjection/Compiler/EventSubscriberCompilerPass.php b/src/Symfony/DependencyInjection/Compiler/EventSubscriberCompilerPass.php deleted file mode 100644 index 1efdfebc..00000000 --- a/src/Symfony/DependencyInjection/Compiler/EventSubscriberCompilerPass.php +++ /dev/null @@ -1,34 +0,0 @@ - - */ - -namespace Flasher\Symfony\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; - -/** - * @SuppressWarnings(PHPMD.UnusedLocalVariable) - */ -final class EventSubscriberCompilerPass implements CompilerPassInterface -{ - /** - * @return void - */ - public function process(ContainerBuilder $container) - { - if (!$container->has('flasher.event_dispatcher')) { - return; - } - - $definition = $container->findDefinition('flasher.event_dispatcher'); - - foreach ($container->findTaggedServiceIds('flasher.event_subscriber') as $id => $tags) { - $definition->addMethodCall('addSubscriber', array(new Reference($id))); - } - } -} diff --git a/src/Symfony/DependencyInjection/Compiler/FactoryCompilerPass.php b/src/Symfony/DependencyInjection/Compiler/FactoryCompilerPass.php deleted file mode 100644 index dd11d1c1..00000000 --- a/src/Symfony/DependencyInjection/Compiler/FactoryCompilerPass.php +++ /dev/null @@ -1,33 +0,0 @@ - - */ - -namespace Flasher\Symfony\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; - -final class FactoryCompilerPass implements CompilerPassInterface -{ - /** - * @return void - */ - public function process(ContainerBuilder $container) - { - if (!$container->has('flasher')) { - return; - } - - $definition = $container->findDefinition('flasher'); - - foreach ($container->findTaggedServiceIds('flasher.factory') as $id => $tags) { - foreach ($tags as $attributes) { - $definition->addMethodCall('addFactory', array($attributes['alias'], new Reference($id))); - } - } - } -} diff --git a/src/Symfony/DependencyInjection/Compiler/FlasherAwareCompilerPass.php b/src/Symfony/DependencyInjection/Compiler/FlasherAwareCompilerPass.php deleted file mode 100644 index 278d7b8d..00000000 --- a/src/Symfony/DependencyInjection/Compiler/FlasherAwareCompilerPass.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - -namespace Flasher\Symfony\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -final class FlasherAwareCompilerPass implements CompilerPassInterface -{ - /** - * @return void - */ - public function process(ContainerBuilder $container) - { - if (!$container->has('flasher')) { - return; - } - - $flasher = $container->findDefinition('flasher'); - - foreach ($container->findTaggedServiceIds('flasher.flasher_aware') as $id => $tags) { - $service = $container->findDefinition($id); - $service->addMethodCall('setFlasher', array($flasher)); - } - } -} diff --git a/src/Symfony/DependencyInjection/Compiler/PresenterCompilerPass.php b/src/Symfony/DependencyInjection/Compiler/PresenterCompilerPass.php index 915253bc..c76c20f6 100644 --- a/src/Symfony/DependencyInjection/Compiler/PresenterCompilerPass.php +++ b/src/Symfony/DependencyInjection/Compiler/PresenterCompilerPass.php @@ -1,32 +1,26 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; final class PresenterCompilerPass implements CompilerPassInterface { - /** - * @return void - */ - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { - if (!$container->has('flasher.response_manager')) { - return; - } - $definition = $container->findDefinition('flasher.response_manager'); foreach ($container->findTaggedServiceIds('flasher.presenter') as $id => $tags) { foreach ($tags as $attributes) { - $definition->addMethodCall('addPresenter', array($attributes['alias'], new Reference($id))); + $definition->addMethodCall('addPresenter', [ + $attributes['alias'], + new ServiceClosureArgument(new Reference($id)), + ]); } } } diff --git a/src/Symfony/DependencyInjection/Configuration.php b/src/Symfony/DependencyInjection/Configuration.php index 1f55200b..a5b060dc 100644 --- a/src/Symfony/DependencyInjection/Configuration.php +++ b/src/Symfony/DependencyInjection/Configuration.php @@ -1,139 +1,133 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\DependencyInjection; use Flasher\Prime\Plugin\FlasherPlugin; -use Flasher\Symfony\Bridge\DependencyInjection\FlasherConfiguration; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; -final class Configuration extends FlasherConfiguration +final readonly class Configuration implements ConfigurationInterface { - /** - * @return TreeBuilder - */ - public function getFlasherConfigTreeBuilder() + public function __construct(private FlasherPlugin $plugin) { - $plugin = new FlasherPlugin(); + } - $treeBuilder = new TreeBuilder($plugin->getName()); + public function getConfigTreeBuilder(): TreeBuilder + { + $treeBuilder = new TreeBuilder($this->plugin->getName()); + $rootNode = $treeBuilder->getRootNode(); - $rootNode = method_exists($treeBuilder, 'getRootNode') - ? $treeBuilder->getRootNode() - : $treeBuilder->root($plugin->getName()); // @phpstan-ignore-line + $this->normalizeConfig($rootNode); - $rootNode - ->beforeNormalization() - ->always(function ($v) use ($plugin) { - return $plugin->normalizeConfig($v); - }) - ->end() - ->children() - ->scalarNode('default') - ->cannotBeEmpty() - ->defaultValue($plugin->getDefault()) - ->end() - ->arrayNode('root_script') - ->prototype('scalar')->end() - ->defaultValue($plugin->getRootScript()) - ->end() - ->arrayNode('scripts') - ->prototype('variable')->end() - ->end() - ->arrayNode('styles') - ->prototype('variable')->end() - ->defaultValue($plugin->getStyles()) - ->end() - ->arrayNode('options') - ->prototype('scalar')->end() - ->end() - ->booleanNode('use_cdn')->defaultTrue()->end() - ->booleanNode('auto_translate')->defaultTrue()->end() - ->booleanNode('auto_render')->defaultTrue()->end() - ->arrayNode('filter_criteria') - ->prototype('scalar')->end() - ->end() - ->end() - ; - - $this->addThemesSection($rootNode); - $this->addFlashBagSection($rootNode, $plugin); + $this->addGeneralSection($rootNode); + $this->addFlashBagSection($rootNode); $this->addPresetsSection($rootNode); + $this->addPluginsSection($rootNode); return $treeBuilder; } - /** - * @return void - */ - private function addThemesSection(ArrayNodeDefinition $rootNode) + private function normalizeConfig(ArrayNodeDefinition $rootNode): void { - $rootNode // @phpstan-ignore-line - ->children() - ->arrayNode('themes') - ->ignoreExtraKeys() - ->prototype('variable')->end() - ->children() - ->scalarNode('view') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->arrayNode('styles')->end() - ->arrayNode('scripts')->end() - ->arrayNode('options')->end() - ->end() - ->end() - ->end() - ; + $rootNode + ->beforeNormalization() + ->always(fn ($v): array => $this->plugin->normalizeConfig($v)) + ->end(); } - /** - * @return void - */ - private function addFlashBagSection(ArrayNodeDefinition $rootNode, FlasherPlugin $plugin) + private function addGeneralSection(ArrayNodeDefinition $rootNode): void { - $rootNode // @phpstan-ignore-line + $rootNode ->children() - ->arrayNode('flash_bag') - ->canBeUnset() - ->addDefaultsIfNotSet() - ->children() - ->booleanNode('enabled')->defaultTrue()->end() - ->arrayNode('mapping') - ->prototype('variable')->end() - ->defaultValue($plugin->getFlashBagMapping()) - ->end() - ->end() + ->scalarNode('default') + ->isRequired() + ->cannotBeEmpty() + ->defaultValue($this->plugin->getDefault()) ->end() - ->end() - ; + ->scalarNode('main_script') + ->defaultValue($this->plugin->getRootScript()) + ->end() + ->booleanNode('translate') + ->defaultTrue() + ->end() + ->booleanNode('inject_assets') + ->defaultTrue() + ->end() + ->arrayNode('filter') + ->variablePrototype()->end() + ->end() + ->arrayNode('scripts') + ->performNoDeepMerging() + ->scalarPrototype()->end() + ->end() + ->arrayNode('styles') + ->performNoDeepMerging() + ->scalarPrototype()->end() + ->end() + ->arrayNode('options') + ->variablePrototype()->end() + ->end() + ->end(); } - /** - * @return void - */ - private function addPresetsSection(ArrayNodeDefinition $rootNode) + private function addFlashBagSection(ArrayNodeDefinition $rootNode): void { - $rootNode // @phpstan-ignore-line + $rootNode + ->children() + ->variableNode('flash_bag') + ->defaultTrue() + ->end() + ->end(); + } + + private function addPresetsSection(ArrayNodeDefinition $rootNode): void + { + $rootNode + ->fixXmlConfig('preset') ->children() ->arrayNode('presets') - ->prototype('array') - ->children() - ->scalarNode('type')->end() - ->scalarNode('title')->end() - ->scalarNode('message')->end() - ->arrayNode('options') - ->useAttributeAsKey('name') - ->prototype('variable')->end() + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('type')->end() + ->scalarNode('title')->end() + ->scalarNode('message')->end() + ->arrayNode('options') + ->variablePrototype()->end() + ->end() ->end() ->end() ->end() - ->end() - ; + ->end(); + } + + private function addPluginsSection(ArrayNodeDefinition $rootNode): void + { + $rootNode + ->fixXmlConfig('plugin') + ->children() + ->arrayNode('plugins') + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('view')->end() + ->arrayNode('styles') + ->performNoDeepMerging() + ->scalarPrototype()->end() + ->end() + ->arrayNode('scripts') + ->performNoDeepMerging() + ->scalarPrototype()->end() + ->end() + ->arrayNode('options') + ->variablePrototype()->end() + ->end() + ->end() + ->end() + ->end() + ->end(); } } diff --git a/src/Symfony/DependencyInjection/FlasherExtension.php b/src/Symfony/DependencyInjection/FlasherExtension.php index c212f0de..7e5b6a04 100644 --- a/src/Symfony/DependencyInjection/FlasherExtension.php +++ b/src/Symfony/DependencyInjection/FlasherExtension.php @@ -1,235 +1,141 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\DependencyInjection; -use Flasher\Prime\Config\ConfigInterface; -use Flasher\Symfony\Bridge\Bridge; -use Symfony\Component\Config\FileLocator; +use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface; +use Flasher\Prime\Plugin\FlasherPlugin; +use Flasher\Prime\Storage\Bag\ArrayBag; +use Flasher\Symfony\Attribute\AsFlasherFactory; +use Flasher\Symfony\Attribute\AsFlasherPresenter; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Extension\AbstractExtension; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -/** - * @phpstan-import-type ConfigType from ConfigInterface - */ -final class FlasherExtension extends Extension implements CompilerPassInterface +final class FlasherExtension extends AbstractExtension implements CompilerPassInterface { - /** - * @phpstan-param ConfigType[] $configs - * - * @return void - */ - public function load(array $configs, ContainerBuilder $container) + public function __construct(private readonly FlasherPlugin $plugin) { - $loader = new Loader\PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); - $loader->load('services.php'); + } - /** @var ConfigType $config */ - $config = $this->processConfiguration(new Configuration(), $configs); - - $this->registerFlasherConfiguration($config, $container); - $this->registerListeners($config, $container); - $this->registerStorageManager($config, $container); - $this->registerHttpExtensions($config, $container); - $this->registerFlasherAutoConfiguration($container); + public function getAlias(): string + { + return $this->plugin->getName(); } /** - * @return void + * @param array $config */ - public function process(ContainerBuilder $container) + public function getConfiguration(array $config, ContainerBuilder $container): ConfigurationInterface + { + return new Configuration($this->plugin); + } + + /** + * @param array{ + * default: string, + * main_script: string, + * inject_assets: bool, + * presets: array, + * flash_bag: array, + * filter: array, + * plugins: array>, + * } $config + */ + public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void + { + $this->registerFlasherParameters($config, $container, $builder); + $this->registerServicesForAutoconfiguration($builder); + + $container->import(__DIR__.'/../Resources/config/services.php'); + } + + public function process(ContainerBuilder $container): void { $this->registerFlasherTranslator($container); - $this->registerFlasherTemplateEngine($container); $this->configureSessionServices($container); + $this->configureFlasherListener($container); } /** - * @phpstan-param ConfigType $config - * - * @return void + * @param array{ + * default: string, + * main_script: string, + * inject_assets: bool, + * presets: array, + * flash_bag: array, + * filter: array, + * plugins: array>, + * } $config */ - private function registerFlasherConfiguration(array $config, ContainerBuilder $container) + private function registerFlasherParameters(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void { - $flasherConfig = $container->getDefinition('flasher.config'); - $flasherConfig->replaceArgument(0, $config); + /** @var string $projectDir */ + $projectDir = $builder->getParameter('kernel.project_dir'); + $publicDir = $projectDir.\DIRECTORY_SEPARATOR.'public'; + $assetsDir = $publicDir.\DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR.'flasher'; + $manifestPath = $assetsDir.\DIRECTORY_SEPARATOR.'manifest.json'; - $flasher = $container->getDefinition('flasher'); - $flasher->replaceArgument(0, $config['default']); - - $presetListener = $container->getDefinition('flasher.preset_listener'); - $presetListener->replaceArgument(0, $config['presets']); + $container->parameters() + ->set('flasher', $config) + ->set('flasher.public_dir', $publicDir) + ->set('flasher.assets_dir', $assetsDir) + ->set('flasher.json_manifest_path', $manifestPath) + ->set('flasher.default', $config['default']) + ->set('flasher.main_script', $config['main_script']) + ->set('flasher.inject_assets', $config['inject_assets']) + ->set('flasher.flash_bag', $config['flash_bag']) + ->set('flasher.filter', $config['filter']) + ->set('flasher.presets', $config['presets']) + ->set('flasher.plugins', $config['plugins']) + ; } - /** - * @phpstan-param ConfigType $config - * - * @return void - */ - private function registerListeners(array $config, ContainerBuilder $container) + private function registerServicesForAutoconfiguration(ContainerBuilder $builder): void { - $this->registerSessionListener($config, $container); - $this->registerFlasherListener($config, $container); + $builder->registerForAutoconfiguration(EventListenerInterface::class) + ->addTag('flasher.event_listener'); + + $builder->registerAttributeForAutoconfiguration(AsFlasherFactory::class, static function (ChildDefinition $definition, AsFlasherFactory $attribute): void { + $definition->addTag('flasher.factory', get_object_vars($attribute)); + }); + + $builder->registerAttributeForAutoconfiguration(AsFlasherPresenter::class, static function (ChildDefinition $definition, AsFlasherPresenter $attribute): void { + $definition->addTag('flasher.presenter', get_object_vars($attribute)); + }); } - /** - * @return void - */ - private function registerResponseExtension(ContainerBuilder $container) + private function registerFlasherTranslator(ContainerBuilder $container): void { - $container->register('flasher.response_extension', 'Flasher\Prime\Http\ResponseExtension') - ->setPublic(false) - ->addArgument(new Reference('flasher')); - } - - /** - * @param array $mapping - * - * @return void - */ - private function registerRequestExtension(ContainerBuilder $container, array $mapping) - { - $container->register('flasher.request_extension', 'Flasher\Prime\Http\RequestExtension') - ->setPublic(false) - ->addArgument(new Reference('flasher')) - ->addArgument($mapping); - } - - /** - * @phpstan-param ConfigType $config - * - * @return void - */ - private function registerSessionListener(array $config, ContainerBuilder $container) - { - if (!$config['flash_bag']['enabled']) { - return; - } - - $container->register('flasher.session_listener', 'Flasher\Symfony\EventListener\SessionListener') - ->setPublic(true) - ->addArgument(new Reference('flasher.request_extension')) - ->addTag('kernel.event_listener', array('event' => 'kernel.response')); - } - - /** - * @phpstan-param ConfigType $config - * - * @return void - */ - private function registerFlasherListener(array $config, ContainerBuilder $container) - { - if (!$config['auto_render']) { - return; - } - - $container->register('flasher.flasher_listener', 'Flasher\Symfony\EventListener\FlasherListener') - ->setPublic(true) - ->addArgument(new Reference('flasher.response_extension')) - ->addTag('kernel.event_listener', array('event' => 'kernel.response', 'priority' => -256)); - } - - /** - * @phpstan-param ConfigType $config - * - * @return void - */ - private function registerStorageManager(array $config, ContainerBuilder $container) - { - $criteria = $config['filter_criteria']; - $storageManager = $container->getDefinition('flasher.storage_manager'); - $storageManager->replaceArgument(2, $criteria); - } - - /** - * @return void - */ - private function registerHttpExtensions(array $config, ContainerBuilder $container) - { - $mapping = $config['flash_bag']['mapping']; - $this->registerRequestExtension($container, $mapping); - - $this->registerResponseExtension($container); - } - - /** - * @return void - */ - private function registerFlasherAutoConfiguration(ContainerBuilder $container) - { - if (!method_exists($container, 'registerForAutoconfiguration')) { - return; - } - - $container - ->registerForAutoconfiguration('Flasher\Prime\Aware\FlasherAwareInterface') - ->addTag('flasher.flasher_aware'); - } - - /** - * @return void - */ - private function registerFlasherTranslator(ContainerBuilder $container) - { - $config = $container->getDefinition('flasher.config')->getArgument(0); - - $translationListener = $container->getDefinition('flasher.translation_listener'); - $translationListener->replaceArgument(1, $config['auto_translate']); // @phpstan-ignore-line - if ($container->has('translator')) { return; } $container->removeDefinition('flasher.translator'); - $translationListener->replaceArgument(0, null); } - /** - * @return void - */ - private function registerFlasherTemplateEngine(ContainerBuilder $container) + private function configureSessionServices(ContainerBuilder $container): void { - if ($container->has('twig')) { + if (!$container->has('session.factory') || false === $container->getParameter('flasher.flash_bag')) { + $container->removeDefinition('flasher.session_listener'); + } + + if (!$container->has('session.factory')) { + $container->removeDefinition('flasher.storage_bag'); + $container->register('flasher.storage_bag', ArrayBag::class); + } + } + + private function configureFlasherListener(ContainerBuilder $container): void + { + if ($container->getParameter('flasher.inject_assets')) { return; } - $container->removeDefinition('flasher.template_engine'); - - $listener = $container->getDefinition('flasher.resource_manager'); - $listener->replaceArgument(1, null); - } - - /** - * @return void - */ - private function configureSessionServices(ContainerBuilder $container) - { - if ($this->isSessionEnabled($container)) { - return; - } - - $container->removeDefinition('flasher.storage_bag'); - $container->removeDefinition('flasher.session_listener'); - - $container->register('flasher.storage_bag', 'Flasher\Prime\Storage\Bag\ArrayBag'); - } - - /** - * @return bool - */ - private function isSessionEnabled(ContainerBuilder $container) - { - if (Bridge::versionCompare('5.3', '>=')) { - return $container->has('session.factory'); - } - - return $container->has('session'); + $container->removeDefinition('flasher.flasher_listener'); } } diff --git a/src/Symfony/EventListener/FlasherListener.php b/src/Symfony/EventListener/FlasherListener.php index ec1dedf6..1aab5149 100644 --- a/src/Symfony/EventListener/FlasherListener.php +++ b/src/Symfony/EventListener/FlasherListener.php @@ -1,39 +1,33 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\EventListener; -use Flasher\Prime\Http\ResponseExtension; +use Flasher\Prime\Http\ResponseExtensionInterface; use Flasher\Symfony\Http\Request; use Flasher\Symfony\Http\Response; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ResponseEvent; -final class FlasherListener +final readonly class FlasherListener implements EventSubscriberInterface { - /** - * @var ResponseExtension - */ - private $responseExtension; - - public function __construct(ResponseExtension $responseExtension) + public function __construct(private ResponseExtensionInterface $responseExtension) { - $this->responseExtension = $responseExtension; } - /** - * @param ResponseEvent $event - * - * @return void - */ - public function onKernelResponse($event) + public function onKernelResponse(ResponseEvent $event): void { $request = new Request($event->getRequest()); $response = new Response($event->getResponse()); $this->responseExtension->render($request, $response); } + + public static function getSubscribedEvents(): array + { + return [ + ResponseEvent::class => ['onKernelResponse', -256], + ]; + } } diff --git a/src/Symfony/EventListener/SessionListener.php b/src/Symfony/EventListener/SessionListener.php index da0b425b..7ad2e64c 100644 --- a/src/Symfony/EventListener/SessionListener.php +++ b/src/Symfony/EventListener/SessionListener.php @@ -1,39 +1,33 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\EventListener; -use Flasher\Prime\Http\RequestExtension; +use Flasher\Prime\Http\RequestExtensionInterface; use Flasher\Symfony\Http\Request; use Flasher\Symfony\Http\Response; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ResponseEvent; -final class SessionListener +final readonly class SessionListener implements EventSubscriberInterface { - /** - * @var RequestExtension - */ - private $requestExtension; - - public function __construct(RequestExtension $requestExtension) + public function __construct(private RequestExtensionInterface $requestExtension) { - $this->requestExtension = $requestExtension; } - /** - * @param ResponseEvent $event - * - * @return void - */ - public function onKernelResponse($event) + public function onKernelResponse(ResponseEvent $event): void { $request = new Request($event->getRequest()); $response = new Response($event->getResponse()); $this->requestExtension->flash($request, $response); } + + public static function getSubscribedEvents(): array + { + return [ + ResponseEvent::class => ['onKernelResponse', 0], + ]; + } } diff --git a/src/Symfony/Factory/NotificationFactoryLocator.php b/src/Symfony/Factory/NotificationFactoryLocator.php new file mode 100644 index 00000000..41d22b82 --- /dev/null +++ b/src/Symfony/Factory/NotificationFactoryLocator.php @@ -0,0 +1,29 @@ + $serviceLocator + */ + public function __construct(private ServiceLocator $serviceLocator) + { + } + + public function has(string $id): bool + { + return $this->serviceLocator->has($id); + } + + public function get(string $id): NotificationFactoryInterface + { + return $this->serviceLocator->get($id); + } +} diff --git a/src/Symfony/FlasherBundle.php b/src/Symfony/FlasherBundle.php new file mode 100644 index 00000000..51d5d4ff --- /dev/null +++ b/src/Symfony/FlasherBundle.php @@ -0,0 +1,40 @@ +container instanceof ContainerInterface) { + FlasherContainer::from($this->container); + } + } + + public function build(ContainerBuilder $container): void + { + $container->addCompilerPass(new EventListenerCompilerPass()); + $container->addCompilerPass(new PresenterCompilerPass()); + } + + public function getContainerExtension(): ExtensionInterface + { + return new FlasherExtension($this->createPlugin()); + } + + public function createPlugin(): FlasherPlugin + { + return new FlasherPlugin(); + } +} diff --git a/src/Symfony/FlasherSymfonyBundle.php b/src/Symfony/FlasherSymfonyBundle.php deleted file mode 100644 index 45c76d43..00000000 --- a/src/Symfony/FlasherSymfonyBundle.php +++ /dev/null @@ -1,57 +0,0 @@ - - */ - -namespace Flasher\Symfony; - -use Flasher\Prime\Container\FlasherContainer; -use Flasher\Prime\Plugin\FlasherPlugin; -use Flasher\Symfony\Container\SymfonyContainer; -use Flasher\Symfony\DependencyInjection\Compiler\EventSubscriberCompilerPass; -use Flasher\Symfony\DependencyInjection\Compiler\FactoryCompilerPass; -use Flasher\Symfony\DependencyInjection\Compiler\FlasherAwareCompilerPass; -use Flasher\Symfony\DependencyInjection\Compiler\PresenterCompilerPass; -use Flasher\Symfony\DependencyInjection\FlasherExtension; -use Flasher\Symfony\Support\Bundle; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -class FlasherSymfonyBundle extends Bundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - /** - * {@inheritdoc} - */ - public function boot() - { - FlasherContainer::init(new SymfonyContainer($this->container)); - } - - /** - * {@inheritDoc} - */ - public function createPlugin() - { - return new FlasherPlugin(); - } - - /** - * {@inheritdoc} - */ - protected function flasherBuild(ContainerBuilder $container) - { - $container->addCompilerPass(new FactoryCompilerPass()); - $container->addCompilerPass(new EventSubscriberCompilerPass()); - $container->addCompilerPass(new PresenterCompilerPass()); - $container->addCompilerPass(new FlasherAwareCompilerPass()); - } - - /** - * {@inheritdoc} - */ - protected function getFlasherContainerExtension() - { - return new FlasherExtension(); - } -} diff --git a/src/Symfony/Http/Request.php b/src/Symfony/Http/Request.php index 5b7af350..f2aa8795 100644 --- a/src/Symfony/Http/Request.php +++ b/src/Symfony/Http/Request.php @@ -1,90 +1,88 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\Http; use Flasher\Prime\Http\RequestInterface; +use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; -use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\FlashBagAwareSessionInterface; +use Symfony\Component\HttpFoundation\Session\SessionInterface; -final class Request implements RequestInterface +final readonly class Request implements RequestInterface { - /** - * @var SymfonyRequest - */ - private $request; - - public function __construct(SymfonyRequest $request) + public function __construct(private SymfonyRequest $request) { - $this->request = $request; } - /** - * {@inheritDoc} - */ - public function isXmlHttpRequest() + public function isXmlHttpRequest(): bool { return $this->request->isXmlHttpRequest(); } - /** - * {@inheritDoc} - */ - public function isHtmlRequestFormat() + public function isHtmlRequestFormat(): bool { return 'html' === $this->request->getRequestFormat(); } - /** - * {@inheritDoc} - */ - public function hasSession() + public function hasSession(): bool { return $this->request->hasSession(); } - /** - * {@inheritDoc} - */ - public function hasType($type) + public function isSessionStarted(): bool { - if (!$this->hasSession()) { + $session = $this->getSession(); + + return $session?->isStarted() ?: false; + } + + public function hasType(string $type): bool + { + if (!$this->hasSession() || !$this->isSessionStarted()) { return false; } - $session = $this->request->getSession(); - if (!$session->isStarted()) { + $session = $this->getSession(); + if (!$session instanceof FlashBagAwareSessionInterface) { return false; } - /** @var Session $session */ - $session = $this->request->getSession(); - $flashBag = $session->getFlashBag(); - - return $flashBag->has($type); + return $session->getFlashBag()->has($type); } - /** - * {@inheritDoc} - */ - public function getType($type) + public function getType(string $type): string|array { - /** @var Session $session */ - $session = $this->request->getSession(); - $flashBag = $session->getFlashBag(); + $session = $this->getSession(); + if (!$session instanceof FlashBagAwareSessionInterface) { + return []; + } - return $flashBag->get($type); + return $session->getFlashBag()->get($type); } - /** - * {@inheritDoc} - */ - public function forgetType($type) + public function forgetType(string $type): void { $this->getType($type); } + + private function getSession(): ?SessionInterface + { + try { + return $this->request->getSession(); + } catch (SessionNotFoundException) { + return null; + } + } + + public function hasHeader(string $key): bool + { + return $this->request->headers->has($key); + } + + public function getHeader(string $key): ?string + { + return $this->request->headers->get($key); + } } diff --git a/src/Symfony/Http/Response.php b/src/Symfony/Http/Response.php index 4ba33b20..edbf3992 100644 --- a/src/Symfony/Http/Response.php +++ b/src/Symfony/Http/Response.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\Http; @@ -11,38 +8,23 @@ use Flasher\Prime\Http\ResponseInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; -final class Response implements ResponseInterface +final readonly class Response implements ResponseInterface { - /** - * @var SymfonyResponse - */ - private $response; - - public function __construct(SymfonyResponse $response) + public function __construct(private SymfonyResponse $response) { - $this->response = $response; } - /** - * {@inheritDoc} - */ - public function isRedirection() + public function isRedirection(): bool { return $this->response->isRedirection(); } - /** - * {@inheritDoc} - */ - public function isJson() + public function isJson(): bool { return $this->response instanceof JsonResponse; } - /** - * {@inheritDoc} - */ - public function isHtml() + public function isHtml(): bool { $contentType = $this->response->headers->get('Content-Type'); @@ -53,10 +35,7 @@ final class Response implements ResponseInterface return false !== stripos($contentType, 'html'); } - /** - * {@inheritDoc} - */ - public function isAttachment() + public function isAttachment(): bool { $contentDisposition = $this->response->headers->get('Content-Disposition', ''); @@ -67,21 +46,38 @@ final class Response implements ResponseInterface return false !== stripos($contentDisposition, 'attachment;'); } - /** - * {@inheritDoc} - */ - public function getContent() + public function isSuccessful(): bool { - $content = $this->response->getContent(); - - return \is_string($content) ? $content : ''; + return $this->response->isSuccessful(); } - /** - * {@inheritDoc} - */ - public function setContent($content) + public function getContent(): string + { + return $this->response->getContent() ?: ''; + } + + public function setContent(string $content): void { $this->response->setContent($content); } + + public function hasHeader(string $key): bool + { + return $this->response->headers->has($key); + } + + public function getHeader(string $key): ?string + { + return $this->response->headers->get($key); + } + + public function setHeader(string $key, array|string|null $values): void + { + $this->response->headers->set($key, $values); + } + + public function removeHeader(string $key): void + { + $this->response->headers->remove($key); + } } diff --git a/src/Symfony/LICENSE b/src/Symfony/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Symfony/LICENSE +++ b/src/Symfony/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Symfony/README.md b/src/Symfony/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Symfony/README.md +++ b/src/Symfony/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
      Younes KHOUBZA
      Younes KHOUBZA

      💻 📖 🚧
      Younes ENNAJI
      Younes ENNAJI

      💻 📖 🚧
      Salma Mourad
      Salma Mourad

      💵
      Nashwan Abdullah
      Nashwan Abdullah

      💵
      Arvid de Jong
      Arvid de Jong

      💵
      - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

      Made with ❤️ by Younes KHOUBZA

      +

      Made with ❤️ by Younes ENNAJI

      diff --git a/src/Symfony/Resources/config/config.yaml b/src/Symfony/Resources/config/config.yaml index b0d1f93e..c2494f6e 100644 --- a/src/Symfony/Resources/config/config.yaml +++ b/src/Symfony/Resources/config/config.yaml @@ -1,173 +1,28 @@ flasher: - # -------------------------------------------------------------------------- - # Default PHPFlasher library - # -------------------------------------------------------------------------- - # This option controls the default library that will be used by PHPFlasher - # to display notifications in your Symfony application. PHPFlasher supports - # several libraries, including "flasher", "toastr", "noty", "notyf", - # "sweetalert" and "pnotify". - # - # The "flasher" library is used by default. If you want to use a different - # library, you will need to install it using composer. For example, to use - # the "toastr" library, run the following command: - # composer require php-flasher/flasher-toastr-symfony - # - # Here is a list of the supported libraries and the corresponding composer - # commands to install them: - # - # "toastr" : composer require php-flasher/flasher-toastr-symfony - # "noty" : composer require php-flasher/flasher-noty-symfony - # "notyf" : composer require php-flasher/flasher-notyf-symfony - # "sweetalert" : composer require php-flasher/flasher-sweetalert-symfony - # "pnotify" : composer require php-flasher/flasher-pnotify-symfony - # + # Default notification library (e.g., 'flasher', 'toastr', 'noty', etc.) default: flasher - # -------------------------------------------------------------------------- - # Main PHPFlasher javascript file - # -------------------------------------------------------------------------- - # This option specifies the location of the main javascript file that is - # required by PHPFlasher to display notifications in your Symfony application. - # - # By default, PHPFlasher uses a CDN to serve the latest version of the library. - # However, you can also choose to download the library locally or install it - # using npm. - # - # To use the local version of the library, run the following command: - # php bin/console flasher:install - # - # This will copy the necessary assets to your application's public folder. - # You can then specify the local path to the javascript file in the 'local' - # field of this option. - # - root_script: - cdn: 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.js' - local: '/vendor/flasher/flasher.min.js' + # Path to the main JavaScript file of PHPFlasher + main_script: '/vendor/flasher/flasher.min.js' - # -------------------------------------------------------------------------- - # PHPFlasher Stylesheet - # -------------------------------------------------------------------------- - # This option specifies the location of the stylesheet file that is - # required by PHPFlasher to style the notifications in your Symfony application. - # - # By default, PHPFlasher uses a CDN to serve the latest version of the stylesheet. - # However, you can also choose to download the stylesheet locally or include it - # from your assets. - # - # To use the local version of the stylesheet, make sure you have the necessary - # assets in your application's public folder. Then specify the local path to - # the stylesheet file in the 'local' field of this option. - # + # Path to the stylesheets for PHPFlasher notifications styles: - cdn: 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.css' - local: '/vendor/flasher/flasher.min.css' + - '/vendor/flasher/flasher.min.css' - # -------------------------------------------------------------------------- - # Whether to use CDN for PHPFlasher assets or not - # -------------------------------------------------------------------------- - # This option controls whether PHPFlasher should use CDN links or local assets - # for its javascript and CSS files. By default, PHPFlasher uses CDN links - # to serve the latest version of the library. However, you can also choose - # to use local assets by setting this option to 'false'. - # - # If you decide to use local assets, don't forget to publish the necessary - # files to your application's public folder by running the following command: - # php bin/console flasher:install - # - # This will copy the necessary assets to your application's public folder. - # - use_cdn: true + # Enable translation of PHPFlasher messages using Symfony's service + translate: true - # -------------------------------------------------------------------------- - # Translate PHPFlasher messages - # -------------------------------------------------------------------------- - # This option controls whether PHPFlasher should pass its messages to the Symfony's - # translation service for localization. - # - # By default, this option is set to 'true', which means that PHPFlasher will - # attempt to translate its messages using the translation service. - # - # If you don't want PHPFlasher to use the Symfony's translation service, you can - # set this option to 'false'. In this case, PHPFlasher will use the messages - # as-is, without attempting to translate them. - # - auto_translate: true - - # -------------------------------------------------------------------------- - # Inject PHPFlasher in Response - # -------------------------------------------------------------------------- - # This option controls whether PHPFlasher should automatically inject its - # javascript and CSS files into the HTML response of your Symfony application. - # - # By default, this option is set to 'true', which means that PHPFlasher will - # listen to the response of your application and automatically insert its - # scripts and stylesheets into the HTML before the closing `` tag. - # - # If you don't want PHPFlasher to automatically inject its scripts and stylesheets - # into the response, you can set this option to 'false'. In this case, you will - # need to manually include the necessary files in your application's layout. - # - auto_render: true + # Automatically inject PHPFlasher assets in HTML response + inject_assets: true + # Map Symfony session keys to PHPFlasher notification types flash_bag: - # ----------------------------------------------------------------------- - # Enable flash bag - # ----------------------------------------------------------------------- - # This option controls whether PHPFlasher should automatically convert - # Symfony's flash messages to PHPFlasher notifications. This feature is - # useful when you want to migrate from a legacy system or another - # library that uses similar conventions for flash messages. - # - # When this option is set to 'true', PHPFlasher will check for flash - # messages in the session and convert them to notifications using the - # mapping specified in the 'mapping' option. When this option is set - # to 'false', PHPFlasher will ignore flash messages in the session. - # - enabled: true + success: ['success'] + error: ['error', 'danger'] + warning: ['warning', 'alarm'] + info: ['info', 'notice', 'alert'] - - # ----------------------------------------------------------------------- - # Flash bag type mapping - # ----------------------------------------------------------------------- - # This option allows you to map or convert session keys to PHPFlasher - # notification types. On the left side are the PHPFlasher types. - # On the right side are the Symfony session keys that you want to - # convert to PHPFlasher types. - # - # For example, if you want to convert Symfony's 'danger' flash - # messages to PHPFlasher's 'error' notifications, you can add - # the following entry to the mapping: - # error: ['danger'], - # - mapping: - success: ['success'] - error: ['error', 'danger'] - warning: ['warning', 'alarm'] - info: ['info', 'notice', 'alert'] - - - # ----------------------------------------------------------------------- - # Global Filter Criteria - # ----------------------------------------------------------------------- - # This option allows you to filter the notifications that are displayed - # in your Symfony application. By default, all notifications are displayed, - # but you can use this option to limit the number of notifications or - # filter them by type. - # - # For example, to limit the number of notifications to 5, you can set - # the 'limit' field to 5: - # limit: 5 - # - # To filter the notifications by type, you can specify an array of - # types that you want to display. For example, to only display - # error notifications, you can set the 'types' field to ['error']: - # types: ['error'], - # - # You can also combine multiple criteria by specifying multiple fields. - # For example, to display up to 5 error notifications, you can set - # the 'limit' and 'types' fields like this: - # limit: 5, - # types: ['error'], - # + # Criteria to filter displayed notifications (limit, types) filter_criteria: + # Limit number of displayed notifications limit: 5 diff --git a/src/Symfony/Resources/config/services.php b/src/Symfony/Resources/config/services.php index f228c7bb..16ab30ea 100644 --- a/src/Symfony/Resources/config/services.php +++ b/src/Symfony/Resources/config/services.php @@ -1,90 +1,149 @@ - */ +declare(strict_types=1); -use Flasher\Symfony\Bridge\Bridge; -use Symfony\Component\DependencyInjection\Reference; +use Flasher\Prime\Asset\AssetManager; +use Flasher\Prime\EventDispatcher\EventDispatcher; +use Flasher\Prime\EventDispatcher\EventListener\ApplyPresetListener; +use Flasher\Prime\EventDispatcher\EventListener\NotificationLoggerListener; +use Flasher\Prime\EventDispatcher\EventListener\TranslationListener; +use Flasher\Prime\Factory\NotificationFactory; +use Flasher\Prime\Flasher; +use Flasher\Prime\FlasherInterface; +use Flasher\Prime\Http\Csp\ContentSecurityPolicyHandler; +use Flasher\Prime\Http\Csp\NonceGenerator; +use Flasher\Prime\Http\RequestExtension; +use Flasher\Prime\Http\ResponseExtension; +use Flasher\Prime\Response\Resource\ResourceManager; +use Flasher\Prime\Response\ResponseManager; +use Flasher\Prime\Storage\Filter\FilterFactory; +use Flasher\Prime\Storage\Storage; +use Flasher\Prime\Storage\StorageManager; +use Flasher\Symfony\Command\InstallCommand; +use Flasher\Symfony\Component\FlasherComponent; +use Flasher\Symfony\EventListener\FlasherListener; +use Flasher\Symfony\EventListener\SessionListener; +use Flasher\Symfony\Factory\NotificationFactoryLocator; +use Flasher\Symfony\Storage\SessionBag; +use Flasher\Symfony\Template\TwigTemplateEngine; +use Flasher\Symfony\Translation\Translator; +use Flasher\Symfony\Twig\FlasherTwigExtension; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -if (!isset($container)) { - return; -} +use function Symfony\Component\DependencyInjection\Loader\Configurator\inline_service; +use function Symfony\Component\DependencyInjection\Loader\Configurator\param; +use function Symfony\Component\DependencyInjection\Loader\Configurator\service; +use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_locator; -$container->register('flasher.config', 'Flasher\Prime\Config\Config') - ->setPublic(false) - ->addArgument(array()); +return static function (ContainerConfigurator $container): void { + $container->services() + ->set('flasher', Flasher::class) + ->public() + ->args([ + param('flasher.default'), + inline_service(NotificationFactoryLocator::class) + ->args([tagged_locator('flasher.factory', indexAttribute: 'alias')]), + service('flasher.response_manager'), + service('flasher.storage_manager'), + ]) + ->alias(FlasherInterface::class, 'flasher') -$storage = Bridge::versionCompare('5.3', '>=') - ? new Reference('request_stack') - : new Reference('session'); + ->set('flasher.flasher_listener', FlasherListener::class) + ->args([ + inline_service(ResponseExtension::class) + ->args([ + service('flasher'), + service('flasher.csp_handler'), + ]), + ]) + ->tag('kernel.event_subscriber') -$container->register('flasher.storage_bag', 'Flasher\Symfony\Storage\SessionBag') - ->setPublic(false) - ->addArgument($storage); + ->set('flasher.twig_extension', FlasherTwigExtension::class) + ->args([service('flasher')]) + ->tag('twig.extension') -$container->register('flasher.storage', 'Flasher\Prime\Storage\StorageBag') - ->setPublic(false) - ->addArgument(new Reference('flasher.storage_bag')); + ->set('flasher.session_listener', SessionListener::class) + ->args([ + inline_service(RequestExtension::class) + ->args([ + service('flasher'), + param('flasher.flash_bag'), + ]), + ]) + ->tag('kernel.event_subscriber') -$container->register('flasher.event_dispatcher', 'Flasher\Prime\EventDispatcher\EventDispatcher') - ->setPublic(false); + ->set('flasher.notification_logger_listener', NotificationLoggerListener::class) + ->tag('flasher.event_dispatcher') + ->tag('kernel.reset', ['method' => 'reset']) -$container->register('flasher.storage_manager', 'Flasher\Prime\Storage\StorageManager') - ->setPublic(false) - ->addArgument(new Reference('flasher.storage')) - ->addArgument(new Reference('flasher.event_dispatcher')) - ->addArgument(array()); + ->set('flasher.translation_listener', TranslationListener::class) + ->args([service('flasher.translator')->nullOnInvalid()]) + ->tag('kernel.event_listener') -$container->register('flasher.twig.extension', 'Flasher\Symfony\Twig\FlasherTwigExtension') - ->setPublic(false) - ->addTag('twig.extension', array()); + ->set('flasher.preset_listener', ApplyPresetListener::class) + ->args([param('flasher.presets')]) + ->tag('kernel.event_listener') -$container->register('flasher.template_engine', 'Flasher\Symfony\Template\TwigTemplateEngine') - ->setPublic(false) - ->addArgument(new Reference('twig')); + ->set('flasher.install_command', InstallCommand::class) + ->args([service('flasher.asset_manager')]) + ->tag('console.command') -$container->register('flasher.resource_manager', 'Flasher\Prime\Response\Resource\ResourceManager') - ->setPublic(false) - ->addArgument(new Reference('flasher.config')) - ->addArgument(new Reference('flasher.template_engine')); + ->set('flasher.flasher_component', FlasherComponent::class) + ->tag('twig.component', [ + 'key' => 'flasher', + 'template' => '@Flasher/components/flasher.html.twig', + 'attributesVar' => 'attributes', + ]) -$container->register('flasher.response_manager', 'Flasher\Prime\Response\ResponseManager') - ->setPublic(false) - ->addArgument(new Reference('flasher.resource_manager')) - ->addArgument(new Reference('flasher.storage_manager')) - ->addArgument(new Reference('flasher.event_dispatcher')); + ->set('flasher.notification_factory', NotificationFactory::class) + ->args([service('flasher.storage_manager')]) -$container->register('flasher', 'Flasher\Prime\Flasher') - ->setPublic(true) - ->addArgument(null) - ->addArgument(new Reference('flasher.response_manager')) - ->addArgument(new Reference('flasher.storage_manager')); + ->set('flasher.storage', Storage::class) + ->args([service('flasher.storage_bag')]) -$container->register('flasher.notification_factory', 'Flasher\Prime\Factory\NotificationFactory') - ->setPublic(false) - ->addArgument(new Reference('flasher.storage_manager')); + ->set('flasher.storage_bag', SessionBag::class) + ->args([service('request_stack')]) -$container->register('flasher.translator', 'Flasher\Symfony\Translation\Translator') - ->setPublic(false) - ->addArgument(new Reference('translator')); + ->set('flasher.event_dispatcher', EventDispatcher::class) -$container->register('flasher.translation_listener', 'Flasher\Prime\EventDispatcher\EventListener\TranslationListener') - ->setPublic(false) - ->addArgument(new Reference('flasher.translator')) - ->addArgument(true) - ->addTag('flasher.event_subscriber'); + ->set('flasher.filter_factory', FilterFactory::class) -$container->register('flasher.preset_listener', 'Flasher\Prime\EventDispatcher\EventListener\PresetListener') - ->setPublic(false) - ->addArgument(array()) - ->addTag('flasher.event_subscriber'); + ->set('flasher.storage_manager', StorageManager::class) + ->args([ + service('flasher.storage'), + service('flasher.event_dispatcher'), + service('flasher.filter_factory'), + param('flasher.filter'), + ]) -$container->register('flasher.install_command', 'Flasher\Symfony\Command\InstallCommand') - ->addTag('console.command'); + ->set('flasher.template_engine', TwigTemplateEngine::class) + ->args([service('twig')->nullOnInvalid()]) -if (Bridge::canLoadAliases()) { - $container->setAlias('Flasher\Prime\Flasher', 'flasher'); - $container->setAlias('Flasher\Prime\FlasherInterface', 'flasher'); -} + ->set('flasher.resource_manager', ResourceManager::class) + ->args([ + service('flasher.template_engine'), + service('flasher.asset_manager'), + param('flasher.main_script'), + param('flasher.plugins'), + ]) + + ->set('flasher.response_manager', ResponseManager::class) + ->args([ + service('flasher.resource_manager'), + service('flasher.storage_manager'), + service('flasher.event_dispatcher'), + ]) + + ->set('flasher.translator', Translator::class) + ->args([service('translator')->nullOnInvalid()]) + + ->set('flasher.csp_handler', ContentSecurityPolicyHandler::class) + ->args([inline_service(NonceGenerator::class)]) + + ->set('flasher.asset_manager', AssetManager::class) + ->args([ + param('flasher.public_dir'), + param('flasher.json_manifest_path'), + ]) + ; +}; diff --git a/src/Symfony/Resources/translations/flasher.ar.php b/src/Symfony/Resources/translations/flasher.ar.php index 52e27520..084fd9ee 100644 --- a/src/Symfony/Resources/translations/flasher.ar.php +++ b/src/Symfony/Resources/translations/flasher.ar.php @@ -1,10 +1,5 @@ - */ +declare(strict_types=1); -use Flasher\Prime\Translation\Messages; - -return Messages::$ar; +return Flasher\Prime\Translation\Messages::get('ar'); diff --git a/src/Symfony/Resources/translations/flasher.de.php b/src/Symfony/Resources/translations/flasher.de.php new file mode 100644 index 00000000..57908c7e --- /dev/null +++ b/src/Symfony/Resources/translations/flasher.de.php @@ -0,0 +1,5 @@ + - */ +declare(strict_types=1); -use Flasher\Prime\Translation\Messages; - -return Messages::$en; +return Flasher\Prime\Translation\Messages::get('en'); diff --git a/src/Symfony/Resources/translations/flasher.es.php b/src/Symfony/Resources/translations/flasher.es.php new file mode 100644 index 00000000..f7fe97e6 --- /dev/null +++ b/src/Symfony/Resources/translations/flasher.es.php @@ -0,0 +1,5 @@ + - */ +declare(strict_types=1); -use Flasher\Prime\Translation\Messages; - -return Messages::$fr; +return Flasher\Prime\Translation\Messages::get('fr'); diff --git a/src/Symfony/Resources/translations/flasher.pt.php b/src/Symfony/Resources/translations/flasher.pt.php new file mode 100644 index 00000000..688f1ef9 --- /dev/null +++ b/src/Symfony/Resources/translations/flasher.pt.php @@ -0,0 +1,5 @@ + + +
      + +
      + diff --git a/src/Symfony/Resources/views/components/flasher.html.twig b/src/Symfony/Resources/views/components/flasher.html.twig new file mode 100644 index 00000000..360776e3 --- /dev/null +++ b/src/Symfony/Resources/views/components/flasher.html.twig @@ -0,0 +1,3 @@ +
      + {{ flasher_render() }} +
      diff --git a/src/Symfony/Resources/views/tailwindcss.html.twig b/src/Symfony/Resources/views/tailwindcss.html.twig new file mode 100644 index 00000000..3074b174 --- /dev/null +++ b/src/Symfony/Resources/views/tailwindcss.html.twig @@ -0,0 +1,52 @@ +{% if 'success' == envelope.type %} + {% set title = 'Success' %} + {% set text_color = 'text-green-600' %} + {% set ring_color = 'ring-green-300' %} + {% set background_color = 'bg-green-600' %} + {% set progress_background_color = 'bg-green-100' %} + {% set border_color = 'border-green-600' %} + {% set icon = '' %} +{% elseif 'error' == envelope.type %} + {% set title = 'Error' %} + {% set text_color = 'text-red-600' %} + {% set ring_color = 'ring-red-300' %} + {% set background_color = 'bg-red-600' %} + {% set progress_background_color = 'bg-red-100' %} + {% set border_color = 'border-red-600' %} + {% set icon = '' %} +{% elseif 'warning' == envelope.type %} + {% set title = 'Warning' %} + {% set text_color = 'text-yellow-600' %} + {% set ring_color = 'ring-yellow-300' %} + {% set background_color = 'bg-yellow-600' %} + {% set progress_background_color = 'bg-yellow-100' %} + {% set border_color = 'border-yellow-600' %} + {% set icon = '' %} +{% else %} + {% set title = 'Info' %} + {% set text_color = 'text-blue-600' %} + {% set ring_color = 'ring-blue-300' %} + {% set background_color = 'bg-blue-600' %} + {% set progress_background_color = 'bg-blue-100' %} + {% set border_color = 'border-blue-600' %} + {% set icon = '' %} +{% endif %} + +
      +
      +
      + {{ icon | raw }} +
      +
      +

      + {{ title | trans }} +

      +

      + {{ envelope.message }} +

      +
      +
      +
      + +
      +
      diff --git a/src/Symfony/Resources/views/tailwindcss_bg.html.twig b/src/Symfony/Resources/views/tailwindcss_bg.html.twig new file mode 100644 index 00000000..702e4d87 --- /dev/null +++ b/src/Symfony/Resources/views/tailwindcss_bg.html.twig @@ -0,0 +1,48 @@ +{% if 'success' == envelope.type %} + {% set title = 'Success' %} + {% set text_color = 'text-green-700' %} + {% set background_color = 'bg-green-50' %} + {% set progress_background_color = 'bg-green-200' %} + {% set border_color = 'border-green-600' %} + {% set icon = '' %} +{% elseif 'error' == envelope.type %} + {% set title = 'Error' %} + {% set text_color = 'text-red-700' %} + {% set background_color = 'bg-red-50' %} + {% set progress_background_color = 'bg-red-200' %} + {% set border_color = 'border-red-600' %} + {% set icon = '' %} +{% elseif 'warning' == envelope.type %} + {% set title = 'Warning' %} + {% set text_color = 'text-yellow-700' %} + {% set background_color = 'bg-yellow-50' %} + {% set progress_background_color = 'bg-yellow-200' %} + {% set border_color = 'border-yellow-600' %} + {% set icon = '' %} +{% else %} + {% set title = 'Info' %} + {% set text_color = 'text-blue-700' %} + {% set background_color = 'bg-blue-50' %} + {% set progress_background_color = 'bg-blue-200' %} + {% set border_color = 'border-blue-600' %} + {% set icon = '' %} +{% endif %} + +
      +
      +
      + {{ icon | raw }} +
      +
      +

      + {{ title | trans }} +

      +

      + {{ envelope.message }} +

      +
      +
      +
      + +
      +
      diff --git a/src/Symfony/Resources/views/tailwindcss_r.html.twig b/src/Symfony/Resources/views/tailwindcss_r.html.twig new file mode 100644 index 00000000..4227a282 --- /dev/null +++ b/src/Symfony/Resources/views/tailwindcss_r.html.twig @@ -0,0 +1,53 @@ +{% if 'success' == envelope.type %} + {% set title = 'Success' %} + {% set text_color = 'text-green-600' %} + {% set ring_color = 'ring-green-300' %} + {% set background_color = 'bg-green-600' %} + {% set progress_background_color = 'bg-green-100' %} + {% set border_color = 'border-green-600' %} + {% set icon = '' %} +{% elseif 'error' == envelope.type %} + {% set title = 'Error' %} + {% set text_color = 'text-red-600' %} + {% set ring_color = 'ring-red-300' %} + {% set background_color = 'bg-red-600' %} + {% set progress_background_color = 'bg-red-100' %} + {% set border_color = 'border-red-600' %} + {% set icon = '' %} +{% elseif 'warning' == envelope.type %} + {% set title = 'Warning' %} + {% set text_color = 'text-yellow-600' %} + {% set ring_color = 'ring-yellow-300' %} + {% set background_color = 'bg-yellow-600' %} + {% set progress_background_color = 'bg-yellow-100' %} + {% set border_color = 'border-yellow-600' %} + {% set icon = '' %} +{% else %} + {% set title = 'Info' %} + {% set text_color = 'text-blue-600' %} + {% set ring_color = 'ring-blue-300' %} + {% set background_color = 'bg-blue-600' %} + {% set progress_background_color = 'bg-blue-100' %} + {% set border_color = 'border-blue-600' %} + {% set icon = '' %} +{% endif %} + + +
      +
      +
      + {{ icon | raw }} +
      +
      +

      + {{ title | trans }} +

      +

      + {{ envelope.message }} +

      +
      +
      +
      + +
      +
      diff --git a/src/Symfony/Storage/FallbackSession.php b/src/Symfony/Storage/FallbackSession.php index 96e8482d..9651f124 100644 --- a/src/Symfony/Storage/FallbackSession.php +++ b/src/Symfony/Storage/FallbackSession.php @@ -1,31 +1,23 @@ */ + private static array $storage = []; - /** - * @param string $name - * @param mixed $default - * - * @return mixed - */ - public function get($name, $default = null) + public function get(string $name, mixed $default = null): mixed { - return array_key_exists($name, self::$storage) - ? self::$storage[$name] - : $default; + return \array_key_exists($name, self::$storage) ? self::$storage[$name] : $default; } - /** - * @param string $name - * @param mixed $value - * - * @return void - */ - public function set($name, $value) + public function set(string $name, mixed $value): void { self::$storage[$name] = $value; } diff --git a/src/Symfony/Storage/FallbackSessionInterface.php b/src/Symfony/Storage/FallbackSessionInterface.php new file mode 100644 index 00000000..f5908f00 --- /dev/null +++ b/src/Symfony/Storage/FallbackSessionInterface.php @@ -0,0 +1,29 @@ + - */ +declare(strict_types=1); namespace Flasher\Symfony\Storage; +use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Storage\Bag\BagInterface; use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\HttpFoundation\Session as LegacySession; use Symfony\Component\HttpFoundation\Session\SessionInterface; -final class SessionBag implements BagInterface +final readonly class SessionBag implements BagInterface { - const ENVELOPES_NAMESPACE = 'flasher::envelopes'; + public const ENVELOPES_NAMESPACE = 'flasher::envelopes'; - /** - * @var RequestStack|SessionInterface - */ - private $session; + private FallbackSessionInterface $fallbackSession; - /** - * @var FallbackSession - */ - private $fallbackSession; - - /** - * @param RequestStack|SessionInterface $session - */ - public function __construct($session) + public function __construct(private RequestStack $requestStack, ?FallbackSessionInterface $fallbackSession = null) { - $this->session = $session; - $this->fallbackSession = new FallbackSession(); + $this->fallbackSession = $fallbackSession ?: new FallbackSession(); } - /** - * {@inheritdoc} - */ - public function get() + public function get(): array { - return $this->session()->get(self::ENVELOPES_NAMESPACE, array()); // @phpstan-ignore-line + $session = $this->getSession(); + + /** @var Envelope[] $envelopes */ + $envelopes = $session->get(self::ENVELOPES_NAMESPACE, []); + + return $envelopes; } - /** - * {@inheritdoc} - */ - public function set(array $envelopes) + public function set(array $envelopes): void { - $this->session()->set(self::ENVELOPES_NAMESPACE, $envelopes); + $session = $this->getSession(); + + $session->set(self::ENVELOPES_NAMESPACE, $envelopes); } - /** - * @return SessionInterface - */ - private function session() + private function getSession(): SessionInterface|FallbackSessionInterface { - if ($this->session instanceof SessionInterface || $this->session instanceof LegacySession) { // @phpstan-ignore-line - return $this->session; // @phpstan-ignore-line - } - try { - if (method_exists($this->session, 'getSession')) { - $session = $this->session->getSession(); - } else { - $session = $this->session->getCurrentRequest()->getSession(); + $request = $this->requestStack->getCurrentRequest(); + + if ($request && !$request->attributes->get('_stateless', false)) { + return $this->requestStack->getSession(); } - - $isStateless = $this->session->getCurrentRequest()->attributes->has('_stateless'); - - if (null !== $session && !$isStateless) { - return $this->session = $session; - } - - return $this->fallbackSession; - } catch (SessionNotFoundException $e) { - return $this->fallbackSession; + } catch (SessionNotFoundException) { } + + return $this->fallbackSession; } } diff --git a/src/Symfony/Support/Bundle.php b/src/Symfony/Support/Bundle.php deleted file mode 100644 index 8de32155..00000000 --- a/src/Symfony/Support/Bundle.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ - -namespace Flasher\Symfony\Support; - -use Flasher\Prime\Plugin\PluginInterface; -use Flasher\Symfony\Bridge\FlasherBundle; - -abstract class Bundle extends FlasherBundle -{ - /** - * @return PluginInterface - */ - abstract public function createPlugin(); - - public function getConfigurationFile() - { - return rtrim($this->getResourcesDir(), '/').'/config/config.yaml'; - } - - protected function getFlasherContainerExtension() - { - return new Extension($this->createPlugin()); - } - - /** - * @return string - */ - protected function getResourcesDir() - { - $r = new \ReflectionClass($this); - - return pathinfo($r->getFileName() ?: '', PATHINFO_DIRNAME).'/Resources/'; - } -} diff --git a/src/Symfony/Support/Configuration.php b/src/Symfony/Support/Configuration.php deleted file mode 100644 index 39702e79..00000000 --- a/src/Symfony/Support/Configuration.php +++ /dev/null @@ -1,60 +0,0 @@ - - */ - -namespace Flasher\Symfony\Support; - -use Flasher\Prime\Plugin\PluginInterface; -use Flasher\Symfony\Bridge\DependencyInjection\FlasherConfiguration; -use Symfony\Component\Config\Definition\Builder\TreeBuilder; - -class Configuration extends FlasherConfiguration -{ - /** - * @var PluginInterface - */ - private $plugin; - - public function __construct(PluginInterface $plugin) - { - $this->plugin = $plugin; - } - - public function getFlasherConfigTreeBuilder() - { - $treeBuilder = new TreeBuilder($this->plugin->getName()); - - $rootNode = method_exists($treeBuilder, 'getRootNode') - ? $treeBuilder->getRootNode() - : $treeBuilder->root($this->plugin->getName()); // @phpstan-ignore-line - - $plugin = $this->plugin; - $rootNode - ->beforeNormalization() - ->always(function ($v) use ($plugin) { - return $plugin->normalizeConfig($v); - }) - ->end() - ->children() - ->arrayNode('scripts') - ->prototype('variable')->end() - ->defaultValue($this->plugin->getScripts()) - ->end() - ->arrayNode('styles') - ->prototype('variable')->end() - ->defaultValue($this->plugin->getStyles()) - ->end() - ->arrayNode('options') - ->prototype('variable')->end() - ->ignoreExtraKeys(false) - ->defaultValue($this->plugin->getOptions()) - ->end() - ->end() - ; - - return $treeBuilder; - } -} diff --git a/src/Symfony/Support/Extension.php b/src/Symfony/Support/Extension.php deleted file mode 100644 index 25a47e40..00000000 --- a/src/Symfony/Support/Extension.php +++ /dev/null @@ -1,116 +0,0 @@ - - */ - -namespace Flasher\Symfony\Support; - -use Flasher\Prime\Plugin\PluginInterface; -use Flasher\Symfony\Bridge\Bridge; -use Flasher\Symfony\Bridge\DependencyInjection\FlasherExtension; -use Symfony\Component\Config\Definition\ConfigurationInterface; -use Symfony\Component\DependencyInjection\ChildDefinition; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\DefinitionDecorator; - -final class Extension extends FlasherExtension implements CompilerPassInterface -{ - /** - * @var PluginInterface - */ - private $plugin; - - public function __construct(PluginInterface $plugin) - { - $this->plugin = $plugin; - } - - /** - * {@inheritdoc} - * - * @param array> $configs - * - * @return void - */ - public function load(array $configs, ContainerBuilder $container) - { - /** @var ChildDefinition $definition */ - $definition = class_exists('Symfony\Component\DependencyInjection\ChildDefinition') - ? new ChildDefinition('flasher.notification_factory') - : new DefinitionDecorator('flasher.notification_factory'); // @phpstan-ignore-line - - $definition - ->setClass($this->plugin->getFactory()) - ->setPublic(true) - ->addTag('flasher.factory', array('alias' => $this->plugin->getAlias())); - - $identifier = $this->plugin->getServiceID(); - $container->setDefinition($identifier, $definition); - - if (Bridge::canLoadAliases()) { - $container->setAlias($this->plugin->getFactory(), $identifier); - } - } - - /** - * {@inheritdoc} - */ - public function getFlasherAlias() - { - return $this->plugin->getName(); - } - - /** - * Returns extension configuration. - * - * @param array> $config - * - * @return ConfigurationInterface|null - */ - public function getConfiguration(array $config, ContainerBuilder $container) - { - return new Configuration($this->plugin); - } - - /** - * {@inheritdoc} - * - * @return void - */ - public function process(ContainerBuilder $container) - { - $configs = $this->processConfiguration( - new Configuration($this->plugin), - $container->getExtensionConfig($this->plugin->getName()) - ); - - $this->processResourceConfiguration($configs, $container); - } - - /** - * @param array $configs - * - * @return void - */ - protected function processResourceConfiguration(array $configs, ContainerBuilder $container) - { - if (!$container->has('flasher.resource_manager')) { - return; - } - - $definition = $container->getDefinition('flasher.resource_manager'); - $handler = $this->plugin->getAlias(); - - $scripts = isset($configs['scripts']) ? $configs['scripts'] : array(); - $definition->addMethodCall('addScripts', array($handler, $scripts)); - - $styles = isset($configs['styles']) ? $configs['styles'] : array(); - $definition->addMethodCall('addStyles', array($handler, $styles)); - - $options = isset($configs['options']) ? $configs['options'] : array(); - $definition->addMethodCall('addOptions', array($handler, $options)); - } -} diff --git a/src/Symfony/Support/PluginBundle.php b/src/Symfony/Support/PluginBundle.php new file mode 100644 index 00000000..a6447bb7 --- /dev/null +++ b/src/Symfony/Support/PluginBundle.php @@ -0,0 +1,75 @@ + $config + */ + public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void + { + if ($this instanceof FlasherBundle) { + return; + } + + $plugin = $this->createPlugin(); + $identifier = $plugin->getServiceId(); + + $container->services() + ->set($identifier, $plugin->getFactory()) + ->parent('flasher.notification_factory') + ->tag('flasher.factory', ['alias' => $plugin->getAlias()]) + ->public() + ; + + foreach ((array) $plugin->getServiceAliases() as $alias) { + $builder->setAlias($alias, $identifier); + } + } + + public function prependExtension(ContainerConfigurator $container, ContainerBuilder $builder): void + { + if ($this instanceof FlasherBundle) { + return; + } + + $plugin = $this->createPlugin(); + + $builder->prependExtensionConfig('flasher', [ + 'plugins' => [ + $plugin->getAlias() => [ + 'scripts' => (array) $plugin->getScripts(), + 'styles' => (array) $plugin->getStyles(), + 'options' => $plugin->getOptions(), + ], + ], + ]); + } + + public function getConfigurationFile(): string + { + return rtrim($this->getPath(), '/').'/Resources/config/config.yaml'; + } + + public function getPath(): string + { + if (!isset($this->path)) { + $reflected = new \ReflectionObject($this); + // assume the modern directory structure by default + $this->path = \dirname($reflected->getFileName() ?: ''); + } + + return $this->path; + } +} diff --git a/src/Symfony/Support/PluginBundleInterface.php b/src/Symfony/Support/PluginBundleInterface.php new file mode 100644 index 00000000..b65d8f47 --- /dev/null +++ b/src/Symfony/Support/PluginBundleInterface.php @@ -0,0 +1,14 @@ +plugin->getName(); + } + + public function load(array $configs, ContainerBuilder $container): void + { + $definition = new ChildDefinition('flasher.notification_factory'); + $definition + ->setClass($this->plugin->getFactory()) + ->setPublic(true) + ->addTag('flasher.factory', ['alias' => $this->plugin->getAlias()]); + + $identifier = $this->plugin->getServiceId(); + $container->setDefinition($identifier, $definition); + + foreach ((array) $this->plugin->getServiceAliases() as $alias) { + $container->setAlias($alias, $identifier); + } + } + + public function prepend(ContainerBuilder $container): void + { + $container->prependExtensionConfig('flasher', [ + 'plugins' => [ + $this->plugin->getAlias() => [ + 'scripts' => (array) $this->plugin->getScripts(), + 'styles' => (array) $this->plugin->getStyles(), + 'options' => $this->plugin->getOptions(), + ], + ], + ]); + } +} diff --git a/src/Symfony/Template/TwigTemplateEngine.php b/src/Symfony/Template/TwigTemplateEngine.php index 7500580a..04fae24e 100644 --- a/src/Symfony/Template/TwigTemplateEngine.php +++ b/src/Symfony/Template/TwigTemplateEngine.php @@ -1,29 +1,24 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\Template; use Flasher\Prime\Template\TemplateEngineInterface; use Twig\Environment; -final class TwigTemplateEngine implements TemplateEngineInterface +final readonly class TwigTemplateEngine implements TemplateEngineInterface { - /** - * @var Environment - */ - private $engine; - - public function __construct(Environment $engine) + public function __construct(private ?Environment $twig = null) { - $this->engine = $engine; } - public function render($name, array $context = array()) + public function render(string $name, array $context = []): string { - return $this->engine->render($name, $context); + if (null === $this->twig) { + throw new \LogicException('The TwigBundle is not registered in your application. Try running "composer require symfony/twig-bundle".'); + } + + return $this->twig->render($name, $context); } } diff --git a/src/Symfony/Translation/Translator.php b/src/Symfony/Translation/Translator.php index 013b5547..73a52ff3 100644 --- a/src/Symfony/Translation/Translator.php +++ b/src/Symfony/Translation/Translator.php @@ -1,48 +1,28 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\Translation; -use Flasher\Prime\Stamp\TranslationStamp; use Flasher\Prime\Translation\TranslatorInterface; use Symfony\Component\Translation\TranslatorBagInterface; use Symfony\Contracts\Translation\TranslatorInterface as SymfonyTranslatorInterface; -final class Translator implements TranslatorInterface +final readonly class Translator implements TranslatorInterface { - /** - * @var SymfonyTranslatorInterface - */ - private $translator; - - /** - * @param SymfonyTranslatorInterface $translator - */ - public function __construct($translator) + public function __construct(private SymfonyTranslatorInterface $translator) { - $this->translator = $translator; } - /** - * {@inheritdoc} - */ - public function translate($id, $parameters = array(), $locale = null) + public function translate(string $id, array $parameters = [], ?string $locale = null): string { - $order = TranslationStamp::parametersOrder($parameters, $locale); - $parameters = $this->addPrefixedParams($order['parameters']); - $locale = $order['locale']; - if (!$this->translator instanceof TranslatorBagInterface) { return $this->translator->trans($id, $parameters, 'flasher', $locale); } $catalogue = $this->translator->getCatalogue($locale); - foreach (array('flasher', 'messages') as $domain) { + foreach (['flasher', 'messages'] as $domain) { if ($catalogue->has($id, $domain)) { return $this->translator->trans($id, $parameters, $domain, $locale); } @@ -51,27 +31,12 @@ final class Translator implements TranslatorInterface return $id; } - /** - * {@inheritDoc} - */ - public function getLocale() + public function getLocale(): string { - return $this->translator->getLocale(); - } - - /** - * @param array $parameters - * - * @return array - */ - private function addPrefixedParams(array $parameters) - { - foreach ($parameters as $key => $value) { - if (0 !== strpos($key, ':')) { - $parameters[':'.$key] = $value; - } + if (method_exists($this->translator, 'getLocale')) { + return $this->translator->getLocale(); } - return $parameters; + return class_exists(\Locale::class) ? \Locale::getDefault() : 'en'; } } diff --git a/src/Symfony/Twig/FlasherTwigExtension.php b/src/Symfony/Twig/FlasherTwigExtension.php index ca098a4c..af6af174 100644 --- a/src/Symfony/Twig/FlasherTwigExtension.php +++ b/src/Symfony/Twig/FlasherTwigExtension.php @@ -1,32 +1,35 @@ - */ +declare(strict_types=1); namespace Flasher\Symfony\Twig; -use Flasher\Symfony\Bridge\Twig\FlasherTwigExtension as BaseFlasherTwigExtension; +use Flasher\Prime\FlasherInterface; +use Twig\Extension\AbstractExtension; use Twig\TwigFunction; -final class FlasherTwigExtension extends BaseFlasherTwigExtension +final class FlasherTwigExtension extends AbstractExtension { - /** - * @return TwigFunction[] - */ - public function getFlasherFunctions() + public function __construct(private readonly FlasherInterface $flasher) { - return array( - new TwigFunction('flasher_render', array($this, 'render')), - ); + } + + public function getFunctions(): array + { + return [ + new TwigFunction('flasher_render', $this->render(...), ['is_safe' => ['html']]), + ]; } /** - * @return string + * Renders the flash notifications based on the specified criteria, presenter, and context. + * + * @param array $criteria the criteria to filter the notifications + * @param "html"|"json"|string $presenter The presenter format for rendering the notifications (e.g., 'html', 'json'). + * @param array $context additional context or options for rendering */ - public function render() + public function render(array $criteria = [], string $presenter = 'html', array $context = []): mixed { - return ''; + return $this->flasher->render($presenter, $criteria, $context); } } diff --git a/src/Symfony/composer.json b/src/Symfony/composer.json index 1e050024..cd49f527 100644 --- a/src/Symfony/composer.json +++ b/src/Symfony/composer.json @@ -1,54 +1,48 @@ { "name": "php-flasher/flasher-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "symfony-bundle", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher Symfony Bundle: Supercharge your Symfony projects with this robust flash message package. Enhance user engagement with intuitive, easy-to-integrate flash messaging. Tailored for developers, PHPFlasher provides a powerful solution for managing user feedback in Symfony applications.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", + "minimum-stability": "dev", + "prefer-stable": true, "require": { - "php": ">=5.3", - "php-flasher/flasher": "^1.15.14", - "symfony/config": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/console": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/dependency-injection": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "symfony/http-kernel": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + "php": ">=8.2", + "php-flasher/flasher": "^2.0", + "symfony/config": "^7.0", + "symfony/console": "^7.0", + "symfony/dependency-injection": "^7.0", + "symfony/http-kernel": "^7.0" }, "suggest": { "symfony/translation": "To translate flash messages, title and presets", - "symfony/twig-bundle": "To create custom themes using twig templates" + "symfony/ux-twig-component": "To utilize and interact with flash messages components in Twig templates" }, - "minimum-stability": "stable", - "prefer-stable": true, "autoload": { "psr-4": { "Flasher\\Symfony\\": "" diff --git a/src/Toastr/Laravel/.github/FUNDING.yml b/src/Toastr/Laravel/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Toastr/Laravel/.github/FUNDING.yml +++ b/src/Toastr/Laravel/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Toastr/Laravel/.github/workflows/auto_closer.yaml b/src/Toastr/Laravel/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Toastr/Laravel/.github/workflows/auto_closer.yaml +++ b/src/Toastr/Laravel/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Toastr/Laravel/Facade/Toastr.php b/src/Toastr/Laravel/Facade/Toastr.php index e84cc25b..8c7d82c9 100644 --- a/src/Toastr/Laravel/Facade/Toastr.php +++ b/src/Toastr/Laravel/Facade/Toastr.php @@ -1,24 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\Toastr\Laravel\Facade; use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; use Flasher\Prime\Stamp\StampInterface; use Flasher\Toastr\Prime\ToastrBuilder; use Illuminate\Support\Facades\Facade; /** - * @method static ToastrBuilder addSuccess(string $message, array $options = array()) - * @method static ToastrBuilder addError(string $message, array $options = array()) - * @method static ToastrBuilder addWarning(string $message, array $options = array()) - * @method static ToastrBuilder addInfo(string $message, array $options = array()) - * @method static ToastrBuilder addFlash(NotificationInterface|string $type, string $message = null, array $options = array()) * @method static ToastrBuilder flash(StampInterface[] $stamps = array()) * @method static ToastrBuilder type(string $type, string $message = null, array $options = array()) * @method static ToastrBuilder message(string $message) @@ -72,9 +63,9 @@ use Illuminate\Support\Facades\Facade; * @method static ToastrBuilder toastClass(string $toastClass) * @method static ToastrBuilder persistent() */ -class Toastr extends Facade +final class Toastr extends Facade { - protected static function getFacadeAccessor() + protected static function getFacadeAccessor(): string { return 'flasher.toastr'; } diff --git a/src/Toastr/Laravel/FlasherToastrServiceProvider.php b/src/Toastr/Laravel/FlasherToastrServiceProvider.php index e7bbc55e..f926db82 100644 --- a/src/Toastr/Laravel/FlasherToastrServiceProvider.php +++ b/src/Toastr/Laravel/FlasherToastrServiceProvider.php @@ -1,21 +1,15 @@ - */ +declare(strict_types=1); namespace Flasher\Toastr\Laravel; -use Flasher\Laravel\Support\ServiceProvider; +use Flasher\Laravel\Support\PluginServiceProvider; use Flasher\Toastr\Prime\ToastrPlugin; -final class FlasherToastrServiceProvider extends ServiceProvider +final class FlasherToastrServiceProvider extends PluginServiceProvider { - /** - * {@inheritdoc} - */ - public function createPlugin() + public function createPlugin(): ToastrPlugin { return new ToastrPlugin(); } diff --git a/src/Toastr/Laravel/LICENSE b/src/Toastr/Laravel/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Toastr/Laravel/LICENSE +++ b/src/Toastr/Laravel/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Toastr/Laravel/README.md b/src/Toastr/Laravel/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Toastr/Laravel/README.md +++ b/src/Toastr/Laravel/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
      Younes KHOUBZA
      Younes KHOUBZA

      💻 📖 🚧
      Younes ENNAJI
      Younes ENNAJI

      💻 📖 🚧
      Salma Mourad
      Salma Mourad

      💵
      Nashwan Abdullah
      Nashwan Abdullah

      💵
      Arvid de Jong
      Arvid de Jong

      💵
      - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

      Made with ❤️ by Younes KHOUBZA

      +

      Made with ❤️ by Younes ENNAJI

      diff --git a/src/Toastr/Laravel/Resources/config.php b/src/Toastr/Laravel/Resources/config.php deleted file mode 100644 index cb68c9f7..00000000 --- a/src/Toastr/Laravel/Resources/config.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ - -return array( - 'scripts' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.min.js', - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-toastr@1.3.2/dist/flasher-toastr.min.js', - ), - 'local' => array( - '/vendor/flasher/jquery.min.js', - '/vendor/flasher/flasher-toastr.min.js', - ), - ), - 'styles' => array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-toastr@1.3.2/dist/flasher-toastr.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-toastr.min.css', - ), - ), -); diff --git a/src/Toastr/Laravel/composer.json b/src/Toastr/Laravel/composer.json index bb9d3bb8..ae829baa 100644 --- a/src/Toastr/Laravel/composer.json +++ b/src/Toastr/Laravel/composer.json @@ -1,47 +1,37 @@ { "name": "php-flasher/flasher-toastr-laravel", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher Toastr for Laravel - A Laravel-specific extension of PHPFlasher for Toastr notifications, enhancing user interactions with aesthetically pleasing and responsive toast messages.", "keywords": [ "php-flasher", + "laravel", + "toastr", "flash-messages", "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", "user-experience", - "rtl", - "dark-mode" + "laravel-package" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-laravel": "^1.15.14", - "php-flasher/flasher-toastr": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-laravel": "^2.0", + "php-flasher/flasher-toastr": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Toastr\\Laravel\\": "" @@ -53,12 +43,12 @@ }, "extra": { "laravel": { - "aliases": { - "Toastr": "Flasher\\Toastr\\Laravel\\Facade\\Toastr" - }, "providers": [ "Flasher\\Toastr\\Laravel\\FlasherToastrServiceProvider" - ] + ], + "aliases": { + "Toastr": "Flasher\\Toastr\\Laravel\\Facade\\Toastr" + } } } } diff --git a/src/Toastr/Prime/.github/FUNDING.yml b/src/Toastr/Prime/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Toastr/Prime/.github/FUNDING.yml +++ b/src/Toastr/Prime/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Toastr/Prime/.github/workflows/auto_closer.yaml b/src/Toastr/Prime/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Toastr/Prime/.github/workflows/auto_closer.yaml +++ b/src/Toastr/Prime/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Toastr/Prime/.phpstorm.meta.php b/src/Toastr/Prime/.phpstorm.meta.php index 62c8e742..e77c82ff 100644 --- a/src/Toastr/Prime/.phpstorm.meta.php +++ b/src/Toastr/Prime/.phpstorm.meta.php @@ -3,16 +3,15 @@ namespace PHPSTORM_META; expectedArguments(\toastr(), 1, 'success', 'error', 'info', 'warning'); +expectedArguments(\Flasher\Toastr\Prime\toastr(), 1, 'success', 'error', 'info', 'warning'); + expectedArguments(\Flasher\Toastr\Prime\ToastrBuilder::showMethod(), 0, 'fadeIn', 'fadeOut', 'slideDown', 'show'); expectedArguments(\Flasher\Toastr\Prime\ToastrBuilder::hideMethod(), 0, 'fadeIn', 'fadeOut', 'slideDown', 'show'); expectedArguments(\Flasher\Toastr\Prime\ToastrBuilder::showEasing(), 0, 'swing', 'linear'); expectedArguments(\Flasher\Toastr\Prime\ToastrBuilder::hideEasing(), 0, 'swing', 'linear'); expectedArguments(\Flasher\Toastr\Prime\ToastrBuilder::positionClass(), 0, 'toast-top-right', 'toast-top-center', 'toast-bottom-center', 'toast-top-full-width', 'toast-bottom-full-width', 'toast-top-left', 'toast-bottom-right', 'toast-bottom-left'); -override(\Flasher\Prime\FlasherInterface::create(), map([ - 'toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, -])); +override(\Flasher\Prime\FlasherInterface::use(), map(['toastr' => \Flasher\Toastr\Prime\ToastrInterface::class])); +override(\Flasher\Prime\Container\FlasherContainer::create(), map(['flasher.toastr' => \Flasher\Toastr\Prime\ToastrInterface::class])); -override(\Flasher\Prime\FlasherInterface::using(), map([ - 'toastr' => \Flasher\Toastr\Prime\ToastrFactory::class, -])); +expectedArguments(\Flasher\Toastr\Prime\ToastrBuilder::option(), 0, 'closeButton', 'closeClass', 'closeDuration', 'closeEasing', 'closeHtml', 'closeMethod', 'closeOnHover', 'containerId', 'debug', 'escapeHtml', 'extendedTimeOut', 'hideDuration', 'hideEasing', 'hideMethod', 'iconClass', 'messageClass', 'newestOnTop', 'onHidden', 'onShown', 'positionClass', 'preventDuplicates', 'progressBar', 'progressClass', 'rtl', 'showDuration', 'showEasing', 'showMethod', 'tapToDismiss', 'target', 'timeOut', 'titleClass', 'toastClass'); diff --git a/src/Toastr/Prime/LICENSE b/src/Toastr/Prime/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Toastr/Prime/LICENSE +++ b/src/Toastr/Prime/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Toastr/Prime/README.md b/src/Toastr/Prime/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Toastr/Prime/README.md +++ b/src/Toastr/Prime/README.md @@ -36,7 +36,7 @@ Shining stars of our community:
      Younes KHOUBZA
      Younes KHOUBZA

      💻 📖 🚧
      Younes ENNAJI
      Younes ENNAJI

      💻 📖 🚧
      Salma Mourad
      Salma Mourad

      💵
      Nashwan Abdullah
      Nashwan Abdullah

      💵
      Arvid de Jong
      Arvid de Jong

      💵
      - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

      Made with ❤️ by Younes KHOUBZA

      +

      Made with ❤️ by Younes ENNAJI

      diff --git a/src/Toastr/Prime/Resources/assets/flasher-toastr.min.css b/src/Toastr/Prime/Resources/assets/flasher-toastr.min.css deleted file mode 100644 index 9cc4a0d7..00000000 --- a/src/Toastr/Prime/Resources/assets/flasher-toastr.min.css +++ /dev/null @@ -1 +0,0 @@ -.toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#fff}.toast-message a:hover{color:#ccc;text-decoration:none}.toast-close-button{color:#fff;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);float:right;font-size:20px;font-weight:700;line-height:1;opacity:.8;position:relative;right:-.3em;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;top:-.3em}.toast-close-button:focus,.toast-close-button:hover{color:#000;cursor:pointer;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40);opacity:.4;text-decoration:none}.rtl .toast-close-button{float:left;left:-.3em;right:.3em}button.toast-close-button{-webkit-appearance:none;background:0 0;border:0;cursor:pointer;padding:0}.toast-top-center{right:0;top:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{right:0;top:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{left:12px;top:12px}.toast-top-right{right:12px;top:12px}.toast-bottom-right{bottom:12px;right:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{pointer-events:none;position:fixed;z-index:999999}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{background-position:15px;background-repeat:no-repeat;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#fff;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);margin:0 0 6px;opacity:.8;overflow:hidden;padding:15px 15px 15px 50px;pointer-events:auto;position:relative;width:300px}#toast-container>div.rtl{background-position:right 15px center;direction:rtl;padding:15px 50px 15px 15px}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;cursor:pointer;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);opacity:1}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{margin-left:auto;margin-right:auto;width:300px}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{margin-left:auto;margin-right:auto;width:96%}.toast{background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-warning{background-color:#f89406}.toast-progress{background-color:#000;bottom:0;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40);height:4px;left:0;opacity:.4;position:absolute}@media (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}} \ No newline at end of file diff --git a/src/Toastr/Prime/Resources/assets/flasher-toastr.min.js b/src/Toastr/Prime/Resources/assets/flasher-toastr.min.js deleted file mode 100644 index cea7d744..00000000 --- a/src/Toastr/Prime/Resources/assets/flasher-toastr.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("jquery")):"function"==typeof define&&define.amd?define(["@flasher/flasher","jquery"],t):((e="undefined"!=typeof globalThis?globalThis:e||self).flasher=e.flasher||{},e.flasher.toastr=t(e.flasher,e.jQuery))}(this,(function(e,t){"use strict";var o=function(){return o=Object.assign||function(e){for(var t,o=1,n=arguments.length;o=0;s--)d(e(n[s]),o)}(s)},remove:function(o){var n=h();t||u(n),o&&0===e(":focus",o).length?g(o):t.children().length&&t.remove()},error:function(e,t,o){return f({type:i,iconClass:h().iconClasses.error,message:e,optionsOverride:o,title:t})},getContainer:u,info:function(e,t,o){return f({type:a,iconClass:h().iconClasses.info,message:e,optionsOverride:o,title:t})},options:{},subscribe:function(e){o=e},success:function(e,t,o){return f({type:r,iconClass:h().iconClasses.success,message:e,optionsOverride:o,title:t})},version:"2.1.4",warning:function(e,t,o){return f({type:l,iconClass:h().iconClasses.warning,message:e,optionsOverride:o,title:t})}};return c;function u(o,n){return o||(o=h()),(t=e("#"+o.containerId)).length||n&&(t=function(o){return(t=e("
      ").attr("id",o.containerId).addClass(o.positionClass)).appendTo(e(o.target)),t}(o)),t}function d(t,o,n){var s=!(!n||!n.force)&&n.force;return!(!t||!s&&0!==e(":focus",t).length||(t[o.hideMethod]({duration:o.hideDuration,easing:o.hideEasing,complete:function(){g(t)}}),0))}function p(e){o&&o(e)}function f(o){var i=h(),a=o.iconClass||i.iconClass;if(void 0!==o.optionsOverride&&(i=e.extend(i,o.optionsOverride),a=o.optionsOverride.iconClass||a),!function(e,t){if(e.preventDuplicates){if(t.message===n)return!0;n=t.message}return!1}(i,o)){s++,t=u(i,!0);var r=null,l=e("
      "),c=e("
      "),d=e("
      "),f=e("
      "),m=e(i.closeHtml),v={intervalId:null,hideEta:null,maxHideTime:null},C={toastId:s,state:"visible",startTime:new Date,options:i,map:o};return o.iconClass&&l.addClass(i.toastClass).addClass(a),function(){if(o.title){var e=o.title;i.escapeHtml&&(e=w(o.title)),c.append(e).addClass(i.titleClass),l.append(c)}}(),function(){if(o.message){var e=o.message;i.escapeHtml&&(e=w(o.message)),d.append(e).addClass(i.messageClass),l.append(d)}}(),i.closeButton&&(m.addClass(i.closeClass).attr("role","button"),l.prepend(m)),i.progressBar&&(f.addClass(i.progressClass),l.prepend(f)),i.rtl&&l.addClass("rtl"),i.newestOnTop?t.prepend(l):t.append(l),function(){var e="";switch(o.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}l.attr("aria-live",e)}(),l.hide(),l[i.showMethod]({duration:i.showDuration,easing:i.showEasing,complete:i.onShown}),i.timeOut>0&&(r=setTimeout(y,i.timeOut),v.maxHideTime=parseFloat(i.timeOut),v.hideEta=(new Date).getTime()+v.maxHideTime,i.progressBar&&(v.intervalId=setInterval(T,10))),i.closeOnHover&&l.hover(b,O),!i.onclick&&i.tapToDismiss&&l.click(y),i.closeButton&&m&&m.click((function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&!0!==e.cancelBubble&&(e.cancelBubble=!0),i.onCloseClick&&i.onCloseClick(e),y(!0)})),i.onclick&&l.click((function(e){i.onclick(e),y()})),p(C),i.debug&&console&&console.log(C),l}function w(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function y(t){var o=t&&!1!==i.closeMethod?i.closeMethod:i.hideMethod,n=t&&!1!==i.closeDuration?i.closeDuration:i.hideDuration,s=t&&!1!==i.closeEasing?i.closeEasing:i.hideEasing;if(!e(":focus",l).length||t)return clearTimeout(v.intervalId),l[o]({duration:n,easing:s,complete:function(){g(l),clearTimeout(r),i.onHidden&&"hidden"!==C.state&&i.onHidden(),C.state="hidden",C.endTime=new Date,p(C)}})}function O(){(i.timeOut>0||i.extendedTimeOut>0)&&(r=setTimeout(y,i.extendedTimeOut),v.maxHideTime=parseFloat(i.extendedTimeOut),v.hideEta=(new Date).getTime()+v.maxHideTime)}function b(){clearTimeout(r),v.hideEta=0,l.stop(!0,!0)[i.showMethod]({duration:i.showDuration,easing:i.showEasing})}function T(){var e=(v.hideEta-(new Date).getTime())/v.maxHideTime*100;f.width(e+"%")}}function h(){return e.extend({},{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},c.options)}function g(e){t||(t=u()),e.is(":visible")||(e.remove(),e=null,0===t.children().length&&(t.remove(),n=void 0))}}()},e.exports?e.exports=o(t):window.toastr=o(window.jQuery)}(s);var i=n(s.exports),a=new(function(){function e(){}return e.prototype.success=function(e,t,o){this.flash("success",e,t,o)},e.prototype.info=function(e,t,o){this.flash("info",e,t,o)},e.prototype.warning=function(e,t,o){this.flash("warning",e,t,o)},e.prototype.error=function(e,t,o){this.flash("error",e,t,o)},e.prototype.flash=function(e,t,o,n){var s=this.createNotification(e,t,o,n);this.renderOptions({}),this.render({notification:s})},e.prototype.createNotification=function(e,t,o,n){if("object"==typeof e?(e=(n=e).type,t=n.message,o=n.title):"object"==typeof t?(t=(n=t).message,o=n.title):"object"==typeof o&&(o=(n=o).title),void 0===t)throw new Error("message option is required");return{type:e||"info",message:t,title:o,options:n}},e.prototype.render=function(e){var t=e.notification,o=t.message,n=t.title,s=t.options,a=t.type||"info",r=i[a](o,n,s);r.parent().attr("data-turbo-cache","false"),r.parent().addClass("fl-no-cache")},e.prototype.renderOptions=function(e){i.options=o({timeOut:e.timeOut||5e3,progressBar:e.progressBar||5e3},e)},e}());return e.addFactory("toastr",a),a})); diff --git a/src/Toastr/Prime/Resources/assets/index.ts b/src/Toastr/Prime/Resources/assets/index.ts new file mode 100644 index 00000000..b89e7fb1 --- /dev/null +++ b/src/Toastr/Prime/Resources/assets/index.ts @@ -0,0 +1,7 @@ +import flasher from '@flasher/flasher' +import ToastrPlugin from './toastr' + +const toastr = new ToastrPlugin() +flasher.addPlugin('toastr', toastr) + +export default toastr diff --git a/src/Toastr/Prime/Resources/assets/jquery.min.js b/src/Toastr/Prime/Resources/assets/jquery.min.js deleted file mode 100644 index e7e29d5b..00000000 --- a/src/Toastr/Prime/Resources/assets/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.0",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},R=function(){V()},M=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&z(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function X(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function z(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"
      Younes KHOUBZA
      Younes KHOUBZA

      💻 📖 🚧
      Younes ENNAJI
      Younes ENNAJI

      💻 📖 🚧
      Salma Mourad
      Salma Mourad

      💵
      Nashwan Abdullah
      Nashwan Abdullah

      💵
      Arvid de Jong
      Arvid de Jong

      💵
      ","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Me(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return R(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return R(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 { + const { message, title, type, options } = envelope + const instance = toastr[type as ToastrType](message, title, options as ToastrOptions) + instance && instance.parent().attr('data-turbo-cache', 'false') + }) + } + + public renderOptions(options: Options): void { + toastr.options = { + timeOut: (options.timeOut || 5000) as unknown as number, + progressBar: (options.progressBar || true) as unknown as boolean, + ...options, + } as ToastrOptions + } +} diff --git a/src/Toastr/Prime/Resources/dist/flasher-toastr.esm.js b/src/Toastr/Prime/Resources/dist/flasher-toastr.esm.js new file mode 100644 index 00000000..410dfbb9 --- /dev/null +++ b/src/Toastr/Prime/Resources/dist/flasher-toastr.esm.js @@ -0,0 +1,66 @@ +import flasher from '@flasher/flasher'; +import toastr$1 from 'toastr'; + +class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } +} + +class ToastrPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + envelopes.forEach((envelope) => { + const { message, title, type, options } = envelope; + const instance = toastr$1[type](message, title, options); + instance && instance.parent().attr('data-turbo-cache', 'false'); + }); + } + renderOptions(options) { + toastr$1.options = Object.assign({ timeOut: (options.timeOut || 5000), progressBar: (options.progressBar || true) }, options); + } +} + +const toastr = new ToastrPlugin(); +flasher.addPlugin('toastr', toastr); + +export { toastr as default }; diff --git a/src/Toastr/Prime/Resources/dist/flasher-toastr.js b/src/Toastr/Prime/Resources/dist/flasher-toastr.js new file mode 100644 index 00000000..5dd2fe3c --- /dev/null +++ b/src/Toastr/Prime/Resources/dist/flasher-toastr.js @@ -0,0 +1,71 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@flasher/flasher'), require('toastr')) : + typeof define === 'function' && define.amd ? define(['@flasher/flasher', 'toastr'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.toastr = factory(global.flasher, global.toastr)); +})(this, (function (flasher, toastr$1) { 'use strict'; + + class AbstractPlugin { + success(message, title, options) { + this.flash('success', message, title, options); + } + error(message, title, options) { + this.flash('error', message, title, options); + } + info(message, title, options) { + this.flash('info', message, title, options); + } + warning(message, title, options) { + this.flash('warning', message, title, options); + } + flash(type, message, title, options) { + if (typeof type === 'object') { + options = type; + type = options.type; + message = options.message; + title = options.title; + } + else if (typeof message === 'object') { + options = message; + message = options.message; + title = options.title; + } + else if (typeof title === 'object') { + options = title; + title = options.title; + } + if (undefined === message) { + throw new Error('message option is required'); + } + const envelope = { + type, + message, + title: title || type, + options: options || {}, + metadata: { + plugin: '', + }, + }; + this.renderOptions(options || {}); + this.renderEnvelopes([envelope]); + } + } + + class ToastrPlugin extends AbstractPlugin { + renderEnvelopes(envelopes) { + envelopes.forEach((envelope) => { + const { message, title, type, options } = envelope; + const instance = toastr$1[type](message, title, options); + instance && instance.parent().attr('data-turbo-cache', 'false'); + }); + } + renderOptions(options) { + toastr$1.options = Object.assign({ timeOut: (options.timeOut || 5000), progressBar: (options.progressBar || true) }, options); + } + } + + const toastr = new ToastrPlugin(); + flasher.addPlugin('toastr', toastr); + + return toastr; + +})); diff --git a/src/Toastr/Prime/Resources/dist/flasher-toastr.min.js b/src/Toastr/Prime/Resources/dist/flasher-toastr.min.js new file mode 100644 index 00000000..a5344970 --- /dev/null +++ b/src/Toastr/Prime/Resources/dist/flasher-toastr.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("toastr")):"function"==typeof define&&define.amd?define(["@flasher/flasher","toastr"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).toastr=t(e.flasher,e.toastr)}(this,(function(e,t){"use strict";class s{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,o){if("object"==typeof e?(e=(o=e).type,t=o.message,s=o.title):"object"==typeof t?(t=(o=t).message,s=o.title):"object"==typeof s&&(s=(o=s).title),void 0===t)throw new Error("message option is required");const r={type:e,message:t,title:s||e,options:o||{},metadata:{plugin:""}};this.renderOptions(o||{}),this.renderEnvelopes([r])}}const o=new class extends s{renderEnvelopes(e){e.forEach((e=>{const{message:s,title:o,type:r,options:i}=e,n=t[r](s,o,i);n&&n.parent().attr("data-turbo-cache","false")}))}renderOptions(e){t.options=Object.assign({timeOut:e.timeOut||5e3,progressBar:e.progressBar||!0},e)}};return e.addPlugin("toastr",o),o})); diff --git a/src/Toastr/Prime/Resources/dist/index.d.ts b/src/Toastr/Prime/Resources/dist/index.d.ts new file mode 100644 index 00000000..afe5973c --- /dev/null +++ b/src/Toastr/Prime/Resources/dist/index.d.ts @@ -0,0 +1,3 @@ +import ToastrPlugin from './toastr'; +declare const toastr: ToastrPlugin; +export default toastr; diff --git a/src/Toastr/Prime/Resources/dist/toastr.d.ts b/src/Toastr/Prime/Resources/dist/toastr.d.ts new file mode 100644 index 00000000..caa1e82f --- /dev/null +++ b/src/Toastr/Prime/Resources/dist/toastr.d.ts @@ -0,0 +1,6 @@ +import { AbstractPlugin } from '@flasher/flasher/dist/plugin'; +import type { Envelope, Options } from '@flasher/flasher/dist/types'; +export default class ToastrPlugin extends AbstractPlugin { + renderEnvelopes(envelopes: Envelope[]): void; + renderOptions(options: Options): void; +} diff --git a/src/Toastr/Prime/Resources/package.json b/src/Toastr/Prime/Resources/package.json new file mode 100644 index 00000000..e1e9a6c6 --- /dev/null +++ b/src/Toastr/Prime/Resources/package.json @@ -0,0 +1,20 @@ +{ + "name": "@flasher/flasher-toastr", + "version": "2.0.0", + "type": "module", + "license": "MIT", + "main": "dist/flasher-toastr.cjs.js", + "module": "dist/flasher-toastr.esm.js", + "browser": "dist/flasher-toastr.umd.js", + "types": "dist/toastr.d.ts", + "scripts": { + "ncu": "ncu -u" + }, + "peerDependencies": { + "toastr": "^2.1.4", + "@flasher/flasher": "^2.0.0" + }, + "devDependencies": { + "@types/toastr": "^2.1.43" + } +} diff --git a/src/Toastr/Prime/Resources/public/flasher-toastr.min.js b/src/Toastr/Prime/Resources/public/flasher-toastr.min.js new file mode 100644 index 00000000..a5344970 --- /dev/null +++ b/src/Toastr/Prime/Resources/public/flasher-toastr.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("toastr")):"function"==typeof define&&define.amd?define(["@flasher/flasher","toastr"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).toastr=t(e.flasher,e.toastr)}(this,(function(e,t){"use strict";class s{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,o){if("object"==typeof e?(e=(o=e).type,t=o.message,s=o.title):"object"==typeof t?(t=(o=t).message,s=o.title):"object"==typeof s&&(s=(o=s).title),void 0===t)throw new Error("message option is required");const r={type:e,message:t,title:s||e,options:o||{},metadata:{plugin:""}};this.renderOptions(o||{}),this.renderEnvelopes([r])}}const o=new class extends s{renderEnvelopes(e){e.forEach((e=>{const{message:s,title:o,type:r,options:i}=e,n=t[r](s,o,i);n&&n.parent().attr("data-turbo-cache","false")}))}renderOptions(e){t.options=Object.assign({timeOut:e.timeOut||5e3,progressBar:e.progressBar||!0},e)}};return e.addPlugin("toastr",o),o})); diff --git a/src/Toastr/Prime/Resources/public/jquery.min.js b/src/Toastr/Prime/Resources/public/jquery.min.js new file mode 100644 index 00000000..7f37b5d9 --- /dev/null +++ b/src/Toastr/Prime/Resources/public/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0div{position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#FFF;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>div.rtl{direction:rtl;padding:15px 50px 15px 15px;background-position:right 15px center}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin-left:auto;margin-right:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin-left:auto;margin-right:auto}.toast{background-color:#030303}.toast-success{background-color:#51A351}.toast-error{background-color:#BD362F}.toast-info{background-color:#2F96B4}.toast-warning{background-color:#F89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}} \ No newline at end of file diff --git a/src/Toastr/Prime/Resources/public/toastr.min.js b/src/Toastr/Prime/Resources/public/toastr.min.js new file mode 100644 index 00000000..06e4814f --- /dev/null +++ b/src/Toastr/Prime/Resources/public/toastr.min.js @@ -0,0 +1,2 @@ +!function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return g({type:O.error,iconClass:m().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=m()),v=e("#"+t.containerId),v.length?v:(n&&(v=d(t)),v)}function o(e,t,n){return g({type:O.info,iconClass:m().iconClasses.info,message:e,optionsOverride:n,title:t})}function s(e){C=e}function i(e,t,n){return g({type:O.success,iconClass:m().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return g({type:O.warning,iconClass:m().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e,t){var o=m();v||n(o),u(e,o,t)||l(o)}function c(t){var o=m();return v||n(o),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function l(t){for(var n=v.children(),o=n.length-1;o>=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("
      ").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e("
      "),M=e("
      "),B=e("
      "),q=e("
      "),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.4",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)}); +//# sourceMappingURL=toastr.js.map diff --git a/src/Toastr/Prime/Toastr.php b/src/Toastr/Prime/Toastr.php new file mode 100644 index 00000000..66ebc14e --- /dev/null +++ b/src/Toastr/Prime/Toastr.php @@ -0,0 +1,18 @@ +storageManager); + } +} diff --git a/src/Toastr/Prime/ToastrBuilder.php b/src/Toastr/Prime/ToastrBuilder.php index a679a8c7..2bc6aabf 100644 --- a/src/Toastr/Prime/ToastrBuilder.php +++ b/src/Toastr/Prime/ToastrBuilder.php @@ -1,66 +1,38 @@ - */ +declare(strict_types=1); namespace Flasher\Toastr\Prime; use Flasher\Prime\Notification\NotificationBuilder; -/** - * @SuppressWarnings(PHPMD.TooManyMethods) - * @SuppressWarnings(PHPMD.TooManyPublicMethods) - */ final class ToastrBuilder extends NotificationBuilder { /** * Enable a close button. - * - * @param bool $closeButton - * - * @return static */ - public function closeButton($closeButton = true) + public function closeButton(bool $closeButton = true): self { $this->option('closeButton', $closeButton); return $this; } - /** - * @param string $closeClass - * - * @return static - */ - public function closeClass($closeClass) + public function closeClass(string $closeClass): self { - $this->closeButton(); - $this->option('closeClass', $closeClass); return $this; } - /** - * @param int $closeDuration - * - * @return static - */ - public function closeDuration($closeDuration) + public function closeDuration(int $closeDuration): self { $this->option('closeDuration', $closeDuration); return $this; } - /** - * @param string $closeEasing - * - * @return static - */ - public function closeEasing($closeEasing) + public function closeEasing(string $closeEasing): self { $this->option('closeEasing', $closeEasing); @@ -69,60 +41,36 @@ final class ToastrBuilder extends NotificationBuilder /** * Override the close button's HTML. - * - * @param string $closeHtml - * - * @return static */ - public function closeHtml($closeHtml) + public function closeHtml(string $closeHtml): self { $this->option('closeHtml', $closeHtml); return $this; } - /** - * @param string $closeMethod - * - * @return static - */ - public function closeMethod($closeMethod) + public function closeMethod(string $closeMethod): self { $this->option('closeMethod', $closeMethod); return $this; } - /** - * @param bool $closeOnHover - * - * @return static - */ - public function closeOnHover($closeOnHover = true) + public function closeOnHover(bool $closeOnHover = true): self { $this->option('closeOnHover', $closeOnHover); return $this; } - /** - * @param string $containerId - * - * @return static - */ - public function containerId($containerId) + public function containerId(string $containerId): self { $this->option('containerId', $containerId); return $this; } - /** - * @param bool $debug - * - * @return static - */ - public function debug($debug = true) + public function debug(bool $debug = true): self { $this->option('debug', $debug); @@ -131,12 +79,8 @@ final class ToastrBuilder extends NotificationBuilder /** * In case you want to escape HTML characters in title and message. - * - * @param bool $escapeHtml - * - * @return static */ - public function escapeHtml($escapeHtml = true) + public function escapeHtml(bool $escapeHtml = true): self { $this->option('escapeHtml', $escapeHtml); @@ -145,12 +89,8 @@ final class ToastrBuilder extends NotificationBuilder /** * How long the toast will display after a user hovers over it. - * - * @param int $extendedTimeOut - * - * @return static */ - public function extendedTimeOut($extendedTimeOut) + public function extendedTimeOut(int $extendedTimeOut): self { $this->option('extendedTimeOut', $extendedTimeOut); @@ -159,12 +99,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Specifies the time during which the pop-up closes in ms. - * - * @param int $hideDuration - * - * @return static */ - public function hideDuration($hideDuration) + public function hideDuration(int $hideDuration): self { $this->option('hideDuration', $hideDuration); @@ -173,12 +109,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Indicates the entry transition of the pop-up. - * - * @param string $hideEasing - * - * @return static */ - public function hideEasing($hideEasing) + public function hideEasing(string $hideEasing): self { $this->option('hideEasing', $hideEasing); @@ -187,36 +119,22 @@ final class ToastrBuilder extends NotificationBuilder /** * Indicates the opening animation of the pop-up. - * - * @param string $hideMethod - * - * @return static */ - public function hideMethod($hideMethod) + public function hideMethod(string $hideMethod): self { $this->option('hideMethod', $hideMethod); return $this; } - /** - * @param string $iconClass - * - * @return static - */ - public function iconClass($iconClass) + public function iconClass(string $iconClass): self { $this->option('iconClass', $iconClass); return $this; } - /** - * @param string $messageClass - * - * @return static - */ - public function messageClass($messageClass) + public function messageClass(string $messageClass): self { $this->option('messageClass', $messageClass); @@ -225,48 +143,29 @@ final class ToastrBuilder extends NotificationBuilder /** * Show newest toast at bottom (top is default). - * - * @param bool $newestOnTop - * - * @return static */ - public function newestOnTop($newestOnTop = true) + public function newestOnTop(bool $newestOnTop = true): self { $this->option('newestOnTop', $newestOnTop); return $this; } - /** - * @param string $onHidden - * - * @return static - */ - public function onHidden($onHidden) + public function onHidden(string $onHidden): self { $this->option('onHidden', $onHidden); return $this; } - /** - * @param string $onShown - * - * @return static - */ - public function onShown($onShown) + public function onShown(string $onShown): self { $this->option('onShown', $onShown); return $this; } - /** - * @param string $positionClass - * - * @return static - */ - public function positionClass($positionClass) + public function positionClass(string $positionClass): self { $this->option('positionClass', $positionClass); @@ -276,12 +175,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Rather than having identical toasts stack, set the preventDuplicates property to true. Duplicates are matched to * the previous toast based on their message content. - * - * @param bool $preventDuplicates - * - * @return static */ - public function preventDuplicates($preventDuplicates = true) + public function preventDuplicates(bool $preventDuplicates = true): self { $this->option('preventDuplicates', $preventDuplicates); @@ -290,24 +185,15 @@ final class ToastrBuilder extends NotificationBuilder /** * Visually indicate how long before a toast expires. - * - * @param bool $progressBar - * - * @return static */ - public function progressBar($progressBar = true) + public function progressBar(bool $progressBar = true): self { $this->option('progressBar', $progressBar); return $this; } - /** - * @param string $progressClass - * - * @return static - */ - public function progressClass($progressClass) + public function progressClass(string $progressClass): self { $this->option('progressClass', $progressClass); @@ -316,12 +202,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Flip the toastr to be displayed properly for right-to-left languages. - * - * @param bool $rtl - * - * @return static */ - public function rtl($rtl = true) + public function rtl(bool $rtl = true): self { $this->option('rtl', $rtl); @@ -330,12 +212,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Specifies the time during which the pop-up opens in ms. - * - * @param int $showDuration - * - * @return static */ - public function showDuration($showDuration) + public function showDuration(int $showDuration): self { $this->option('showDuration', $showDuration); @@ -344,12 +222,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Indicates the entry transition of the pop-up. - * - * @param string $showEasing - * - * @return static */ - public function showEasing($showEasing) + public function showEasing(string $showEasing): self { $this->option('showEasing', $showEasing); @@ -358,12 +232,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Indicates the opening animation of the pop-up. - * - * @param string $showMethod - * - * @return static */ - public function showMethod($showMethod) + public function showMethod(string $showMethod): self { $this->option('showMethod', $showMethod); @@ -372,24 +242,15 @@ final class ToastrBuilder extends NotificationBuilder /** * Forces the user to validate the pop-up before closing. - * - * @param bool $tapToDismiss - * - * @return static */ - public function tapToDismiss($tapToDismiss = true) + public function tapToDismiss(bool $tapToDismiss = true): self { $this->option('tapToDismiss', $tapToDismiss); return $this; } - /** - * @param string $target - * - * @return static - */ - public function target($target) + public function target(string $target): self { $this->option('target', $target); @@ -398,13 +259,8 @@ final class ToastrBuilder extends NotificationBuilder /** * How long the toast will display without user interaction. - * - * @param int $timeOut - * @param int $extendedTimeOut - * - * @return static */ - public function timeOut($timeOut, $extendedTimeOut = null) + public function timeOut(int $timeOut, ?int $extendedTimeOut = null): self { $this->option('timeOut', $timeOut); @@ -415,24 +271,14 @@ final class ToastrBuilder extends NotificationBuilder return $this; } - /** - * @param string $titleClass - * - * @return static - */ - public function titleClass($titleClass) + public function titleClass(string $titleClass): self { $this->option('titleClass', $titleClass); return $this; } - /** - * @param string $toastClass - * - * @return static - */ - public function toastClass($toastClass) + public function toastClass(string $toastClass): self { $this->option('toastClass', $toastClass); @@ -441,10 +287,8 @@ final class ToastrBuilder extends NotificationBuilder /** * Prevent from Auto Hiding. - * - * @return static */ - public function persistent() + public function persistent(): self { $this->timeOut(0); $this->extendedTimeOut(0); diff --git a/src/Toastr/Prime/ToastrFactory.php b/src/Toastr/Prime/ToastrFactory.php deleted file mode 100644 index 2838e93f..00000000 --- a/src/Toastr/Prime/ToastrFactory.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -namespace Flasher\Toastr\Prime; - -use Flasher\Prime\Factory\NotificationFactory; -use Flasher\Prime\Notification\Notification; - -/** - * @mixin ToastrBuilder - */ -final class ToastrFactory extends NotificationFactory -{ - /** - * {@inheritdoc} - */ - public function createNotificationBuilder() - { - return new ToastrBuilder($this->getStorageManager(), new Notification(), 'toastr'); - } -} diff --git a/src/Toastr/Prime/ToastrInterface.php b/src/Toastr/Prime/ToastrInterface.php new file mode 100644 index 00000000..f939ae6e --- /dev/null +++ b/src/Toastr/Prime/ToastrInterface.php @@ -0,0 +1,14 @@ + - */ +declare(strict_types=1); namespace Flasher\Toastr\Prime; use Flasher\Prime\Plugin\Plugin; -class ToastrPlugin extends Plugin +final class ToastrPlugin extends Plugin { - /** - * {@inheritdoc} - */ - public function getScripts() + public function getAlias(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js', - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-toastr@1.3.2/dist/flasher-toastr.min.js', - ), - 'local' => array( - '/vendor/flasher/jquery.min.js', - '/vendor/flasher/flasher-toastr.min.js', - ), - ); + return 'toastr'; } - /** - * {@inheritdoc} - */ - public function getStyles() + public function getFactory(): string { - return array( - 'cdn' => array( - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-toastr@1.3.2/dist/flasher-toastr.min.css', - ), - 'local' => array( - '/vendor/flasher/flasher-toastr.min.css', - ), - ); + return Toastr::class; + } + + public function getServiceAliases(): string + { + return ToastrInterface::class; + } + + public function getScripts(): string|array + { + return [ + '/vendor/flasher/jquery.min.js', + '/vendor/flasher/toastr.min.js', + '/vendor/flasher/flasher-toastr.min.js', + ]; + } + + public function getStyles(): string|array + { + return [ + '/vendor/flasher/toastr.min.css', + ]; } } diff --git a/src/Toastr/Prime/composer.json b/src/Toastr/Prime/composer.json index 07e106ff..c4993bb8 100644 --- a/src/Toastr/Prime/composer.json +++ b/src/Toastr/Prime/composer.json @@ -1,51 +1,46 @@ { "name": "php-flasher/flasher-toastr", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "library", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher Toastr - An extension for PHPFlasher to integrate Toastr notifications seamlessly in Laravel or Symfony. Enhances UX with elegant, responsive toast messages.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Toastr\\Prime\\": "" }, "files": [ + "functions.php", "helpers.php" ] }, diff --git a/src/Toastr/Prime/functions.php b/src/Toastr/Prime/functions.php new file mode 100644 index 00000000..1b31998c --- /dev/null +++ b/src/Toastr/Prime/functions.php @@ -0,0 +1,42 @@ + $options additional options for the Toastr notification + * @param string|null $title the title of the notification + * + * @return Envelope|ToastrInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of ToastrInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Toastr factory: $toastr = toastr(); + * 2. With arguments - Create and return a Toastr notification: + * toastr('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); + */ + function toastr(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|ToastrInterface + { + $factory = FlasherContainer::create('flasher.toastr'); + + if (0 === \func_num_args()) { + return $factory; + } + + return $factory->flash($type, $message, $options, $title); + } +} diff --git a/src/Toastr/Prime/helpers.php b/src/Toastr/Prime/helpers.php index 46de6791..74e0f9ef 100644 --- a/src/Toastr/Prime/helpers.php +++ b/src/Toastr/Prime/helpers.php @@ -1,33 +1,41 @@ - */ +declare(strict_types=1); use Flasher\Prime\Container\FlasherContainer; use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\NotificationInterface; -use Flasher\Toastr\Prime\ToastrFactory; +use Flasher\Prime\Notification\Type; +use Flasher\Toastr\Prime\ToastrInterface; if (!function_exists('toastr')) { /** - * @param string $message - * @param string $type - * @param string $title - * @param array $options + * Creates a Toastr notification or returns the Toastr factory. * - * @return Envelope|ToastrFactory + * This function simplifies the process of creating Toastr notifications. + * When called with no arguments, it returns an instance of ToastrInterface. + * When called with arguments, it creates a Toastr notification and returns an Envelope. + * + * @param string|null $message the message content of the notification + * @param string $type The type of the notification (e.g., success, error, warning, info). + * @param array $options additional options for the Toastr notification + * @param string|null $title the title of the notification + * + * @return Envelope|ToastrInterface Returns an Envelope containing the notification details when arguments are provided. + * Returns an instance of ToastrInterface when no arguments are provided. + * + * Usage: + * 1. Without arguments - Get the Toastr factory: $toastr = toastr(); + * 2. With arguments - Create and return a Toastr notification: + * toastr('Message', Type::SUCCESS, ['option' => 'value'], 'Title'); */ - function toastr($message = null, $type = NotificationInterface::SUCCESS, $title = '', array $options = array()) + function toastr(?string $message = null, string $type = Type::SUCCESS, array $options = [], ?string $title = null): Envelope|ToastrInterface { - /** @var ToastrFactory $factory */ $factory = FlasherContainer::create('flasher.toastr'); if (0 === func_num_args()) { return $factory; } - return $factory->title($title)->addFlash($type, $message, $options); + return $factory->flash($type, $message, $options, $title); } } diff --git a/src/Toastr/Symfony/.github/FUNDING.yml b/src/Toastr/Symfony/.github/FUNDING.yml index c3863630..895dabf5 100644 --- a/src/Toastr/Symfony/.github/FUNDING.yml +++ b/src/Toastr/Symfony/.github/FUNDING.yml @@ -1,5 +1,2 @@ github: yoeunes -patreon: yoeunes -ko_fi: yoeunes -open_collective: php-flasher custom: https://www.paypal.com/paypalme/yoeunes diff --git a/src/Toastr/Symfony/.github/workflows/auto_closer.yaml b/src/Toastr/Symfony/.github/workflows/auto_closer.yaml index f807ac59..ba4fb618 100644 --- a/src/Toastr/Symfony/.github/workflows/auto_closer.yaml +++ b/src/Toastr/Symfony/.github/workflows/auto_closer.yaml @@ -2,21 +2,22 @@ name: Auto Closer PR on: pull_request_target: - types: [opened] + types: [ opened ] jobs: run: + name: 🤖 PR Auto-Closure runs-on: ubuntu-latest steps: - - uses: superbrothers/close-pull-request@v3 - with: - comment: | - Hi, thank you for your contribution. + - uses: superbrothers/close-pull-request@v3 + with: + comment: | + Hi there 👋, - Unfortunately, this repository is read-only. It's a split from our main monorepo repository. + First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository. - We'd like to kindly ask you to move the contribution there - https://github.com/php-flasher/php-flasher. + 🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher. - We'll check it, review it and give you feed back right way. + Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️ - Thank you. + Thanks again for your understanding and cooperation. We really appreciate it! 🙌 diff --git a/src/Toastr/Symfony/FlasherToastrBundle.php b/src/Toastr/Symfony/FlasherToastrBundle.php new file mode 100644 index 00000000..007d4d4b --- /dev/null +++ b/src/Toastr/Symfony/FlasherToastrBundle.php @@ -0,0 +1,17 @@ + - */ - -namespace Flasher\Toastr\Symfony; - -use Flasher\Symfony\Support\Bundle; -use Flasher\Toastr\Prime\ToastrPlugin; - -final class FlasherToastrSymfonyBundle extends Bundle // Symfony\Component\HttpKernel\Bundle\Bundle -{ - /** - * {@inheritdoc} - */ - public function createPlugin() - { - return new ToastrPlugin(); - } -} diff --git a/src/Toastr/Symfony/LICENSE b/src/Toastr/Symfony/LICENSE index 8e94bc16..cf3a76d6 100644 --- a/src/Toastr/Symfony/LICENSE +++ b/src/Toastr/Symfony/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 PHPFlasher +Copyright (c) 2024 PHPFlasher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Toastr/Symfony/README.md b/src/Toastr/Symfony/README.md index 70a05eb4..cd352ed2 100644 --- a/src/Toastr/Symfony/README.md +++ b/src/Toastr/Symfony/README.md @@ -36,7 +36,7 @@ Shining stars of our community: - + @@ -64,11 +64,11 @@ You can reach out with questions, bug reports, or feature requests on any of the - [Github Issues](https://github.com/php-flasher/php-flasher/issues) - [Github](https://github.com/yoeunes) - [Twitter](https://twitter.com/yoeunes) -- [Linkedin](https://www.linkedin.com/in/younes-khoubza/) -- [Email me directly](mailto:younes.khoubza@gmail.com) +- [Linkedin](https://www.linkedin.com/in/younes--ennaji//) +- [Email me directly](mailto:younes.ennaji.pro@gmail.com) ## License PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -

      Made with ❤️ by Younes KHOUBZA

      +

      Made with ❤️ by Younes ENNAJI

      diff --git a/src/Toastr/Symfony/Resources/config/config.yaml b/src/Toastr/Symfony/Resources/config/config.yaml deleted file mode 100644 index a4555e16..00000000 --- a/src/Toastr/Symfony/Resources/config/config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -flasher_toastr: - scripts: - cdn: - - 'https://cdn.jsdelivr.net/npm/jquery@3.6.3/dist/jquery.min.js' - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-toastr@1.3.2/dist/flasher-toastr.min.js' - local: - - '/vendor/flasher/jquery.min.js' - - '/vendor/flasher/flasher-toastr.min.js' - - styles: - cdn: - - 'https://cdn.jsdelivr.net/npm/@flasher/flasher-toastr@1.3.2/dist/flasher-toastr.min.css' - local: - - '/vendor/flasher/flasher-toastr.min.css' diff --git a/src/Toastr/Symfony/composer.json b/src/Toastr/Symfony/composer.json index da31e0ea..cba69002 100644 --- a/src/Toastr/Symfony/composer.json +++ b/src/Toastr/Symfony/composer.json @@ -1,47 +1,41 @@ { "name": "php-flasher/flasher-toastr-symfony", - "description": "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution.", - "license": "MIT", "type": "symfony-bundle", + "license": "MIT", + "homepage": "https://php-flasher.io", + "description": "PHPFlasher Toastr Symfony Bundle - Leverages PHPFlasher for integrating Toastr notifications in Symfony projects. Offers a rich set of features for enhanced user notifications.", "keywords": [ - "php-flasher", "flash-messages", - "notification-system", - "user-feedback", - "toastr", - "sweetalert", - "pnotify", - "noty", - "notyf", - "desktop-notifications", - "php", - "laravel", - "symfony", - "javascript", - "yoeunes", - "framework-agnostic", - "phpstorm-auto-complete", - "custom-adapter", - "user-experience", - "rtl", - "dark-mode" + "php-notification-system", + "laravel-notification", + "symfony-notification", + "user-feedback-tools", + "web-application-notifications", + "php-user-interface", + "customizable-alerts-php", + "interactive-web-notifications", + "php-messaging-library", + "user-engagement-php" ], + "support": { + "issues": "https://github.com/php-flasher/php-flasher/issues", + "source": "https://github.com/php-flasher/php-flasher" + }, "authors": [ { - "name": "Younes KHOUBZA", - "email": "younes.khoubza@gmail.com", - "homepage": "https://www.linkedin.com/in/younes-khoubza", + "name": "Younes ENNAJI", + "email": "younes.ennaji.pro@gmail.com", + "homepage": "https://www.linkedin.com/in/younes--ennaji/", "role": "Developer" } ], - "homepage": "https://php-flasher.io", - "require": { - "php": ">=5.3", - "php-flasher/flasher-symfony": "^1.15.14", - "php-flasher/flasher-toastr": "^1.15.14" - }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, + "require": { + "php": ">=8.2", + "php-flasher/flasher-symfony": "^2.0", + "php-flasher/flasher-toastr": "^2.0" + }, "autoload": { "psr-4": { "Flasher\\Toastr\\Symfony\\": "" diff --git a/taskfile.dist.yml b/taskfile.dist.yml new file mode 100644 index 00000000..311c3d63 --- /dev/null +++ b/taskfile.dist.yml @@ -0,0 +1,47 @@ +version: '3' + +tasks: + install: + desc: "📦 Install project dependencies using Composer." + cmds: + - composer install + aliases: + - i + - in + + update: + desc: "🔄 Update project dependencies to the lowest possible versions within the specified version constraints, ensuring compatibility." + cmds: + - composer update --prefer-lowest -W + - npm run ncu && npm install --force + aliases: + - u + - up + + require: + desc: "➕ Require a project dependency using Composer." + cmds: + - composer require {{ .CLI_ARGS }} + aliases: + - req + + lint: + desc: "🔍 Run various linting tools to ensure code quality, including PHP-CS-Fixer, PHPStan, Composer validation, and PHPLint." + cmds: + - vendor/bin/php-cs-fixer fix + - vendor/bin/phpstan analyse + - composer validate --strict + - vendor/bin/phplint + aliases: + - pint + - check + - validate + + test: + desc: "✅ Run PHPUnit tests to verify the correctness of the codebase." + cmds: + - vendor/bin/phpunit + aliases: + - tests + - phpunit + - unit diff --git a/tests/Laravel/Command/InstallCommandTest.php b/tests/Laravel/Command/InstallCommandTest.php new file mode 100644 index 00000000..74842204 --- /dev/null +++ b/tests/Laravel/Command/InstallCommandTest.php @@ -0,0 +1,49 @@ +assertStringContainsString('PHPFlasher resources have been successfully installed.', $output); + } + + public function testExecuteWithConfigOption(): void + { + Artisan::call('flasher:install', ['--config' => true]); + + $output = Artisan::output(); + + $this->assertStringContainsString('Configuration files have been published.', $output); + } + + public function testExecuteWithSymlinkOption(): void + { + Artisan::call('flasher:install', ['--symlink' => true]); + + $output = Artisan::output(); + + $this->assertStringContainsString('Assets were symlinked.', $output); + } + + public function testExecuteWithAllOptions(): void + { + Artisan::call('flasher:install', ['--config' => true, '--symlink' => true]); + + $output = Artisan::output(); + + $this->assertStringContainsString('PHPFlasher resources have been successfully installed.', $output); + $this->assertStringContainsString('Configuration files have been published.', $output); + $this->assertStringContainsString('Assets were symlinked.', $output); + } +} diff --git a/tests/Laravel/Component/FlasherComponentTest.php b/tests/Laravel/Component/FlasherComponentTest.php new file mode 100644 index 00000000..a9bcb70a --- /dev/null +++ b/tests/Laravel/Component/FlasherComponentTest.php @@ -0,0 +1,39 @@ +allows('render') + ->andReturns('Your expected result'); + + Container::getInstance()->instance('flasher', $flasherServiceMock); + + $this->flasherComponent = new FlasherComponent('{"key":"value"}', '{"key":"value"}'); + } + + public function testRender(): void + { + $expectedResult = 'Your expected result'; + $actualResult = $this->flasherComponent->render(); + $this->assertSame($expectedResult, $actualResult); + } +} diff --git a/tests/Laravel/Http/RequestTest.php b/tests/Laravel/Http/RequestTest.php new file mode 100644 index 00000000..75691e8f --- /dev/null +++ b/tests/Laravel/Http/RequestTest.php @@ -0,0 +1,102 @@ +laravelRequestMock = \Mockery::mock(LaravelRequest::class); + } + + public function testIsXmlHttpRequest(): void + { + $this->laravelRequestMock->expects('ajax')->andReturns(true); + + $request = new Request($this->laravelRequestMock); + + $this->assertTrue($request->isXmlHttpRequest()); + } + + public function testIsHtmlRequestFormat(): void + { + $this->laravelRequestMock->expects('acceptsHtml')->andReturns(true); + + $request = new Request($this->laravelRequestMock); + + $this->assertTrue($request->isHtmlRequestFormat()); + } + + public function testHasSession(): void + { + $this->laravelRequestMock->expects('hasSession')->andReturns(true); + + $request = new Request($this->laravelRequestMock); + + $this->assertTrue($request->hasSession()); + } + + public function testIsSessionStarted(): void + { + $sessionMock = \Mockery::mock(SessionStore::class); + $sessionMock->expects('isStarted')->andReturns(true); + + $this->laravelRequestMock->expects('session')->andReturns($sessionMock); + + $request = new Request($this->laravelRequestMock); + + $this->assertTrue($request->isSessionStarted()); + } + + public function testHasType(): void + { + $sessionMock = \Mockery::mock(SessionStore::class); + $sessionMock->expects('has')->with('type')->andReturns(true); + $sessionMock->expects('isStarted')->andReturns(true); + + $this->laravelRequestMock->expects('session')->twice()->andReturns($sessionMock); + $this->laravelRequestMock->expects('hasSession')->andReturn(true); + + $request = new Request($this->laravelRequestMock); + + $this->assertTrue($request->hasType('type')); + } + + public function testGetType(): void + { + $expectedValue = 'value'; + $sessionMock = \Mockery::mock(SessionStore::class); + $sessionMock->expects('get')->with('type')->andReturns($expectedValue); + + $this->laravelRequestMock->expects('session')->andReturns($sessionMock); + + $request = new Request($this->laravelRequestMock); + + $this->assertSame($expectedValue, $request->getType('type')); + } + + public function testForgetType(): void + { + $sessionMock = \Mockery::mock(SessionStore::class); + $sessionMock->expects('forget')->with('type'); + + $this->laravelRequestMock->expects('session')->andReturns($sessionMock); + + $request = new Request($this->laravelRequestMock); + + $request->forgetType('type'); + } +} diff --git a/tests/Laravel/Http/ResponseTest.php b/tests/Laravel/Http/ResponseTest.php new file mode 100644 index 00000000..ad533c5e --- /dev/null +++ b/tests/Laravel/Http/ResponseTest.php @@ -0,0 +1,168 @@ +responseHeaderBagMock = \Mockery::mock(ResponseHeaderBag::class); + + $this->responseMock = \Mockery::mock(LaravelResponse::class); + $this->responseMock->headers = $this->responseHeaderBagMock; + } + + public function testIsRedirection(): void + { + $this->responseMock->expects()->isRedirection()->andReturns(true); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isRedirection()); + } + + public function testIsJson(): void + { + $jsonResponseMock = \Mockery::mock(LaravelJsonResponse::class); + + $response = new Response($jsonResponseMock); + + $this->assertTrue($response->isJson()); + } + + public function testIsHtml(): void + { + $this->responseHeaderBagMock->expects()->get('Content-Type')->andReturns('text/html; charset=UTF-8'); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isHtml()); + } + + public function testIsAttachment(): void + { + $this->responseHeaderBagMock->expects()->get('Content-Disposition', '')->andReturns('attachment; filename="filename.jpg"'); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isAttachment()); + } + + public function testIsSuccessful(): void + { + $this->responseMock->expects()->isSuccessful()->andReturns(true); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isSuccessful()); + } + + public function testGetContent(): void + { + $expectedContent = 'response content'; + $this->responseMock->expects()->getContent()->andReturns($expectedContent); + + $response = new Response($this->responseMock); + + $this->assertSame($expectedContent, $response->getContent()); + } + + public function testSetContentOnLaravelResponseWithOriginalContent(): void + { + $originalContent = '

      Original

      '; + $newContent = 'New content'; + + $laravelResponse = \Mockery::mock(LaravelResponse::class); + $laravelResponse->allows('getOriginalContent')->andReturns($originalContent); + $laravelResponse->expects('setContent')->with($newContent); + $laravelResponse->original = null; // Simulate initial state + + $response = new Response($laravelResponse); + $response->setContent($newContent); + + $this->assertSame($originalContent, $laravelResponse->original); + } + + public function testSetContentOnLaravelResponseWithoutOriginalContent(): void + { + $newContent = 'New content'; + + $laravelResponse = \Mockery::mock(LaravelResponse::class); + $laravelResponse->allows('getOriginalContent')->andReturnNull(); + $laravelResponse->expects('setContent')->with($newContent); + $laravelResponse->original = null; // Simulate initial state + + $response = new Response($laravelResponse); + $response->setContent($newContent); + + $this->assertNull($laravelResponse->original); + } + + public function testSetContentOnJsonResponse(): void + { + $newContent = '{"message":"New content"}'; + + $laravelJsonResponse = \Mockery::mock(LaravelJsonResponse::class); + $laravelJsonResponse->expects('setContent')->with($newContent); + // JsonResponses don't usually handle `original` content, but let's ensure no side effects + $laravelJsonResponse->original = null; + + $response = new Response($laravelJsonResponse); + $response->setContent($newContent); + } + + public function testHasHeader(): void + { + $headerKey = 'X-Custom-Header'; + $this->responseHeaderBagMock->expects()->has($headerKey)->andReturns(true); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->hasHeader($headerKey)); + } + + public function testGetHeader(): void + { + $headerKey = 'X-Custom-Header'; + $headerValue = 'Value'; + $this->responseHeaderBagMock->expects()->get($headerKey)->andReturns($headerValue); + + $response = new Response($this->responseMock); + + $this->assertSame($headerValue, $response->getHeader($headerKey)); + } + + public function testSetHeader(): void + { + $headerKey = 'X-Custom-Header'; + $headerValue = 'Value'; + $this->responseHeaderBagMock->expects()->set($headerKey, $headerValue); + + $response = new Response($this->responseMock); + $response->setHeader($headerKey, $headerValue); + } + + public function testRemoveHeader(): void + { + $headerKey = 'X-Custom-Header'; + $this->responseHeaderBagMock->expects()->remove($headerKey); + + $response = new Response($this->responseMock); + $response->removeHeader($headerKey); + } +} diff --git a/tests/Laravel/Middleware/FlasherMiddlewareTest.php b/tests/Laravel/Middleware/FlasherMiddlewareTest.php new file mode 100644 index 00000000..6c0fd5a2 --- /dev/null +++ b/tests/Laravel/Middleware/FlasherMiddlewareTest.php @@ -0,0 +1,80 @@ +responseExtensionMock = \Mockery::mock(ResponseExtensionInterface::class); + $this->middleware = new FlasherMiddleware($this->responseExtensionMock); + } + + public function testHandle(): void + { + $laravelRequest = \Mockery::mock(LaravelRequest::class); + + $this->responseExtensionMock + ->expects('render') + ->with(\Mockery::type(Request::class), \Mockery::type(Response::class)) + ->andReturnUsing(function (Request $request, Response $response): Response { + $response->setContent('Modified content'); + + return $response; + }); + + /** @var LaravelResponse $response */ + $response = $this->middleware->handle($laravelRequest, fn ($r) => new LaravelResponse()); + $this->assertSame('Modified content', $response->getContent()); + } + + public function testHandleJsonResponse(): void + { + $laravelRequest = \Mockery::mock(LaravelRequest::class); + + $this->responseExtensionMock + ->expects('render') + ->with(\Mockery::type(Request::class), \Mockery::type(Response::class)) + ->andReturnUsing(function (Request $request, Response $response): Response { + $response->setContent(json_encode(['foo' => 'modified bar'], \JSON_THROW_ON_ERROR)); + + return $response; + }); + + /** @var LaravelResponse $response */ + $response = $this->middleware->handle( + $laravelRequest, + fn ($r) => new JsonResponse(['foo' => 'bar']) + ); + + $this->assertSame('{"foo":"modified bar"}', $response->getContent()); + } + + public function testHandleWithNonLaravelResponse(): void + { + $laravelRequest = \Mockery::mock(LaravelRequest::class); + + $this->responseExtensionMock->allows('render')->never(); + + $response = $this->middleware->handle($laravelRequest, fn ($r) => 'Not a Laravel Response'); + $this->assertSame('Not a Laravel Response', $response); + } +} diff --git a/tests/Laravel/Middleware/SessionMiddlewareTest.php b/tests/Laravel/Middleware/SessionMiddlewareTest.php new file mode 100644 index 00000000..ae1d5bbd --- /dev/null +++ b/tests/Laravel/Middleware/SessionMiddlewareTest.php @@ -0,0 +1,78 @@ +requestExtensionMock = \Mockery::mock(RequestExtensionInterface::class); + $this->sessionMiddleware = new SessionMiddleware($this->requestExtensionMock); + } + + public function testHandleWithLaravelResponse(): void + { + $requestMock = \Mockery::mock(LaravelRequest::class); + $responseMock = \Mockery::mock(LaravelResponse::class); + + $this->requestExtensionMock->expects('flash') + ->withArgs(function ($flasherRequest, $flasherResponse) { + return $flasherRequest instanceof Request && $flasherResponse instanceof Response; + }); + + $handle = $this->sessionMiddleware->handle($requestMock, fn () => $responseMock); + + $this->assertSame($responseMock, $handle); + } + + public function testHandleWithLaravelJsonResponse(): void + { + $requestMock = \Mockery::mock(LaravelRequest::class); + $responseMock = \Mockery::mock(LaravelJsonResponse::class); + + $this->requestExtensionMock->expects('flash') + ->withArgs(function ($flasherRequest, $flasherResponse) { + return $flasherRequest instanceof Request && $flasherResponse instanceof Response; + }); + + $handle = $this->sessionMiddleware->handle($requestMock, fn () => $responseMock); + + $this->assertSame($responseMock, $handle); + } + + public function testHandleWithOtherResponses(): void + { + $requestMock = \Mockery::mock(LaravelRequest::class); + $responseMock = \Mockery::mock(\Symfony\Component\HttpFoundation\Response::class); + + $this->requestExtensionMock->allows('flash')->never(); + + $handle = $this->sessionMiddleware->handle($requestMock, fn () => $responseMock); + + $this->assertSame($responseMock, $handle); + } +} diff --git a/tests/Laravel/ServiceProviderTest.php b/tests/Laravel/ServiceProviderTest.php index 627203ba..f0463b29 100644 --- a/tests/Laravel/ServiceProviderTest.php +++ b/tests/Laravel/ServiceProviderTest.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Laravel; @@ -11,47 +8,36 @@ use Flasher\Prime\FlasherInterface; final class ServiceProviderTest extends TestCase { - /** - * @return void - */ - public function testContainerContainServices() + public function testContainerContainServices(): void { $this->assertTrue($this->app->bound('flasher')); $this->assertTrue($this->app->bound('flasher.noty')); $this->assertTrue($this->app->bound('flasher.notyf')); - $this->assertTrue($this->app->bound('flasher.pnotify')); $this->assertTrue($this->app->bound('flasher.sweetalert')); $this->assertTrue($this->app->bound('flasher.toastr')); - $this->assertInstanceOf('Flasher\Prime\Flasher', $this->app->make('flasher')); - $this->assertInstanceOf('Flasher\Noty\Prime\NotyFactory', $this->app->make('flasher.noty')); - $this->assertInstanceOf('Flasher\Notyf\Prime\NotyfFactory', $this->app->make('flasher.notyf')); - $this->assertInstanceOf('Flasher\Pnotify\Prime\PnotifyFactory', $this->app->make('flasher.pnotify')); - $this->assertInstanceOf('Flasher\SweetAlert\Prime\SweetAlertFactory', $this->app->make('flasher.sweetalert')); - $this->assertInstanceOf('Flasher\Toastr\Prime\ToastrFactory', $this->app->make('flasher.toastr')); + $this->assertInstanceOf(\Flasher\Prime\Flasher::class, $this->app->make('flasher')); + $this->assertInstanceOf(\Flasher\Noty\Prime\Noty::class, $this->app->make('flasher.noty')); + $this->assertInstanceOf(\Flasher\Notyf\Prime\Notyf::class, $this->app->make('flasher.notyf')); + $this->assertInstanceOf(\Flasher\SweetAlert\Prime\SweetAlert::class, $this->app->make('flasher.sweetalert')); + $this->assertInstanceOf(\Flasher\Toastr\Prime\Toastr::class, $this->app->make('flasher.toastr')); } - /** - * @return void - */ - public function testFlasherCanCreateServicesFromAlias() + public function testFlasherCanCreateServicesFromAlias(): void { /** @var FlasherInterface $flasher */ $flasher = $this->app->make('flasher'); - $adapter = $flasher->create('noty'); - $this->assertInstanceOf('Flasher\Noty\Prime\NotyFactory', $adapter); + $adapter = $flasher->use('noty'); + $this->assertInstanceOf(\Flasher\Noty\Prime\Noty::class, $adapter); - $adapter = $flasher->create('notyf'); - $this->assertInstanceOf('Flasher\Notyf\Prime\NotyfFactory', $adapter); + $adapter = $flasher->use('notyf'); + $this->assertInstanceOf(\Flasher\Notyf\Prime\Notyf::class, $adapter); - $adapter = $flasher->create('pnotify'); - $this->assertInstanceOf('Flasher\Pnotify\Prime\PnotifyFactory', $adapter); + $adapter = $flasher->use('sweetalert'); + $this->assertInstanceOf(\Flasher\SweetAlert\Prime\SweetAlert::class, $adapter); - $adapter = $flasher->create('sweetalert'); - $this->assertInstanceOf('Flasher\SweetAlert\Prime\SweetAlertFactory', $adapter); - - $adapter = $flasher->create('toastr'); - $this->assertInstanceOf('Flasher\Toastr\Prime\ToastrFactory', $adapter); + $adapter = $flasher->use('toastr'); + $this->assertInstanceOf(\Flasher\Toastr\Prime\Toastr::class, $adapter); } } diff --git a/tests/Laravel/Storage/SessionBagTest.php b/tests/Laravel/Storage/SessionBagTest.php new file mode 100644 index 00000000..c05e94d6 --- /dev/null +++ b/tests/Laravel/Storage/SessionBagTest.php @@ -0,0 +1,62 @@ +sessionManagerMock = \Mockery::mock(SessionManager::class); + $this->sessionBag = new SessionBag($this->sessionManagerMock); + } + + public function testGet(): void + { + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $this->sessionManagerMock->expects() + ->get(SessionBag::ENVELOPES_NAMESPACE, []) + ->andReturns($envelopes); + + $this->assertEquals($envelopes, $this->sessionBag->get()); + } + + public function testSet(): void + { + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $this->sessionManagerMock->allows() + ->get(SessionBag::ENVELOPES_NAMESPACE, []) + ->andReturns($envelopes); + + $this->sessionManagerMock->expects() + ->put(SessionBag::ENVELOPES_NAMESPACE, $envelopes); + + $this->sessionBag->set($envelopes); + + $this->assertSame($envelopes, $this->sessionBag->get()); + } +} diff --git a/tests/Laravel/StorageTest.php b/tests/Laravel/StorageTest.php deleted file mode 100644 index bf8e4b89..00000000 --- a/tests/Laravel/StorageTest.php +++ /dev/null @@ -1,159 +0,0 @@ - - */ - -namespace Flasher\Tests\Laravel; - -use Flasher\Laravel\Storage\SessionBag; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\Notification; -use Flasher\Prime\Stamp\PriorityStamp; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Prime\Storage\StorageBag; - -final class StorageTest extends TestCase -{ - /** - * @return void - */ - public function testInitialState() - { - $storage = $this->getStorage(); - $this->assertEquals(array(), $storage->all()); - } - - /** - * @return void - */ - public function testAddEnvelope() - { - $storage = $this->getStorage(); - $envelope = new Envelope(new Notification()); - $storage->add($envelope); - - $this->assertEquals(array($envelope), $storage->all()); - } - - /** - * @return void - */ - public function testAddMultipleEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification()), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - } - - /** - * @return void - */ - public function testUpdateEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $envelopes[1]->withStamp(new PriorityStamp(1)); - $storage->update($envelopes[1]); - - $this->assertEquals($envelopes, $storage->all()); - $this->assertInstanceOf( - 'Flasher\Prime\Stamp\PriorityStamp', - $envelopes[1]->get('Flasher\Prime\Stamp\PriorityStamp') - ); - } - - /** - * @return void - */ - public function testRemoveEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $storage->remove($envelopes[1]); - $this->assertEquals(array($envelopes[0]), $storage->all()); - } - - /** - * @return void - */ - public function testRemoveMultipleEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $storage->remove($envelopes); - $this->assertEquals(array(), $storage->all()); - } - - /** - * @return void - */ - public function testClearAllEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $storage->clear(); - $this->assertEquals(array(), $storage->all()); - } - - /** - * @return StorageBag - */ - private function getStorage() - { - /** @var \Illuminate\Session\Store $session */ - $session = $this->app->make('session'); - - return new StorageBag(new SessionBag($session)); - } -} diff --git a/tests/Laravel/Support/LivewireListenerTest.php b/tests/Laravel/Support/LivewireListenerTest.php new file mode 100644 index 00000000..d88904ee --- /dev/null +++ b/tests/Laravel/Support/LivewireListenerTest.php @@ -0,0 +1,67 @@ + $requestMock); + + $componentMock = \Mockery::mock(Component::class); + $contextMock = \Mockery::mock(ComponentContext::class); + + $livewireManagerMock->expects('isLivewireRequest')->andReturns(false); + $flasherMock->expects('render')->never(); + + $livewireListener->__invoke($componentMock, $contextMock); + } + + public function testInvokeMethodDispatchNotifications(): void + { + $flasherMock = \Mockery::mock(FlasherInterface::class); + $livewireManagerMock = \Mockery::mock(LivewireManager::class); + $cspHandlerMock = \Mockery::mock(ContentSecurityPolicyHandlerInterface::class); + $requestMock = \Mockery::mock(LaravelRequest::class); + + $livewireListener = new LivewireListener($livewireManagerMock, $flasherMock, $cspHandlerMock, fn () => $requestMock); + + $componentMock = \Mockery::mock(Component::class); + $contextMock = \Mockery::mock(ComponentContext::class); + + $livewireManagerMock->expects('isLivewireRequest')->andReturns(true); + $cspHandlerMock->expects('getNonces')->andReturns(['csp_script_nonce' => null, 'csp_style_nonce' => null]); + + $componentMock->expects('getId')->andReturns('1'); + $componentMock->expects('getName')->andReturns('MyComponent'); + $contextMock->expects('addEffect'); + + $flasherMock + ->expects('render') + ->andReturns(['envelopes' => [new Envelope(new Notification(), new IdStamp('1111'))]]); + + $livewireListener->__invoke($componentMock, $contextMock); + } +} diff --git a/tests/Laravel/Template/BladeTemplateEngineTest.php b/tests/Laravel/Template/BladeTemplateEngineTest.php new file mode 100644 index 00000000..c2d0ba20 --- /dev/null +++ b/tests/Laravel/Template/BladeTemplateEngineTest.php @@ -0,0 +1,35 @@ + 'value']; + + $view = \Mockery::mock(View::class); + $view->allows('render')->andReturns('rendered data'); + + $blade = \Mockery::mock(Factory::class); + $blade->allows('make')->with($name, $context)->andReturns($view); + + $bladeTemplateEngine = new BladeTemplateEngine($blade); + + $result = $bladeTemplateEngine->render($name, $context); + + $this->assertIsString($result); + $this->assertSame('rendered data', $result); + } +} diff --git a/tests/Laravel/TestCase.php b/tests/Laravel/TestCase.php index 8c9542ec..45302e1b 100644 --- a/tests/Laravel/TestCase.php +++ b/tests/Laravel/TestCase.php @@ -1,93 +1,49 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Laravel; -use Flasher\Laravel\Support\Laravel; -use Illuminate\Config\Repository as Config; -use Illuminate\Foundation\AliasLoader; -use Illuminate\Foundation\Application; -use Illuminate\Http\Request; +use Illuminate\Config\Repository; use Illuminate\Support\Facades\Facade; -use Orchestra\Testbench\TestCase as Orchestra; +use Illuminate\Support\ServiceProvider; -class TestCase extends Orchestra +class TestCase extends \Orchestra\Testbench\TestCase { - public function createApplication() + /** + * @return array> + */ + protected function getPackageProviders($app): array { - if (0 !== strpos(Application::VERSION, '4.0')) { - return parent::createApplication(); - } - - $app = new Application(); - - $app->detectEnvironment(array( - 'local' => array('your-machine-name'), - )); - - $app->bindInstallPaths($this->getApplicationPaths()); - - $app['env'] = 'testing'; - - $app->instance('app', $app); - - Facade::clearResolvedInstances(); - Facade::setFacadeApplication($app); - - $config = new Config($app->getConfigLoader(), $app['env']); - $app->instance('config', $config); - $app->startExceptionHandling(); - - if ($app->runningInConsole()) { - $app->setRequestForConsoleEnvironment(); - } - - date_default_timezone_set($this->getApplicationTimezone()); - - $aliases = array_merge($this->getApplicationAliases(), $this->getPackageAliases()); - AliasLoader::getInstance($aliases)->register(); - - Request::enableHttpMethodParameterOverride(); - - $providers = array_merge($this->getApplicationProviders(), $this->getPackageProviders()); - $app->getProviderRepository()->load($app, $providers); - - $this->getEnvironmentSetUp($app); - - $app->boot(); - - return $app; + return [ + \Flasher\Laravel\FlasherServiceProvider::class, + \Flasher\Noty\Laravel\FlasherNotyServiceProvider::class, + \Flasher\Notyf\Laravel\FlasherNotyfServiceProvider::class, + \Flasher\SweetAlert\Laravel\FlasherSweetAlertServiceProvider::class, + \Flasher\Toastr\Laravel\FlasherToastrServiceProvider::class, + ]; } /** - * @param Application|null $app + * Override application aliases. * - * @return string[] + * @return array> */ - protected function getPackageProviders($app = null) + protected function getPackageAliases($app): array { - return array( - 'Flasher\Laravel\FlasherServiceProvider', - 'Flasher\Noty\Laravel\FlasherNotyServiceProvider', - 'Flasher\Notyf\Laravel\FlasherNotyfServiceProvider', - 'Flasher\Pnotify\Laravel\FlasherPnotifyServiceProvider', - 'Flasher\SweetAlert\Laravel\FlasherSweetAlertServiceProvider', - 'Flasher\Toastr\Laravel\FlasherToastrServiceProvider', - ); + return [ + 'Flasher' => \Flasher\Laravel\Facade\Flasher::class, + 'Noty' => \Flasher\Noty\Laravel\Facade\Noty::class, + 'Notyf' => \Flasher\Notyf\Laravel\Facade\Notyf::class, + 'SweetAlert' => \Flasher\SweetAlert\Laravel\Facade\SweetAlert::class, + 'Toastr' => \Flasher\Toastr\Laravel\Facade\Toastr::class, + ]; } - /** - * @param Application $app - */ - protected function getEnvironmentSetUp($app) + protected function defineEnvironment($app): void { - $separator = Laravel::isVersion('4') ? '::config' : ''; - - $app->make('config')->set('session.driver', 'array'); - $app->make('config')->set('session'.$separator.'.driver', 'array'); + tap($app['config'], function (Repository $config) { + $config->set('session.driver', 'array'); + }); } } diff --git a/tests/Laravel/Translation/TranslatorTest.php b/tests/Laravel/Translation/TranslatorTest.php new file mode 100644 index 00000000..ae3d685e --- /dev/null +++ b/tests/Laravel/Translation/TranslatorTest.php @@ -0,0 +1,79 @@ +laravelTranslatorMock = \Mockery::mock(LaravelTranslator::class); + } + + public function testTranslateWithExistingTranslation(): void + { + $this->laravelTranslatorMock->expects() + ->has('flasher::messages.key', null) + ->andReturnTrue(); + + $this->laravelTranslatorMock->expects() + ->get('flasher::messages.key', ['some_param' => 1], null) + ->andReturns('translated message'); + + $translator = new Translator($this->laravelTranslatorMock); + $this->assertSame('translated message', $translator->translate('key', ['some_param' => 1])); + } + + public function testTranslateWithFallbackTranslation(): void + { + $this->laravelTranslatorMock->expects() + ->has('flasher::messages.key', null) + ->andReturnFalse(); + + $this->laravelTranslatorMock->expects() + ->has('messages.key', null) + ->andReturnTrue(); + + $this->laravelTranslatorMock->expects() + ->get('messages.key', ['some_param' => 1], null) + ->andReturns('fallback translated message'); + + $translator = new Translator($this->laravelTranslatorMock); + $this->assertSame('fallback translated message', $translator->translate('key', ['some_param' => 1])); + } + + public function testTranslateWithNoTranslationFound(): void + { + $this->laravelTranslatorMock->allows('has') + ->andReturnFalse(); + + $this->laravelTranslatorMock->allows('get') + ->andReturnUsing(function ($id, $parameters, $locale) { + return $id; // Simulate Laravel's behavior of returning the key when no translation is found + }); + + $translator = new Translator($this->laravelTranslatorMock); + $this->assertSame('key', $translator->translate('key', ['some_param' => 1])); + } + + public function testGetLocale(): void + { + $this->laravelTranslatorMock->expects() + ->getLocale() + ->andReturns('en'); + + $translator = new Translator($this->laravelTranslatorMock); + $this->assertSame('en', $translator->getLocale()); + } +} diff --git a/tests/Laravel/TranslatorTest.php b/tests/Laravel/TranslatorTest.php deleted file mode 100644 index e0251ce2..00000000 --- a/tests/Laravel/TranslatorTest.php +++ /dev/null @@ -1,53 +0,0 @@ - - */ - -namespace Flasher\Tests\Laravel; - -use Flasher\Laravel\Translation\Translator; - -final class TranslatorTest extends TestCase -{ - /** - * @return void - */ - public function testTranslateMessage() - { - $translator = $this->getTranslator(); - - $this->assertEquals('Success', $translator->translate('success', array(), 'en')); - $this->assertEquals('Succès', $translator->translate('success', array(), 'fr')); - $this->assertEquals('نجاح', $translator->translate('success', array(), 'ar')); - } - - /** - * @return void - */ - public function testTranslateMessageWithParameters() - { - $translator = $this->getTranslator(); - - $this->assertEquals('The :resource was created', $translator->translate('The resource was created', array(), 'en')); - $this->assertEquals('The user was created', $translator->translate('The resource was created', array('resource' => 'user'), 'en')); - - $this->assertEquals('La ressource :resource a été ajoutée', $translator->translate('The resource was created', array(), 'fr')); - $this->assertEquals('La ressource utilisateur a été ajoutée', $translator->translate('The resource was created', array('resource' => 'utilisateur'), 'fr')); - - $this->assertEquals('تم إنشاء :resource', $translator->translate('The resource was created', array(), 'ar')); - $this->assertEquals('تم إنشاء الملف', $translator->translate('The resource was created', array('resource' => 'الملف'), 'ar')); - } - - /** - * @return Translator - */ - private function getTranslator() - { - /** @var \Illuminate\Translation\Translator $laravelTranslator */ - $laravelTranslator = $this->app->make('translator'); - - return new Translator($laravelTranslator); - } -} diff --git a/tests/Noty/Laravel/FlasherNotyServiceProviderTest.php b/tests/Noty/Laravel/FlasherNotyServiceProviderTest.php new file mode 100644 index 00000000..8a9a41f4 --- /dev/null +++ b/tests/Noty/Laravel/FlasherNotyServiceProviderTest.php @@ -0,0 +1,78 @@ +app = \Mockery::mock(Application::class); + $this->serviceProvider = new FlasherNotyServiceProvider($this->app); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(NotyPlugin::class, $this->serviceProvider->createPlugin()); + } + + public function testRegister(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('configurationIsCached')->never(); + + $this->serviceProvider->register(); + $this->addToAssertionCount(1); + } + + public function testBoot(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('singleton'); + $this->app->expects('alias'); + $this->app->expects('extend'); + + $this->serviceProvider->register(); + $this->serviceProvider->boot(); + $this->addToAssertionCount(1); + } + + public function testGetConfigurationFile(): void + { + $expectedPath = $this->getResourcesPathFromServiceProvider(); + $this->assertStringEndsWith('/Resources/config.php', $this->serviceProvider->getConfigurationFile()); + $this->assertStringContainsString($expectedPath, $this->serviceProvider->getConfigurationFile()); + } + + private function getResourcesPathFromServiceProvider(): string + { + $reflection = new \ReflectionClass(FlasherNotyServiceProvider::class); + $method = $reflection->getMethod('getResourcesDir'); + $method->setAccessible(true); + + /** @var string $string */ + $string = $method->invoke($this->serviceProvider); + + return rtrim($string, '/').'/'; + } +} diff --git a/tests/Noty/Prime/NotyBuilderTest.php b/tests/Noty/Prime/NotyBuilderTest.php new file mode 100644 index 00000000..bc5610d2 --- /dev/null +++ b/tests/Noty/Prime/NotyBuilderTest.php @@ -0,0 +1,202 @@ +notyBuilder = new NotyBuilder('noty', $storageManagerMock); + } + + public function testText(): void + { + $this->notyBuilder->text('Test message'); + + $envelope = $this->notyBuilder->getEnvelope(); + $notification = $envelope->getNotification(); + $actualMessage = $notification->getMessage(); + + $this->assertSame('Test message', $actualMessage); + } + + public function testAlert(): void + { + $this->notyBuilder->alert('Test alert'); + + $envelope = $this->notyBuilder->getEnvelope(); + $notification = $envelope->getNotification(); + + $this->assertSame('alert', $notification->getType()); + } + + public function testLayout(): void + { + $this->notyBuilder->layout('top'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['layout' => 'top'], $options); + } + + public function testTheme(): void + { + $this->notyBuilder->theme('mint'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['theme' => 'mint'], $options); + } + + public function testTimeout(): void + { + $this->notyBuilder->timeout(5000); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['timeout' => 5000], $options); + } + + public function testProgressBar(): void + { + $this->notyBuilder->progressBar(true); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['progressBar' => true], $options); + } + + public function testCloseWith(): void + { + $closeWith = 'click'; + $this->notyBuilder->closeWith($closeWith); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeWith' => ['click']], $options); + } + + public function testAnimation(): void + { + $this->notyBuilder->animation('open', 'fadeIn'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['animation.open' => 'fadeIn'], $options); + } + + public function testSounds(): void + { + $this->notyBuilder->sounds('open', 'sound.mp3'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['sounds.open' => 'sound.mp3'], $options); + } + + public function testDocTitle(): void + { + $this->notyBuilder->docTitle('Success', 'Title Changed'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['docTitleSuccess' => 'Title Changed'], $options); + } + + public function testModal(): void + { + $this->notyBuilder->modal(true); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['modal' => true], $options); + } + + public function testId(): void + { + $this->notyBuilder->id('custom_id'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['id' => 'custom_id'], $options); + } + + public function testForce(): void + { + $this->notyBuilder->force(true); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['force' => true], $options); + } + + public function testQueue(): void + { + $this->notyBuilder->queue('customQueue'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['queue' => 'customQueue'], $options); + } + + public function testKiller(): void + { + $this->notyBuilder->killer(true); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['killer' => true], $options); + } + + public function testContainer(): void + { + $this->notyBuilder->container('.custom-container'); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['container' => '.custom-container'], $options); + } + + public function testButtons(): void + { + $this->notyBuilder->buttons(['Yes', 'No']); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['buttons' => ['Yes', 'No']], $options); + } + + public function testVisibilityControl(): void + { + $this->notyBuilder->visibilityControl(true); + + $envelope = $this->notyBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['visibilityControl' => true], $options); + } +} diff --git a/tests/Noty/Prime/NotyPluginTest.php b/tests/Noty/Prime/NotyPluginTest.php new file mode 100644 index 00000000..f53f8ebd --- /dev/null +++ b/tests/Noty/Prime/NotyPluginTest.php @@ -0,0 +1,78 @@ +notyPlugin = new NotyPlugin(); + } + + public function testGetAlias(): void + { + $this->assertSame('noty', $this->notyPlugin->getAlias()); + } + + public function testGetFactory(): void + { + $this->assertSame(Noty::class, $this->notyPlugin->getFactory()); + } + + public function testGetServiceAliases(): void + { + $this->assertSame(NotyInterface::class, $this->notyPlugin->getServiceAliases()); + } + + public function testGetScripts(): void + { + $this->assertSame([ + '/vendor/flasher/noty.min.js', + '/vendor/flasher/flasher-noty.min.js', + ], $this->notyPlugin->getScripts()); + } + + public function testGetStyles(): void + { + $this->assertSame([ + '/vendor/flasher/noty.css', + '/vendor/flasher/mint.css', + ], $this->notyPlugin->getStyles()); + } + + public function testGetName(): void + { + $this->assertSame('flasher_noty', $this->notyPlugin->getName()); + } + + public function testGetServiceId(): void + { + $this->assertSame('flasher.noty', $this->notyPlugin->getServiceId()); + } + + public function testNormalizeConfig(): void + { + $expected = [ + 'scripts' => [ + '/vendor/flasher/noty.min.js', + '/vendor/flasher/flasher-noty.min.js', + ], + 'styles' => [ + '/vendor/flasher/noty.css', + '/vendor/flasher/mint.css', + ], + 'options' => [], + ]; + + $this->assertSame($expected, $this->notyPlugin->normalizeConfig([])); + } +} diff --git a/tests/Noty/Prime/NotyTest.php b/tests/Noty/Prime/NotyTest.php new file mode 100644 index 00000000..13411155 --- /dev/null +++ b/tests/Noty/Prime/NotyTest.php @@ -0,0 +1,39 @@ +createNotificationBuilder(); + + $this->assertInstanceOf(NotyBuilder::class, $result); + } + + public function testNotyBuilderTextMethod(): void + { + $storageManager = \Mockery::mock(StorageManagerInterface::class); + + $noty = new Noty($storageManager); + + $builder = $noty->createNotificationBuilder(); + $response = $noty->text('Hello World'); + + $this->assertInstanceOf(NotyBuilder::class, $response); + $this->assertInstanceOf(NotyBuilder::class, $builder); + } +} diff --git a/tests/Noty/Symfony/FlasherNotyBundleTest.php b/tests/Noty/Symfony/FlasherNotyBundleTest.php new file mode 100644 index 00000000..b0f1b06d --- /dev/null +++ b/tests/Noty/Symfony/FlasherNotyBundleTest.php @@ -0,0 +1,40 @@ +flasherNotyBundle = new FlasherNotyBundle(); + } + + public function testInstance(): void + { + $this->assertInstanceOf(PluginBundle::class, $this->flasherNotyBundle); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(NotyPlugin::class, $this->flasherNotyBundle->createPlugin()); + } + + public function testGetConfigurationFileReturnsExpectedPath(): void + { + $expectedPath = $this->flasherNotyBundle->getPath().'/Resources/config/config.yaml'; + + $this->assertSame($expectedPath, $this->flasherNotyBundle->getConfigurationFile()); + } +} diff --git a/tests/Notyf/Laravel/FlasherNotyfServiceProviderTest.php b/tests/Notyf/Laravel/FlasherNotyfServiceProviderTest.php new file mode 100644 index 00000000..0d12c856 --- /dev/null +++ b/tests/Notyf/Laravel/FlasherNotyfServiceProviderTest.php @@ -0,0 +1,78 @@ +app = \Mockery::mock(Application::class); + $this->serviceProvider = new FlasherNotyfServiceProvider($this->app); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(NotyfPlugin::class, $this->serviceProvider->createPlugin()); + } + + public function testRegister(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('configurationIsCached')->never(); + + $this->serviceProvider->register(); + $this->addToAssertionCount(1); + } + + public function testBoot(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('singleton'); + $this->app->expects('alias'); + $this->app->expects('extend'); + + $this->serviceProvider->register(); + $this->serviceProvider->boot(); + $this->addToAssertionCount(1); + } + + public function testGetConfigurationFile(): void + { + $expectedPath = $this->getResourcesPathFromServiceProvider(); + $this->assertStringEndsWith('/Resources/config.php', $this->serviceProvider->getConfigurationFile()); + $this->assertStringContainsString($expectedPath, $this->serviceProvider->getConfigurationFile()); + } + + private function getResourcesPathFromServiceProvider(): string + { + $reflection = new \ReflectionClass(FlasherNotyfServiceProvider::class); + $method = $reflection->getMethod('getResourcesDir'); + $method->setAccessible(true); + + /** @var string $string */ + $string = $method->invoke($this->serviceProvider); + + return rtrim($string, '/').'/'; + } +} diff --git a/tests/Notyf/Prime/NotyfBuilderTest.php b/tests/Notyf/Prime/NotyfBuilderTest.php new file mode 100644 index 00000000..cf005d87 --- /dev/null +++ b/tests/Notyf/Prime/NotyfBuilderTest.php @@ -0,0 +1,61 @@ +notyfBuilder = new NotyfBuilder('notyf', $storageManagerMock); + } + + public function testDuration(): void + { + $this->notyfBuilder->duration(6000); + + $envelope = $this->notyfBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['duration' => 6000], $options); + } + + public function testRipple(): void + { + $this->notyfBuilder->ripple(); + + $envelope = $this->notyfBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['ripple' => true], $options); + } + + public function testPosition(): void + { + $this->notyfBuilder->position('x', 'center'); + $this->notyfBuilder->position('y', 'top'); + + $envelope = $this->notyfBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['position' => ['x' => 'center', 'y' => 'top']], $options); + } + + public function testDismissible(): void + { + $this->notyfBuilder->dismissible(true); + + $envelope = $this->notyfBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['dismissible' => true], $options); + } +} diff --git a/tests/Notyf/Prime/NotyfPluginTest.php b/tests/Notyf/Prime/NotyfPluginTest.php new file mode 100644 index 00000000..e8eb88a3 --- /dev/null +++ b/tests/Notyf/Prime/NotyfPluginTest.php @@ -0,0 +1,66 @@ +notyfPlugin = new NotyfPlugin(); + } + + public function testGetAlias(): void + { + $this->assertSame('notyf', $this->notyfPlugin->getAlias()); + } + + public function testGetFactory(): void + { + $this->assertSame(Notyf::class, $this->notyfPlugin->getFactory()); + } + + public function testGetServiceAliases(): void + { + $this->assertSame(NotyfInterface::class, $this->notyfPlugin->getServiceAliases()); + } + + public function testGetScripts(): void + { + $this->assertSame(['/vendor/flasher/flasher-notyf.min.js'], $this->notyfPlugin->getScripts()); + } + + public function testGetStyles(): void + { + $this->assertSame(['/vendor/flasher/flasher-notyf.min.css'], $this->notyfPlugin->getStyles()); + } + + public function testGetName(): void + { + $this->assertSame('flasher_notyf', $this->notyfPlugin->getName()); + } + + public function testGetServiceId(): void + { + $this->assertSame('flasher.notyf', $this->notyfPlugin->getServiceId()); + } + + public function testNormalizeConfig(): void + { + $expected = [ + 'scripts' => ['/vendor/flasher/flasher-notyf.min.js'], + 'styles' => ['/vendor/flasher/flasher-notyf.min.css'], + 'options' => [], + ]; + + $this->assertSame($expected, $this->notyfPlugin->normalizeConfig([])); + } +} diff --git a/tests/Notyf/Prime/NotyfTest.php b/tests/Notyf/Prime/NotyfTest.php new file mode 100644 index 00000000..2a1a13c8 --- /dev/null +++ b/tests/Notyf/Prime/NotyfTest.php @@ -0,0 +1,39 @@ +createNotificationBuilder(); + + $this->assertInstanceOf(NotyfBuilder::class, $result); + } + + public function testNotyfBuilderTextMethod(): void + { + $storageManager = \Mockery::mock(StorageManagerInterface::class); + + $notyf = new Notyf($storageManager); + + $builder = $notyf->createNotificationBuilder(); + $response = $notyf->duration(6000); + + $this->assertInstanceOf(NotyfBuilder::class, $response); + $this->assertInstanceOf(NotyfBuilder::class, $builder); + } +} diff --git a/tests/Notyf/Symfony/FlasherNotyfBundleTest.php b/tests/Notyf/Symfony/FlasherNotyfBundleTest.php new file mode 100644 index 00000000..5922320d --- /dev/null +++ b/tests/Notyf/Symfony/FlasherNotyfBundleTest.php @@ -0,0 +1,40 @@ +flasherNotyfBundle = new FlasherNotyfBundle(); + } + + public function testInstance(): void + { + $this->assertInstanceOf(PluginBundle::class, $this->flasherNotyfBundle); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(NotyfPlugin::class, $this->flasherNotyfBundle->createPlugin()); + } + + public function testGetConfigurationFileReturnsExpectedPath(): void + { + $expectedPath = $this->flasherNotyfBundle->getPath().'/Resources/config/config.yaml'; + + $this->assertSame($expectedPath, $this->flasherNotyfBundle->getConfigurationFile()); + } +} diff --git a/tests/Prime/Asset/AssetManagerTest.php b/tests/Prime/Asset/AssetManagerTest.php new file mode 100644 index 00000000..6fade10d --- /dev/null +++ b/tests/Prime/Asset/AssetManagerTest.php @@ -0,0 +1,92 @@ +publicDir = __DIR__.'/../Fixtures/Asset'; + $this->manifestPath = __DIR__.'/../Fixtures/Asset/manifest.json'; + } + + protected function tearDown(): void + { + if (file_exists($this->manifestPath)) { + unlink($this->manifestPath); + } + } + + public function testConstruct(): void + { + $assetManager = new AssetManager($this->publicDir, $this->manifestPath); + $this->assertInstanceOf(AssetManager::class, $assetManager); + } + + public function testGetPath(): void + { + $assetManager = new AssetManager($this->publicDir, $this->manifestPath); + + $filePath = __DIR__.'/../Fixtures/Asset/test.css'; + + $assetManager->createManifest([$filePath]); + + $expectedPath = '/test.css?id=2cb85c44817ffbc50452dab7fc3e4823'; + + $this->assertSame($expectedPath, $assetManager->getPath('/test.css')); + } + + public function testGetPaths(): void + { + $assetManager = new AssetManager($this->publicDir, $this->manifestPath); + + $assetManager->createManifest([ + __DIR__.'/../Fixtures/Asset/test1.css', + __DIR__.'/../Fixtures/Asset/test2.css', + __DIR__.'/../Fixtures/Asset/test3.css', + ]); + + $files = ['/test1.css', '/test2.css', '/test3.css']; + $expectedPaths = [ + '/test1.css?id=38eeac10df68fe4b49c30f8c6af0b1cc', + '/test2.css?id=3cb80f170ff572502dca33a5ddb3ead3', + '/test3.css?id=e7172b646b854195291ebc5b12c88022', + ]; + + $this->assertSame($expectedPaths, $assetManager->getPaths($files)); + } + + public function testCreateManifest(): void + { + $assetManager = new AssetManager($this->publicDir, $this->manifestPath); + $files = [ + __DIR__.'/../Fixtures/Asset/test1.css', + __DIR__.'/../Fixtures/Asset/test2.css', + __DIR__.'/../Fixtures/Asset/test3.css', + ]; + $assetManager->createManifest($files); + + $expectedEntries = [ + '/test1.css' => '/test1.css?id=38eeac10df68fe4b49c30f8c6af0b1cc', + '/test2.css' => '/test2.css?id=3cb80f170ff572502dca33a5ddb3ead3', + '/test3.css' => '/test3.css?id=e7172b646b854195291ebc5b12c88022', + ]; + + // Using reflection to make getEntriesData() accessible + $reflection = new \ReflectionClass(AssetManager::class); + $method = $reflection->getMethod('getEntriesData'); + $method->setAccessible(true); + + $entriesData = $method->invoke($assetManager); + + $this->assertSame($expectedEntries, $entriesData); + } +} diff --git a/tests/Prime/Config/ConfigTest.php b/tests/Prime/Config/ConfigTest.php deleted file mode 100644 index 7cd82410..00000000 --- a/tests/Prime/Config/ConfigTest.php +++ /dev/null @@ -1,67 +0,0 @@ - - */ - -namespace Flasher\Tests\Prime\Config; - -use Flasher\Prime\Config\Config; -use Flasher\Tests\Prime\TestCase; - -final class ConfigTest extends TestCase -{ - /** - * @return void - */ - public function testGet() - { - /** @phpstan-ignore-next-line */ - $config = new Config(array( - 'default' => 'flasher', - 'root_script' => 'flasher.min.js', - 'themes' => array( - 'flasher' => array( - 'scripts' => array('script.js'), - 'styles' => array('styles.css'), - 'options' => array(), - ), - ), - 'auto_translate' => true, - 'flash_bag' => array( - 'enabled' => true, - 'mapping' => array( - 'success' => array('success'), - 'error' => array('error'), - ), - ), - 'presets' => array( - 'success' => array( - 'type' => 'success', - 'title' => 'Success', - 'message' => 'Success message', - 'options' => array(), - ), - 'error' => array( - 'type' => 'error', - 'title' => 'Error', - 'message' => 'Error message', - 'options' => array(), - ), - ), - )); - - $this->assertEquals('flasher', $config->get('default')); - $this->assertEquals(array( - 'scripts' => array('script.js'), - 'styles' => array('styles.css'), - 'options' => array(), - ), $config->get('themes.flasher')); - $this->assertEquals(array('styles.css'), $config->get('themes.flasher.styles')); - $this->assertEquals(array('script.js'), $config->get('themes.flasher.scripts')); - $this->assertEquals(array(), $config->get('themes.flasher.options')); - $this->assertNull($config->get('drivers.not_exists.options')); - $this->assertEquals('now_it_exists', $config->get('drivers.not_exists.options', 'now_it_exists')); - } -} diff --git a/tests/Prime/Container/FlasherContainerTest.php b/tests/Prime/Container/FlasherContainerTest.php index c12fd27c..ac01f0b9 100644 --- a/tests/Prime/Container/FlasherContainerTest.php +++ b/tests/Prime/Container/FlasherContainerTest.php @@ -1,59 +1,71 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Container; use Flasher\Prime\Container\FlasherContainer; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Factory\NotificationFactoryInterface; +use Flasher\Prime\FlasherInterface; +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; -class FlasherContainerTest extends TestCase +final class FlasherContainerTest extends TestCase { - /** - * @return void - */ - public function testInit() + protected function setUp(): void { - $this->setProperty('Flasher\Prime\Container\FlasherContainer', 'instance', null); - $container = $this->getMockBuilder('Flasher\Prime\Container\ContainerInterface')->getMock(); - - FlasherContainer::init($container); - - $property = $this->getProperty('Flasher\Prime\Container\FlasherContainer', 'container'); - - $this->assertEquals($container, $property); + // Reset the FlasherContainer instance to ensure isolation between tests + FlasherContainer::reset(); } - /** - * @return void - */ - public function testCreate() + public function testCreateReturnsCorrectType(): void { - $this->setProperty('Flasher\Prime\Container\FlasherContainer', 'instance', null); + $flasher = $this->createMock(FlasherInterface::class); - $container = $this->getMockBuilder('Flasher\Prime\Container\ContainerInterface')->getMock(); - $container - ->method('get') - ->willreturn($this->getMockBuilder('Flasher\Prime\FlasherInterface')->getMock()); + $container = $this->createMock(ContainerInterface::class); + $container->method('has')->willReturn(true); + $container->method('get')->willReturn($flasher); - FlasherContainer::init($container); + FlasherContainer::from($container); - $service = FlasherContainer::create('flasher'); - - $this->assertInstanceOf('Flasher\Prime\FlasherInterface', $service); + $this->assertInstanceOf(FlasherInterface::class, FlasherContainer::create('flasher')); } - /** - * @return void - */ - public function testThrowsExceptionIfNotInitialized() + public function testCreateThrowsExceptionForNotFoundService(): void { - $this->setExpectedException('\LogicException', 'Container is not initialized yet. Container::init() must be called with a real container.'); + $invalidService = new \stdClass(); + $container = $this->createMock(ContainerInterface::class); + $container->method('has')->willReturn(false); + $container->method('get')->willReturn($invalidService); - $this->setProperty('Flasher\Prime\Container\FlasherContainer', 'instance', null); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The container does not have the requested service "invalid_service".'); + + FlasherContainer::from($container); + FlasherContainer::create('invalid_service'); + } + + public function testCreateThrowsExceptionForInvalidServiceType(): void + { + $invalidService = new \stdClass(); + $container = $this->createMock(ContainerInterface::class); + $container->method('has')->willReturn(true); + $container->method('get')->willReturn($invalidService); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage(sprintf('Expected an instance of "%s" or "%s", got "%s".', FlasherInterface::class, NotificationFactoryInterface::class, get_debug_type($invalidService))); + + FlasherContainer::from($container); + FlasherContainer::create('invalid_service'); + } + + public function testCreateThrowsExceptionIfNotInitialized(): void + { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('FlasherContainer has not been initialized. Please initialize it by calling FlasherContainer::from(ContainerInterface $container).'); + + // Ensure that FlasherContainer is not initialized + FlasherContainer::reset(); FlasherContainer::create('flasher'); } diff --git a/tests/Prime/EventDispatcher/Event/FilterEventTest.php b/tests/Prime/EventDispatcher/Event/FilterEventTest.php index 898cb50d..c4a7a2e4 100644 --- a/tests/Prime/EventDispatcher/Event/FilterEventTest.php +++ b/tests/Prime/EventDispatcher/Event/FilterEventTest.php @@ -1,40 +1,34 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\FilterEvent; -use Flasher\Prime\Filter\Filter; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Storage\Filter\Filter; +use PHPUnit\Framework\TestCase; -class FilterEventTest extends TestCase +final class FilterEventTest extends TestCase { - /** - * @return void - */ - public function testFilterEvent() + public function testFilterEvent(): void { - $envelopes = array( + $filter = new Filter(); + + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; - $event = new FilterEvent($envelopes, array('limit' => 2)); + $criteria = ['limit' => 2]; - $this->assertInstanceOf('Flasher\Prime\Filter\Filter', $event->getFilter()); - $this->assertEquals(array($envelopes[0], $envelopes[1]), $event->getEnvelopes()); + $event = new FilterEvent($filter, $envelopes, $criteria); - $filter = new Filter($envelopes, array()); - $event->setFilter($filter); - - $this->assertEquals($envelopes, $event->getEnvelopes()); + $this->assertSame($filter, $event->getFilter()); + $this->assertSame($envelopes, $event->getEnvelopes()); + $this->assertSame($criteria, $event->getCriteria()); } } diff --git a/tests/Prime/EventDispatcher/Event/PersistEventTest.php b/tests/Prime/EventDispatcher/Event/PersistEventTest.php index 737bb8fd..dd45c9ee 100644 --- a/tests/Prime/EventDispatcher/Event/PersistEventTest.php +++ b/tests/Prime/EventDispatcher/Event/PersistEventTest.php @@ -1,38 +1,32 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\PersistEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class PersistEventTest extends TestCase +final class PersistEventTest extends TestCase { - /** - * @return void - */ - public function testPersistEvent() + public function testPersistEvent(): void { - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; $event = new PersistEvent($envelopes); $this->assertEquals($envelopes, $event->getEnvelopes()); - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), - ); + ]; $event->setEnvelopes($envelopes); $this->assertEquals($envelopes, $event->getEnvelopes()); diff --git a/tests/Prime/EventDispatcher/Event/PostPersistEventTest.php b/tests/Prime/EventDispatcher/Event/PostPersistEventTest.php index 1f7ddc15..d81495b0 100644 --- a/tests/Prime/EventDispatcher/Event/PostPersistEventTest.php +++ b/tests/Prime/EventDispatcher/Event/PostPersistEventTest.php @@ -1,30 +1,24 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\PostPersistEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class PostPersistEventTest extends TestCase +final class PostPersistEventTest extends TestCase { - /** - * @return void - */ - public function testPostPersistEvent() + public function testPostPersistEvent(): void { - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; $event = new PostPersistEvent($envelopes); diff --git a/tests/Prime/EventDispatcher/Event/PostRemoveEventTest.php b/tests/Prime/EventDispatcher/Event/PostRemoveEventTest.php index f0ed284d..025c3bbe 100644 --- a/tests/Prime/EventDispatcher/Event/PostRemoveEventTest.php +++ b/tests/Prime/EventDispatcher/Event/PostRemoveEventTest.php @@ -1,33 +1,27 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\PostRemoveEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class PostRemoveEventTest extends TestCase +final class PostRemoveEventTest extends TestCase { - /** - * @return void - */ - public function testPostRemoveEvent() + public function testPostRemoveEvent(): void { - $envelopesToRemove = array( + $envelopesToRemove = [ new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; - $envelopesToKeep = array( + $envelopesToKeep = [ new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; $event = new PostRemoveEvent($envelopesToRemove, $envelopesToKeep); diff --git a/tests/Prime/EventDispatcher/Event/PostUpdateEventTest.php b/tests/Prime/EventDispatcher/Event/PostUpdateEventTest.php index cb5df545..ea55ae3d 100644 --- a/tests/Prime/EventDispatcher/Event/PostUpdateEventTest.php +++ b/tests/Prime/EventDispatcher/Event/PostUpdateEventTest.php @@ -1,30 +1,24 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\PostUpdateEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class PostUpdateEventTest extends TestCase +final class PostUpdateEventTest extends TestCase { - /** - * @return void - */ - public function testPostUpdateEvent() + public function testPostUpdateEvent(): void { - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; $event = new PostUpdateEvent($envelopes); diff --git a/tests/Prime/EventDispatcher/Event/PresentationEventTest.php b/tests/Prime/EventDispatcher/Event/PresentationEventTest.php index 07a4e87a..9a641b60 100644 --- a/tests/Prime/EventDispatcher/Event/PresentationEventTest.php +++ b/tests/Prime/EventDispatcher/Event/PresentationEventTest.php @@ -1,34 +1,28 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\PresentationEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class PresentationEventTest extends TestCase +final class PresentationEventTest extends TestCase { - /** - * @return void - */ - public function testPresentationEvent() + public function testPresentationEvent(): void { - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; - $context = array( + $context = [ 'livewire' => true, - ); + ]; $event = new PresentationEvent($envelopes, $context); diff --git a/tests/Prime/EventDispatcher/Event/RemoveEventTest.php b/tests/Prime/EventDispatcher/Event/RemoveEventTest.php index cdfe59f8..a9c431a4 100644 --- a/tests/Prime/EventDispatcher/Event/RemoveEventTest.php +++ b/tests/Prime/EventDispatcher/Event/RemoveEventTest.php @@ -1,40 +1,34 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\RemoveEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class RemoveEventTest extends TestCase +final class RemoveEventTest extends TestCase { - /** - * @return void - */ - public function testRemoveEvent() + public function testRemoveEvent(): void { - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; $event = new RemoveEvent($envelopes); $this->assertEquals($envelopes, $event->getEnvelopesToRemove()); - $this->assertEquals(array(), $event->getEnvelopesToKeep()); + $this->assertSame([], $event->getEnvelopesToKeep()); - $event->setEnvelopesToKeep(array($envelopes[0], $envelopes[1])); - $event->setEnvelopesToRemove(array($envelopes[2], $envelopes[3])); + $event->setEnvelopesToKeep([$envelopes[0], $envelopes[1]]); + $event->setEnvelopesToRemove([$envelopes[2], $envelopes[3]]); - $this->assertEquals(array($envelopes[2], $envelopes[3]), $event->getEnvelopesToRemove()); - $this->assertEquals(array($envelopes[0], $envelopes[1]), $event->getEnvelopesToKeep()); + $this->assertEquals([$envelopes[2], $envelopes[3]], $event->getEnvelopesToRemove()); + $this->assertEquals([$envelopes[0], $envelopes[1]], $event->getEnvelopesToKeep()); } } diff --git a/tests/Prime/EventDispatcher/Event/ResponseEventTest.php b/tests/Prime/EventDispatcher/Event/ResponseEventTest.php index 6a10ca7f..d43b0920 100644 --- a/tests/Prime/EventDispatcher/Event/ResponseEventTest.php +++ b/tests/Prime/EventDispatcher/Event/ResponseEventTest.php @@ -1,29 +1,23 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\ResponseEvent; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class ResponseEventTest extends TestCase +final class ResponseEventTest extends TestCase { - /** - * @return void - */ - public function testResponseEvent() + public function testResponseEvent(): void { $event = new ResponseEvent('{"foo": "bar"}', 'json'); - $this->assertEquals('{"foo": "bar"}', $event->getResponse()); - $this->assertEquals('json', $event->getPresenter()); + $this->assertSame('{"foo": "bar"}', $event->getResponse()); + $this->assertSame('json', $event->getPresenter()); $event->setResponse('{"foo": "baz"}'); - $this->assertEquals('{"foo": "baz"}', $event->getResponse()); + $this->assertSame('{"foo": "baz"}', $event->getResponse()); } } diff --git a/tests/Prime/EventDispatcher/Event/UpdateEventTest.php b/tests/Prime/EventDispatcher/Event/UpdateEventTest.php index 55997400..2467b578 100644 --- a/tests/Prime/EventDispatcher/Event/UpdateEventTest.php +++ b/tests/Prime/EventDispatcher/Event/UpdateEventTest.php @@ -1,38 +1,32 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\Event; use Flasher\Prime\EventDispatcher\Event\UpdateEvent; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class UpdateEventTest extends TestCase +final class UpdateEventTest extends TestCase { - /** - * @return void - */ - public function testUpdateEvent() + public function testUpdateEvent(): void { - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; $event = new UpdateEvent($envelopes); $this->assertEquals($envelopes, $event->getEnvelopes()); - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), - ); + ]; $event->setEnvelopes($envelopes); $this->assertEquals($envelopes, $event->getEnvelopes()); diff --git a/tests/Prime/EventDispatcher/EventDispatcherTest.php b/tests/Prime/EventDispatcher/EventDispatcherTest.php index 05f7a563..7d9cae28 100644 --- a/tests/Prime/EventDispatcher/EventDispatcherTest.php +++ b/tests/Prime/EventDispatcher/EventDispatcherTest.php @@ -1,192 +1,113 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher; -use Flasher\Prime\EventDispatcher\Event\StoppableEventInterface; use Flasher\Prime\EventDispatcher\EventDispatcher; -use Flasher\Prime\EventDispatcher\EventListener\EventSubscriberInterface; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface; +use Flasher\Tests\Prime\Fixtures\EventDispatcher\Event\InvokeableEvent; +use Flasher\Tests\Prime\Fixtures\EventDispatcher\Event\StoppableEvent; +use Flasher\Tests\Prime\Fixtures\EventDispatcher\EventListener\InvokeableEventListener; +use Flasher\Tests\Prime\Fixtures\EventDispatcher\EventListener\NonCallableListener; +use Flasher\Tests\Prime\Fixtures\EventDispatcher\EventListener\StoppableEventListener; +use PHPUnit\Framework\TestCase; -class EventDispatcherTest extends TestCase +final class EventDispatcherTest extends TestCase { - // Some pseudo events - const preFoo = 'pre.foo'; + private EventDispatcher $dispatcher; - const postFoo = 'post.foo'; + protected function setUp(): void + { + $this->dispatcher = new EventDispatcher(); + } - const preBar = 'pre.bar'; - - const postBar = 'post.bar'; - - /** - * @return void - */ - public function testInitialState() + public function testInitialState(): void { $dispatcher = new EventDispatcher(); - $this->assertEquals(array(), $dispatcher->getListeners('fake_event')); + $this->assertSame([], $dispatcher->getListeners('fake_event')); } - /** - * @return void - */ - public function testAddListener() + public function testAddAndRetrieveListeners(): void { - $dispatcher = new EventDispatcher(); - $listener = new TestEventListener(); + $listener = $this->createMock(EventListenerInterface::class); + $listener->method('getSubscribedEvents') + ->willReturn(['some_event']); - $dispatcher->addListener('pre.foo', array($listener, 'preFoo')); - $dispatcher->addListener('post.foo', array($listener, 'postFoo')); - $this->assertCount(1, $dispatcher->getListeners(self::preFoo)); - $this->assertCount(1, $dispatcher->getListeners(self::postFoo)); + $this->dispatcher->addListener($listener); + + $listeners = $this->dispatcher->getListeners('some_event'); + $this->assertCount(1, $listeners); + $this->assertSame($listener, $listeners[0]); } - /** - * @return void - */ - public function testDispatch() + public function testDispatchCallsListeners(): void { - $dispatcher = new EventDispatcher(); - $listener = new TestEventListener(); + $event = new InvokeableEvent(); + $listener = new InvokeableEventListener(); - $event = new Event(); - $dispatcher->addListener('Flasher\Tests\Prime\EventDispatcher\Event', array($listener, 'preFoo')); - $dispatcher->addListener('NotFoundEvent', array($listener, 'postFoo')); + $this->dispatcher->addListener($listener); + $this->dispatcher->dispatch($event); - $return = $dispatcher->dispatch($event); - - $this->assertTrue($listener->preFooInvoked); - $this->assertFalse($listener->postFooInvoked); - - $this->assertInstanceOf('Flasher\Tests\Prime\EventDispatcher\Event', $return); - $this->assertEquals($event, $return); + $this->assertTrue($event->isInvoked()); } - /** - * @return void - */ - public function testDispatchForClosure() + public function testDispatchWithStoppableEvent(): void { - $dispatcher = new EventDispatcher(); + $event = new StoppableEvent(); + $listener = new StoppableEventListener(); - $invoked = 0; - $listener = function () use (&$invoked) { - ++$invoked; - }; + $this->dispatcher->addListener($listener); + $this->dispatcher->dispatch($event); - $event = new Event(); - $dispatcher->addListener('Flasher\Tests\Prime\EventDispatcher\Event', $listener); - $dispatcher->addListener('AnotherEvent', $listener); - $dispatcher->dispatch($event); - $this->assertEquals(1, $invoked); + $this->assertTrue($event->isPropagationStopped()); } - /** - * @return void - */ - public function testStopEventPropagation() + public function testDispatchWithNonCallableListener(): void { - $dispatcher = new EventDispatcher(); - $listener = new TestEventListener(); + $event = new class() {}; + $eventName = $event::class; - $otherListener = new TestEventListener(); + $listener = new NonCallableListener($eventName); - $event = new Event(); - // postFoo() stops the propagation, so only one listener should - // be executed - // Manually set priority to enforce $listener to be called first - $dispatcher->addListener('Flasher\Tests\Prime\EventDispatcher\Event', array($listener, 'postFoo'), 10); - $dispatcher->addListener('Flasher\Tests\Prime\EventDispatcher\Event', array($otherListener, 'preFoo')); - $dispatcher->dispatch($event); - $this->assertTrue($listener->postFooInvoked); - $this->assertFalse($otherListener->postFooInvoked); - } -} - -class Event implements StoppableEventInterface -{ - private $propagationStopped = false; - - private $data; - - public function __construct($data = null) - { - $this->data = $data; - } - - public function isPropagationStopped() - { - return $this->propagationStopped; - } - - public function stopPropagation() - { - $this->propagationStopped = true; - } -} - -class CallableClass -{ - public function __invoke() - { - } -} - -class TestEventListener -{ - public $preFooInvoked = false; - - public $postFooInvoked = false; - - public function preFoo(Event $e) - { - $this->preFooInvoked = true; - } - - public function postFoo(Event $e) - { - $this->postFooInvoked = true; - - $e->stopPropagation(); - } -} - -class TestEventSubscriber implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - 'pre.foo' => 'preFoo', - 'post.foo' => 'postFoo', - ); - } -} - -class TestEventSubscriberWithPriorities implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - 'pre.foo' => array('preFoo', 10), - 'post.foo' => array('postFoo'), - ); - } -} - -class TestEventSubscriberWithMultipleListeners implements EventSubscriberInterface -{ - public static function getSubscribedEvents() - { - return array( - 'pre.foo' => array( - array('preFoo1'), - array('preFoo2', 10), - ), - ); + $this->dispatcher->addListener($listener); + + $this->expectException(\InvalidArgumentException::class); + $this->dispatcher->dispatch($event); + } + + public function testMultipleListenersForSingleEvent(): void + { + $event = new InvokeableEvent(); + $listener1 = new InvokeableEventListener(); + $listener2 = new InvokeableEventListener(); + + $this->dispatcher->addListener($listener1); + $this->dispatcher->addListener($listener2); + $this->dispatcher->dispatch($event); + + $this->assertSame(2, $event->getInvokeCount()); + } + + public function testMultipleListenersForStoppableEvent(): void + { + $event = new InvokeableEvent(); + $listener1 = new StoppableEventListener(); + $listener2 = new InvokeableEventListener(); + + $this->dispatcher->addListener($listener1); + $this->dispatcher->addListener($listener2); + $this->dispatcher->dispatch($event); + + $this->assertTrue($event->isInvoked()); + $this->assertSame(1, $event->getInvokeCount()); + } + + public function testDispatchEventWithNoListeners(): void + { + $event = new InvokeableEvent(); + $this->dispatcher->dispatch($event); + + $this->assertFalse($event->isInvoked()); } } diff --git a/tests/Prime/EventDispatcher/EventListener/AddToStorageListenerTest.php b/tests/Prime/EventDispatcher/EventListener/AddToStorageListenerTest.php index 769e8041..6b256f44 100644 --- a/tests/Prime/EventDispatcher/EventListener/AddToStorageListenerTest.php +++ b/tests/Prime/EventDispatcher/EventListener/AddToStorageListenerTest.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\EventListener; @@ -14,31 +11,30 @@ use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Stamp\UnlessStamp; use Flasher\Prime\Stamp\WhenStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Tests\Prime\Helper\ObjectInvader; +use PHPUnit\Framework\TestCase; -class AddToStorageListenerTest extends TestCase +final class AddToStorageListenerTest extends TestCase { - /** - * @return void - */ - public function testAddToStorageListener() + public function testAddToStorageListener(): void { $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + + ObjectInvader::from($eventDispatcher)->set('listeners', []); $listener = new AddToStorageListener(); - $eventDispatcher->addSubscriber($listener); + $eventDispatcher->addListener($listener); - $envelopes = array( + $envelopes = [ new Envelope(new Notification(), new WhenStamp(false)), new Envelope(new Notification()), new Envelope(new Notification(), new UnlessStamp(true)), new Envelope(new Notification()), - ); - $event = new PersistEvent($envelopes); + ]; + $event = new PersistEvent($envelopes); $eventDispatcher->dispatch($event); - $this->assertEquals(array($envelopes[1], $envelopes[3]), $event->getEnvelopes()); + $this->assertCount(2, $event->getEnvelopes()); } } diff --git a/tests/Prime/EventDispatcher/EventListener/PresetListenerTest.php b/tests/Prime/EventDispatcher/EventListener/PresetListenerTest.php index 2c33f8d3..40dc2dc5 100644 --- a/tests/Prime/EventDispatcher/EventListener/PresetListenerTest.php +++ b/tests/Prime/EventDispatcher/EventListener/PresetListenerTest.php @@ -1,44 +1,40 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\EventListener; use Flasher\Prime\EventDispatcher\Event\PersistEvent; use Flasher\Prime\EventDispatcher\EventDispatcher; -use Flasher\Prime\EventDispatcher\EventListener\PresetListener; +use Flasher\Prime\EventDispatcher\EventListener\ApplyPresetListener; +use Flasher\Prime\Exception\PresetNotFoundException; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Stamp\PresetStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Tests\Prime\Helper\ObjectInvader; +use PHPUnit\Framework\TestCase; -class PresetListenerTest extends TestCase +final class PresetListenerTest extends TestCase { - /** - * @return void - */ - public function testPresetListener() + public function testPresetListener(): void { $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + ObjectInvader::from($eventDispatcher)->set('listeners', []); - $listener = new PresetListener(array( - 'entity_saved' => array( + $listener = new ApplyPresetListener([ + 'entity_saved' => [ 'type' => 'success', 'title' => 'PHPFlasher', 'message' => 'success message', - 'options' => array('timeout' => 2500), - ), - )); - $eventDispatcher->addSubscriber($listener); + 'options' => ['timeout' => 2500], + ], + ]); + $eventDispatcher->addListener($listener); - $envelopes = array( + $envelopes = [ new Envelope(new Notification(), new PresetStamp('entity_saved')), new Envelope(new Notification()), - ); + ]; $event = new PersistEvent($envelopes); $eventDispatcher->dispatch($event); @@ -46,39 +42,38 @@ class PresetListenerTest extends TestCase $envelopes = $event->getEnvelopes(); $this->assertCount(2, $envelopes); - $this->assertEquals('success', $envelopes[0]->getType()); - $this->assertEquals('PHPFlasher', $envelopes[0]->getTitle()); - $this->assertEquals('success message', $envelopes[0]->getMessage()); - $this->assertEquals(array('timeout' => 2500), $envelopes[0]->getOptions()); + $this->assertSame('success', $envelopes[0]->getType()); + $this->assertSame('PHPFlasher', $envelopes[0]->getTitle()); + $this->assertSame('success message', $envelopes[0]->getMessage()); + $this->assertSame(['timeout' => 2500], $envelopes[0]->getOptions()); } - /** - * @return void - */ - public function testThrowExceptionIfPresetNotFound() + public function testThrowExceptionIfPresetNotFound(): void { - $this->setExpectedException( - 'Flasher\Prime\Exception\PresetNotFoundException', - 'Preset "entity_deleted" not found, did you forget to register it? Available presets: entity_saved' + $this->expectException( + PresetNotFoundException::class + ); + $this->expectExceptionMessage( + 'Preset "entity_deleted" not found, did you forget to register it? Available presets: "entity_saved"' ); $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + ObjectInvader::from($eventDispatcher)->set('listeners', []); - $listener = new PresetListener(array( - 'entity_saved' => array( + $listener = new ApplyPresetListener([ + 'entity_saved' => [ 'type' => 'success', 'title' => 'PHPFlasher', 'message' => 'success message', - 'options' => array('timeout' => 2500), - ), - )); - $eventDispatcher->addSubscriber($listener); + 'options' => ['timeout' => 2500], + ], + ]); + $eventDispatcher->addListener($listener); - $envelopes = array( + $envelopes = [ new Envelope(new Notification(), new PresetStamp('entity_deleted')), new Envelope(new Notification()), - ); + ]; $event = new PersistEvent($envelopes); $eventDispatcher->dispatch($event); diff --git a/tests/Prime/EventDispatcher/EventListener/RemoveListenerTest.php b/tests/Prime/EventDispatcher/EventListener/RemoveListenerTest.php index d1b363ce..9f9c6515 100644 --- a/tests/Prime/EventDispatcher/EventListener/RemoveListenerTest.php +++ b/tests/Prime/EventDispatcher/EventListener/RemoveListenerTest.php @@ -1,44 +1,39 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\EventListener; use Flasher\Prime\EventDispatcher\Event\RemoveEvent; use Flasher\Prime\EventDispatcher\EventDispatcher; -use Flasher\Prime\EventDispatcher\EventListener\RemoveListener; +use Flasher\Prime\EventDispatcher\EventListener\EnvelopeRemovalListener; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Stamp\HopsStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Tests\Prime\Helper\ObjectInvader; +use PHPUnit\Framework\TestCase; -class RemoveListenerTest extends TestCase +final class RemoveListenerTest extends TestCase { - /** - * @return void - */ - public function testRemoveListener() + public function testRemoveListener(): void { $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + ObjectInvader::from($eventDispatcher)->set('listeners', []); - $listener = new RemoveListener(); - $eventDispatcher->addSubscriber($listener); + $listener = new EnvelopeRemovalListener(); + $eventDispatcher->addListener($listener); - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification(), new HopsStamp(2)), - new Envelope(new Notification(), new HopsStamp(1)), - new Envelope(new Notification(), new HopsStamp(3)), - ); + $envelopes = [ + new Envelope(new Notification()), + new Envelope(new Notification(), new HopsStamp(2)), + new Envelope(new Notification(), new HopsStamp(1)), + new Envelope(new Notification(), new HopsStamp(3)), + ]; $event = new RemoveEvent($envelopes); $eventDispatcher->dispatch($event); - $this->assertEquals(array($envelopes[0], $envelopes[2]), $event->getEnvelopesToRemove()); - $this->assertEquals(array($envelopes[1], $envelopes[3]), $event->getEnvelopesToKeep()); + $this->assertEquals([$envelopes[0], $envelopes[2]], $event->getEnvelopesToRemove()); + $this->assertEquals([$envelopes[1], $envelopes[3]], $event->getEnvelopesToKeep()); } } diff --git a/tests/Prime/EventDispatcher/EventListener/StampsListenerTest.php b/tests/Prime/EventDispatcher/EventListener/StampsListenerTest.php index 11ea8a74..0265bc19 100644 --- a/tests/Prime/EventDispatcher/EventListener/StampsListenerTest.php +++ b/tests/Prime/EventDispatcher/EventListener/StampsListenerTest.php @@ -1,45 +1,45 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\EventListener; use Flasher\Prime\EventDispatcher\Event\PersistEvent; use Flasher\Prime\EventDispatcher\EventDispatcher; -use Flasher\Prime\EventDispatcher\EventListener\StampsListener; +use Flasher\Prime\EventDispatcher\EventListener\AttachDefaultStampsListener; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\CreatedAtStamp; +use Flasher\Prime\Stamp\DelayStamp; +use Flasher\Prime\Stamp\HopsStamp; +use Flasher\Prime\Stamp\IdStamp; +use Flasher\Prime\Stamp\PriorityStamp; +use Flasher\Tests\Prime\Helper\ObjectInvader; +use PHPUnit\Framework\TestCase; -class StampsListenerTest extends TestCase +final class StampsListenerTest extends TestCase { - /** - * @return void - */ - public function testStampsListener() + public function testStampsListener(): void { $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + ObjectInvader::from($eventDispatcher)->set('listeners', []); - $listener = new StampsListener(); - $eventDispatcher->addSubscriber($listener); + $listener = new AttachDefaultStampsListener(); + $eventDispatcher->addListener($listener); - $envelopes = array( + $envelopes = [ new Envelope(new Notification()), - ); + ]; $event = new PersistEvent($envelopes); $eventDispatcher->dispatch($event); $envelopes = $event->getEnvelopes(); - $this->assertInstanceOf('Flasher\Prime\Stamp\CreatedAtStamp', $envelopes[0]->get('Flasher\Prime\Stamp\CreatedAtStamp')); - $this->assertInstanceOf('Flasher\Prime\Stamp\UuidStamp', $envelopes[0]->get('Flasher\Prime\Stamp\UuidStamp')); - $this->assertInstanceOf('Flasher\Prime\Stamp\DelayStamp', $envelopes[0]->get('Flasher\Prime\Stamp\DelayStamp')); - $this->assertInstanceOf('Flasher\Prime\Stamp\HopsStamp', $envelopes[0]->get('Flasher\Prime\Stamp\HopsStamp')); - $this->assertInstanceOf('Flasher\Prime\Stamp\PriorityStamp', $envelopes[0]->get('Flasher\Prime\Stamp\PriorityStamp')); + $this->assertInstanceOf(CreatedAtStamp::class, $envelopes[0]->get(CreatedAtStamp::class)); + $this->assertInstanceOf(IdStamp::class, $envelopes[0]->get(IdStamp::class)); + $this->assertInstanceOf(DelayStamp::class, $envelopes[0]->get(DelayStamp::class)); + $this->assertInstanceOf(HopsStamp::class, $envelopes[0]->get(HopsStamp::class)); + $this->assertInstanceOf(PriorityStamp::class, $envelopes[0]->get(PriorityStamp::class)); } } diff --git a/tests/Prime/EventDispatcher/EventListener/TranslationListenerTest.php b/tests/Prime/EventDispatcher/EventListener/TranslationListenerTest.php index d40600bd..7d88619e 100644 --- a/tests/Prime/EventDispatcher/EventListener/TranslationListenerTest.php +++ b/tests/Prime/EventDispatcher/EventListener/TranslationListenerTest.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\EventDispatcher\EventListener; @@ -15,71 +12,66 @@ use Flasher\Prime\Notification\Notification; use Flasher\Prime\Stamp\PresetStamp; use Flasher\Prime\Stamp\TranslationStamp; use Flasher\Prime\Translation\EchoTranslator; -use Flasher\Tests\Prime\TestCase; +use Flasher\Tests\Prime\Helper\ObjectInvader; +use PHPUnit\Framework\TestCase; -class TranslationListenerTest extends TestCase +final class TranslationListenerTest extends TestCase { - /** - * @return void - */ - public function testTranslationListenerWithAutoTranslateEnabled() + public function testTranslationListenerWithAutoTranslateEnabled(): void { $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + ObjectInvader::from($eventDispatcher)->set('listeners', []); - $listener = new TranslationListener(new EchoTranslator(), true); - $eventDispatcher->addSubscriber($listener); + $listener = new TranslationListener(new EchoTranslator()); + $eventDispatcher->addListener($listener); $notification = new Notification(); $notification->setTitle('PHPFlasher'); $notification->setMessage('success message'); - $envelopes = array( + $envelopes = [ new Envelope($notification), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; - $envelopes[0]->withStamp(new TranslationStamp(array('resource' => 'resource'), 'ar')); - $envelopes[0]->withStamp(new PresetStamp('entity_saved', array('resource' => 'resource'))); + $envelopes[0]->withStamp(new TranslationStamp(['resource' => 'resource'], 'ar')); + $envelopes[0]->withStamp(new PresetStamp('entity_saved', ['resource' => 'resource'])); - $envelopes[1]->withStamp(new TranslationStamp(array('resource' => 'resource'), 'ar')); - $envelopes[1]->withStamp(new PresetStamp('entity_saved', array('resource' => 'resource'))); + $envelopes[1]->withStamp(new TranslationStamp(['resource' => 'resource'], 'ar')); + $envelopes[1]->withStamp(new PresetStamp('entity_saved', ['resource' => 'resource'])); - $event = new PresentationEvent($envelopes, array()); + $event = new PresentationEvent($envelopes, []); $eventDispatcher->dispatch($event); $this->assertEquals($envelopes, $event->getEnvelopes()); } - /** - * @return void - */ - public function testTranslationListenerWithAutoTranslateDisabled() + public function testTranslationListenerWithAutoTranslateDisabled(): void { $eventDispatcher = new EventDispatcher(); - $this->setProperty($eventDispatcher, 'listeners', array()); + ObjectInvader::from($eventDispatcher)->set('listeners', []); - $listener = new TranslationListener(new EchoTranslator(), false); - $eventDispatcher->addSubscriber($listener); + $listener = new TranslationListener(new EchoTranslator()); + $eventDispatcher->addListener($listener); $notification = new Notification(); $notification->setTitle('PHPFlasher'); $notification->setMessage('success message'); - $envelopes = array( + $envelopes = [ new Envelope($notification), new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; - $envelopes[0]->withStamp(new TranslationStamp(array('resource' => 'resource'), 'ar')); - $envelopes[0]->withStamp(new PresetStamp('entity_saved', array('resource' => 'resource'))); + $envelopes[0]->withStamp(new TranslationStamp(['resource' => 'resource'], 'ar')); + $envelopes[0]->withStamp(new PresetStamp('entity_saved', ['resource' => 'resource'])); - $envelopes[1]->withStamp(new TranslationStamp(array('resource' => 'resource'), 'ar')); - $envelopes[1]->withStamp(new PresetStamp('entity_saved', array('resource' => 'resource'))); + $envelopes[1]->withStamp(new TranslationStamp(['resource' => 'resource'], 'ar')); + $envelopes[1]->withStamp(new PresetStamp('entity_saved', ['resource' => 'resource'])); - $event = new PresentationEvent($envelopes, array()); + $event = new PresentationEvent($envelopes, []); $eventDispatcher->dispatch($event); $this->assertEquals($envelopes, $event->getEnvelopes()); diff --git a/tests/Prime/Factory/NotificationFactoryLocatorTest.php b/tests/Prime/Factory/NotificationFactoryLocatorTest.php new file mode 100644 index 00000000..f5bc6bfa --- /dev/null +++ b/tests/Prime/Factory/NotificationFactoryLocatorTest.php @@ -0,0 +1,56 @@ +addFactory('alias', $factoryMock); + + $retrievedFactory = $notificationFactoryLocator->get('alias'); + + $this->assertSame($factoryMock, $retrievedFactory); + } + + public function testGetWithUnregisteredFactory(): void + { + $notificationFactoryLocator = new NotificationFactoryLocator(); + + $this->expectException(FactoryNotFoundException::class); + $notificationFactoryLocator->get('alias'); + } + + public function testHas(): void + { + $factoryMock = \Mockery::mock(NotificationFactoryInterface::class); + $notificationFactoryLocator = new NotificationFactoryLocator(); + + $this->assertFalse($notificationFactoryLocator->has('alias')); + + $notificationFactoryLocator->addFactory('alias', $factoryMock); + + $this->assertTrue($notificationFactoryLocator->has('alias')); + } + + public function testAddFactory(): void + { + $factoryMock = \Mockery::mock(NotificationFactoryInterface::class); + $notificationFactoryLocator = new NotificationFactoryLocator(); + $notificationFactoryLocator->addFactory('alias', $factoryMock); + + $this->assertTrue($notificationFactoryLocator->has('alias')); + } +} diff --git a/tests/Prime/Factory/NotificationFactoryTest.php b/tests/Prime/Factory/NotificationFactoryTest.php index c5f5ba69..e5affe20 100644 --- a/tests/Prime/Factory/NotificationFactoryTest.php +++ b/tests/Prime/Factory/NotificationFactoryTest.php @@ -1,48 +1,48 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Factory; use Flasher\Prime\Factory\NotificationFactory; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Notification\NotificationBuilderInterface; +use Flasher\Prime\Storage\StorageManagerInterface; +use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\TestCase; -class NotificationFactoryTest extends TestCase +final class NotificationFactoryTest extends TestCase { - /** - * @return void - */ - public function testCreateNotificationBuilder() + use MockeryPHPUnitIntegration; + + public function testCreateNotificationBuilder(): void { - $factory = new NotificationFactory(); + $storageManager = \Mockery::mock(StorageManagerInterface::class); + $factory = new NotificationFactory($storageManager); + $builder = $factory->createNotificationBuilder(); - $this->assertInstanceOf('Flasher\Prime\Notification\NotificationBuilderInterface', $builder); + $this->assertInstanceOf(NotificationBuilderInterface::class, $builder); } - /** - * @return void - */ - public function testGetStorageManager() + public function testStorageManagerForwardsAnyMethodCall(): void { - $factory = new NotificationFactory(); - $manager = $factory->getStorageManager(); + $method = 'test_method'; + $arguments = ['test_argument']; - $this->assertInstanceOf('Flasher\Prime\Storage\StorageManagerInterface', $manager); - } + $mockedInterface = \Mockery::mock(NotificationBuilderInterface::class); + $mockedInterface->allows($method) + ->withArgs($arguments) + ->andReturnTrue(); - /** - * @return void - */ - public function testDynamicCallToNotificationBuilder() - { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); - $storageManager->expects($this->once())->method('add'); + $storageManager = \Mockery::mock(StorageManagerInterface::class); + $factory = \Mockery::mock(NotificationFactory::class, [$storageManager]) // @phpstan-ignore-line + ->makePartial() + ->allows('createNotificationBuilder') + ->andReturns($mockedInterface) + ->getMock(); - $factory = new NotificationFactory($storageManager); - $factory->addCreated(); + $result = $factory->__call($method, $arguments); // @phpstan-ignore-line + + $this->assertTrue($result); } } diff --git a/tests/Prime/Filter/CriteriaBuilderTest.php b/tests/Prime/Filter/CriteriaBuilderTest.php deleted file mode 100644 index 127a9104..00000000 --- a/tests/Prime/Filter/CriteriaBuilderTest.php +++ /dev/null @@ -1,177 +0,0 @@ - - */ - -namespace Flasher\Tests\Prime\Filter; - -use Flasher\Prime\Filter\CriteriaBuilder; -use Flasher\Prime\Filter\Filter; -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\Notification; -use Flasher\Prime\Stamp\CreatedAtStamp; -use Flasher\Prime\Stamp\PresetStamp; -use Flasher\Prime\Stamp\PriorityStamp; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Tests\Prime\TestCase; - -class CriteriaBuilderTest extends TestCase -{ - /** - * @return void - */ - public function testItAddsPrioritySpecification() - { - $filter = $this->getFilter(); - $criteria = array('priority' => 2); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildPriority(); - - $specification = $this->getProperty($filter, 'specification'); - - $this->assertInstanceOf('Flasher\Prime\Filter\Specification\PrioritySpecification', $specification); - $this->assertEquals(2, $this->getProperty($specification, 'minPriority')); - $this->assertNull($this->getProperty($specification, 'maxPriority')); - } - - /** - * @return void - */ - public function testItAddsHopsSpecification() - { - $filter = $this->getFilter(); - $criteria = array('hops' => 2); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildHops(); - - $specification = $this->getProperty($filter, 'specification'); - - $this->assertInstanceOf('Flasher\Prime\Filter\Specification\HopsSpecification', $specification); - $this->assertEquals(2, $this->getProperty($specification, 'minAmount')); - $this->assertNull($this->getProperty($specification, 'maxAmount')); - } - - /** - * @return void - */ - public function testItAddsDelaySpecification() - { - $filter = $this->getFilter(); - $criteria = array('delay' => 2); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildDelay(); - - $specification = $this->getProperty($filter, 'specification'); - - $this->assertInstanceOf('Flasher\Prime\Filter\Specification\DelaySpecification', $specification); - $this->assertEquals(2, $this->getProperty($specification, 'minDelay')); - $this->assertNull($this->getProperty($specification, 'maxDelay')); - } - - /** - * @return void - */ - public function testItAddsLifeSpecification() - { - $filter = $this->getFilter(); - $criteria = array('life' => 2); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildLife(); - - $specification = $this->getProperty($filter, 'specification'); - - $this->assertInstanceOf('Flasher\Prime\Filter\Specification\HopsSpecification', $specification); - $this->assertEquals(2, $this->getProperty($specification, 'minAmount')); - $this->assertNull($this->getProperty($specification, 'maxAmount')); - } - - /** - * @return void - */ - public function testItAddsOrdering() - { - $filter = $this->getFilter(); - $criteria = array('order_by' => 'priority'); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildOrder(); - - $orderings = $this->getProperty($filter, 'orderings'); - - $this->assertEquals(array("Flasher\Prime\Stamp\PriorityStamp" => 'ASC'), $orderings); - } - - /** - * @return void - */ - public function testItFilterEnvelopesByStamps() - { - $filter = $this->getFilter(); - $criteria = array('stamps' => 'preset'); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildStamps(); - - $specification = $this->getProperty($filter, 'specification'); - - $this->assertInstanceOf('Flasher\Prime\Filter\Specification\StampsSpecification', $specification); - $this->assertEquals(array('Flasher\Prime\Stamp\PresetStamp'), $this->getProperty($specification, 'stamps')); - $this->assertEquals('or', $this->getProperty($specification, 'strategy')); - } - - /** - * @return void - */ - public function testItFilterEnvelopesByCallbacks() - { - $callback = function () {}; - $filter = $this->getFilter(); - $criteria = array('filter' => $callback); - - $criteriaBuilder = new CriteriaBuilder($filter, $criteria); - $criteriaBuilder->buildCallback(); - - $specification = $this->getProperty($filter, 'specification'); - - $this->assertInstanceOf('Flasher\Prime\Filter\Specification\CallbackSpecification', $specification); - $this->assertEquals($filter, $this->getProperty($specification, 'filter')); - $this->assertEquals($callback, $this->getProperty($specification, 'callback')); - } - - /** - * @return Filter - */ - private function getFilter() - { - $envelopes = array(); - - $notification = new Notification(); - $notification->setMessage('success message'); - $notification->setTitle('PHPFlasher'); - $notification->setType('success'); - $envelopes[] = new Envelope($notification, array( - new CreatedAtStamp(new \DateTime('2023-02-05 16:22:50')), - new UuidStamp('1111'), - new PriorityStamp(1), - new PresetStamp('entity_saved'), - )); - - $notification = new Notification(); - $notification->setMessage('warning message'); - $notification->setTitle('yoeunes/toastr'); - $notification->setType('warning'); - $envelopes[] = new Envelope($notification, array( - new CreatedAtStamp(new \DateTime('2023-02-06 16:22:50')), - new UuidStamp('2222'), - new PriorityStamp(3), - )); - - return new Filter($envelopes, array()); - } -} diff --git a/tests/Prime/Fixtures/Asset/test.css b/tests/Prime/Fixtures/Asset/test.css new file mode 100644 index 00000000..1972bba1 --- /dev/null +++ b/tests/Prime/Fixtures/Asset/test.css @@ -0,0 +1,3 @@ +body { + background-color: #fff; +} diff --git a/tests/Prime/Fixtures/Asset/test1.css b/tests/Prime/Fixtures/Asset/test1.css new file mode 100644 index 00000000..48fe1b57 --- /dev/null +++ b/tests/Prime/Fixtures/Asset/test1.css @@ -0,0 +1,3 @@ +body { + background-color: #111; +} diff --git a/tests/Prime/Fixtures/Asset/test2.css b/tests/Prime/Fixtures/Asset/test2.css new file mode 100644 index 00000000..7c58dbc1 --- /dev/null +++ b/tests/Prime/Fixtures/Asset/test2.css @@ -0,0 +1,3 @@ +body { + background-color: #222; +} diff --git a/tests/Prime/Fixtures/Asset/test3.css b/tests/Prime/Fixtures/Asset/test3.css new file mode 100644 index 00000000..3ea8e427 --- /dev/null +++ b/tests/Prime/Fixtures/Asset/test3.css @@ -0,0 +1,3 @@ +body { + background-color: #333; +} diff --git a/tests/Prime/Fixtures/EventDispatcher/Event/InvokeableEvent.php b/tests/Prime/Fixtures/EventDispatcher/Event/InvokeableEvent.php new file mode 100644 index 00000000..23a023ed --- /dev/null +++ b/tests/Prime/Fixtures/EventDispatcher/Event/InvokeableEvent.php @@ -0,0 +1,40 @@ +invoked = true; + ++$this->invokeCount; + } + + public function isInvoked(): bool + { + return $this->invoked; + } + + public function getInvokeCount(): int + { + return $this->invokeCount; + } + + public function stopPropagation(): void + { + $this->propagationStopped = true; + } + + public function isPropagationStopped(): bool + { + return $this->propagationStopped; + } +} diff --git a/tests/Prime/Fixtures/EventDispatcher/Event/StoppableEvent.php b/tests/Prime/Fixtures/EventDispatcher/Event/StoppableEvent.php new file mode 100644 index 00000000..60492fc9 --- /dev/null +++ b/tests/Prime/Fixtures/EventDispatcher/Event/StoppableEvent.php @@ -0,0 +1,22 @@ +propagationStopped = true; + } + + public function isPropagationStopped(): bool + { + return $this->propagationStopped; + } +} diff --git a/tests/Prime/Fixtures/EventDispatcher/EventListener/InvokeableEventListener.php b/tests/Prime/Fixtures/EventDispatcher/EventListener/InvokeableEventListener.php new file mode 100644 index 00000000..669e13de --- /dev/null +++ b/tests/Prime/Fixtures/EventDispatcher/EventListener/InvokeableEventListener.php @@ -0,0 +1,21 @@ +invoke(); + } + + public function getSubscribedEvents(): string + { + return InvokeableEvent::class; + } +} diff --git a/tests/Prime/Fixtures/EventDispatcher/EventListener/NonCallableListener.php b/tests/Prime/Fixtures/EventDispatcher/EventListener/NonCallableListener.php new file mode 100644 index 00000000..c79c1e1f --- /dev/null +++ b/tests/Prime/Fixtures/EventDispatcher/EventListener/NonCallableListener.php @@ -0,0 +1,22 @@ +eventName = $eventName; + } + + public function getSubscribedEvents(): string + { + return $this->eventName; + } +} diff --git a/tests/Prime/Fixtures/EventDispatcher/EventListener/StoppableEventListener.php b/tests/Prime/Fixtures/EventDispatcher/EventListener/StoppableEventListener.php new file mode 100644 index 00000000..f4bdbe16 --- /dev/null +++ b/tests/Prime/Fixtures/EventDispatcher/EventListener/StoppableEventListener.php @@ -0,0 +1,21 @@ +stopPropagation(); + } + + public function getSubscribedEvents(): string + { + return StoppableEvent::class; + } +} diff --git a/tests/Prime/FlasherTest.php b/tests/Prime/FlasherTest.php new file mode 100644 index 00000000..9cf4d831 --- /dev/null +++ b/tests/Prime/FlasherTest.php @@ -0,0 +1,119 @@ +factoryLocatorMock = \Mockery::mock(NotificationFactoryLocatorInterface::class); + $this->responseManagerMock = \Mockery::mock(ResponseManagerInterface::class); + $this->storageManagerMock = \Mockery::mock(StorageManagerInterface::class); + + $this->flasher = new Flasher('default', $this->factoryLocatorMock, $this->responseManagerMock, $this->storageManagerMock); + } + + public function testUseWithEmptyFactory(): void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Unable to resolve empty factory'); + + $this->flasher->use(' '); + } + + public function testUseReturnsFactoryLocatorFactoryWhenAliasFound(): void + { + $this->factoryLocatorMock->expects() + ->has('alias') + ->andReturns(true); + + $this->factoryLocatorMock->expects() + ->get('alias') + ->andReturns(\Mockery::mock(NotificationFactoryInterface::class)); + + $result = $this->flasher->use('alias'); + + $this->assertInstanceOf(NotificationFactoryInterface::class, $result); + } + + public function testUseReturnsNewFactoryWhenAliasNotFound(): void + { + $this->factoryLocatorMock->expects() + ->has('alias') + ->andReturns(false); + + $this->factoryLocatorMock->expects() + ->get('') + ->never(); + + $result = $this->flasher->use('alias'); + + $this->assertInstanceOf(NotificationFactoryInterface::class, $result); + } + + public function testCreateRunsUse(): void + { + $this->factoryLocatorMock->expects() + ->has('alias') + ->andReturns(true); + + $this->factoryLocatorMock->expects() + ->get('alias') + ->andReturns(\Mockery::mock(NotificationFactoryInterface::class)); + + $result = $this->flasher->create('alias'); + + $this->assertInstanceOf(NotificationFactoryInterface::class, $result); + } + + public function testRenderRunsRenderManager(): void + { + $this->responseManagerMock->expects() + ->render('html', [], []) + ->andReturns('Mocked Render Result'); + + $result = $this->flasher->render(); + + $this->assertSame('Mocked Render Result', $result); + } + + public function testCallForwardsToUseMethod(): void + { + $this->factoryLocatorMock->expects() + ->has('default') + ->andReturns(true); + + $mockedFactory = \Mockery::mock(NotificationFactoryInterface::class); + $mockedFactory->expects('randomMethod') + ->with('param') + ->andReturns('Mocked method call'); + + $this->factoryLocatorMock->expects('get') + ->with('default') + ->andReturns($mockedFactory); + + $result = $this->flasher->randomMethod('param'); // @phpstan-ignore-line + + $this->assertSame('Mocked method call', $result); + } +} diff --git a/tests/Prime/Helper/ObjectInvader.php b/tests/Prime/Helper/ObjectInvader.php new file mode 100644 index 00000000..dab8cd17 --- /dev/null +++ b/tests/Prime/Helper/ObjectInvader.php @@ -0,0 +1,100 @@ + + */ + public \ReflectionClass $reflected; + + /** + * @phpstan-param T $obj + * + * @throws \ReflectionException + */ + public function __construct(object $obj) + { + $this->obj = $obj; + $this->reflected = new \ReflectionClass($obj); + } + + /** + * @phpstan-param T $obj + * + * @phpstan-return self + * + * @throws \ReflectionException + */ + public static function from(object $obj): self + { + return new self($obj); + } + + /** + * Allows dynamic property access. + * + * @param string $name name of the property + * + * @throws \ReflectionException + */ + public function get(string $name): mixed + { + $property = $this->reflected->getProperty($name); + + $property->setAccessible(true); + + return $property->getValue($this->obj); + } + + /** + * Allows dynamic setting of properties. + * + * @param string $name name of the property + * @param mixed $value new value for the property + * + * @throws \ReflectionException + */ + public function set(string $name, mixed $value): void + { + $property = $this->reflected->getProperty($name); + + $property->setAccessible(true); + + $property->setValue($this->obj, $value); + } + + /** + * Allows dynamic calling of methods. + * + * @param string $name name of the method + * @param array $params parameters to pass to the method + * + * @throws \ReflectionException + * + * @phpstan-ignore-next-line + */ + public function call(string $name, array $params = []): mixed + { + $method = $this->reflected->getMethod($name); + + $method->setAccessible(true); + + return $method->invoke($this->obj, ...$params); + } +} diff --git a/tests/Prime/Http/Csp/ContentSecurityPolicyHandlerTest.php b/tests/Prime/Http/Csp/ContentSecurityPolicyHandlerTest.php new file mode 100644 index 00000000..1f208946 --- /dev/null +++ b/tests/Prime/Http/Csp/ContentSecurityPolicyHandlerTest.php @@ -0,0 +1,245 @@ +nonceGeneratorMock = $this->createMock(NonceGeneratorInterface::class); + $this->requestMock = $this->createMock(RequestInterface::class); + $this->responseMock = $this->createMock(ResponseInterface::class); + + $this->cspHandler = new ContentSecurityPolicyHandler($this->nonceGeneratorMock); + } + + public function testGetNoncesFromRequestHeaders(): void + { + $this->requestMock->method('hasHeader')->willReturnCallback(function ($headerName) { + return \in_array($headerName, ['X-PHPFlasher-Script-Nonce', 'X-PHPFlasher-Style-Nonce']); + }); + $this->requestMock->method('getHeader')->willReturnCallback(function ($headerName) { + return 'X-PHPFlasher-Script-Nonce' === $headerName ? 'test-script-nonce' : 'test-style-nonce'; + }); + + $nonces = $this->cspHandler->getNonces($this->requestMock); + + $this->assertSame([ + 'csp_script_nonce' => 'test-script-nonce', + 'csp_style_nonce' => 'test-style-nonce', + ], $nonces); + } + + public function testGetNoncesFromResponseHeaders(): void + { + $this->requestMock->method('hasHeader')->willReturnCallback(function ($headerName) { + return \in_array($headerName, ['X-PHPFlasher-Script-Nonce', 'X-PHPFlasher-Style-Nonce']); + }); + $this->requestMock->method('getHeader')->willReturnCallback(function ($headerName) { + return 'X-PHPFlasher-Script-Nonce' === $headerName ? 'test-script-nonce' : 'test-style-nonce'; + }); + + $nonces = $this->cspHandler->getNonces($this->requestMock, $this->responseMock); + + $this->assertSame([ + 'csp_script_nonce' => 'test-script-nonce', + 'csp_style_nonce' => 'test-style-nonce', + ], $nonces); + } + + public function testGetGeneratedNonces(): void + { + $this->nonceGeneratorMock->method('generate') + ->willReturn('generated-nonce'); + + $this->responseMock->expects($this->exactly(2)) + ->method('setHeader') + ->willReturnCallback(function ($headerName, $value) { + static $calls = 0; + switch (++$calls) { + case 1: + $this->assertSame('X-PHPFlasher-Script-Nonce', $headerName); + $this->assertSame('generated-nonce', $value); + break; + case 2: + $this->assertSame('X-PHPFlasher-Style-Nonce', $headerName); + $this->assertSame('generated-nonce', $value); + break; + default: + $this->fail('setHeader called more than twice.'); + } + }); + + $nonces = $this->cspHandler->getNonces($this->requestMock, $this->responseMock); + + $this->assertSame([ + 'csp_script_nonce' => 'generated-nonce', + 'csp_style_nonce' => 'generated-nonce', + ], $nonces); + } + + public function testDisableCsp(): void + { + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); + + // Simulate the internal tracking of CSP headers. + $cspHeaders = [ + 'Content-Security-Policy' => true, + 'X-Content-Security-Policy' => true, + ]; + + // Simulate response behavior based on CSP header tracking. + $response->method('hasHeader')->willReturnCallback(function ($headerName) use (&$cspHeaders) { + return !empty($cspHeaders[$headerName]); + }); + + // Mock the removal of headers to update our simulated tracking. + $response->method('removeHeader')->willReturnCallback(function ($headerName) use (&$cspHeaders) { + unset($cspHeaders[$headerName]); + }); + + // Assuming CSP is initially enabled and headers are present. + // This call should set CSP headers. + $this->cspHandler->updateResponseHeaders($request, $response); + + // Check if CSP headers are initially present. + $this->assertTrue($response->hasHeader('Content-Security-Policy')); + $this->assertTrue($response->hasHeader('X-Content-Security-Policy')); + + // Disabling CSP. + $this->cspHandler->disableCsp(); + + // Now CSP headers should be removed. + // This call should remove CSP headers. + $this->cspHandler->updateResponseHeaders($request, $response); + + // Check if CSP headers are removed. + $this->assertFalse($response->hasHeader('Content-Security-Policy')); + $this->assertFalse($response->hasHeader('X-Content-Security-Policy')); + } + + public function testUpdateResponseHeadersWhenCspIsDisabled(): void + { + $removedHeaders = []; + $this->responseMock->method('removeHeader')->willReturnCallback(function ($headerName) use (&$removedHeaders) { + $removedHeaders[] = $headerName; + }); + + $this->cspHandler->disableCsp(); + $nonces = $this->cspHandler->updateResponseHeaders($this->requestMock, $this->responseMock); + + $expectedRemovedHeaders = [ + 'Content-Security-Policy', + 'X-Content-Security-Policy', + 'Content-Security-Policy-Report-Only', + ]; + $this->assertSame([], $nonces); + foreach ($expectedRemovedHeaders as $header) { + $this->assertContains($header, $removedHeaders, "$header was not removed."); + } + } + + public function testUpdateResponseHeadersWhenCspIsEnabled(): void + { + $setHeaders = []; + $this->responseMock->method('setHeader')->willReturnCallback(function ($headerName, $value) use (&$setHeaders) { + $setHeaders[$headerName] = $value; + }); + + $this->nonceGeneratorMock->method('generate')->willReturnOnConsecutiveCalls('nonce1', 'nonce2', 'nonce3', 'nonce4'); + + $nonces = $this->cspHandler->updateResponseHeaders($this->requestMock, $this->responseMock); + + // Verify that nonces were generated and set as expected + $this->assertCount(2, $setHeaders, 'Expected two headers to be set.'); + $this->assertSame('nonce1', $setHeaders['X-PHPFlasher-Script-Nonce']); + $this->assertSame('nonce2', $setHeaders['X-PHPFlasher-Style-Nonce']); + + $this->assertSame([ + 'csp_script_nonce' => 'nonce1', + 'csp_style_nonce' => 'nonce2', + ], $nonces); + } + + public function testGetNoncesFromHeaders(): void + { + $nonces = ['csp_script_nonce' => 'random1', 'csp_style_nonce' => 'random2']; + + $this->requestMock->method('hasHeader')->willReturn(true); + + $this->requestMock->expects($this->exactly(2))->method('getHeader') + ->willReturnCallback(function ($header) use ($nonces) { + return 'X-PHPFlasher-Script-Nonce' === $header ? $nonces['csp_script_nonce'] : $nonces['csp_style_nonce']; + }); + + $result = $this->cspHandler->getNonces($this->requestMock); + $this->assertSame($nonces, $result); + } + + public function testGetNoncesFromResponseHeadersWhenNoHeadersInRequest(): void + { + $nonces = ['csp_script_nonce' => 'random3', 'csp_style_nonce' => 'random4']; + + $this->requestMock->method('hasHeader')->willReturn(false); + $this->responseMock->method('hasHeader')->willReturn(true); + + $this->responseMock->expects($this->exactly(2))->method('getHeader') + ->willReturnCallback(function ($header) use ($nonces) { + return 'X-PHPFlasher-Script-Nonce' === $header ? $nonces['csp_script_nonce'] : $nonces['csp_style_nonce']; + }); + + $result = $this->cspHandler->getNonces($this->requestMock, $this->responseMock); + $this->assertSame($nonces, $result); + } + + public function testGetNoncesWithRandomGeneratedNoncesWhenHeadersEmpty(): void + { + $nonces = ['csp_script_nonce' => 'random5', 'csp_style_nonce' => 'random6']; + + $this->nonceGeneratorMock->expects($this->exactly(2))->method('generate') + ->willReturnCallback(function () use ($nonces) { + static $i = 0; + + return $i++ ? $nonces['csp_style_nonce'] : $nonces['csp_script_nonce']; + }); + + $this->requestMock->expects($this->exactly(1))->method('hasHeader')->willReturn(false); + $this->responseMock->expects($this->exactly(1))->method('hasHeader')->willReturn(false); + + $this->responseMock->expects($this->exactly(2))->method('setHeader') + ->willReturnCallback(function ($headerName, $headerValue) { + static $i = 0; + if (0 === $i++) { + $this->assertSame('X-PHPFlasher-Script-Nonce', $headerName); + $this->assertSame('random5', $headerValue); + } else { + $this->assertSame('X-PHPFlasher-Style-Nonce', $headerName); + $this->assertSame('random6', $headerValue); + } + }); + + $result = $this->cspHandler->getNonces($this->requestMock, $this->responseMock); + $this->assertSame($nonces, $result); + } +} diff --git a/tests/Prime/Http/Csp/NonceGeneratorTest.php b/tests/Prime/Http/Csp/NonceGeneratorTest.php new file mode 100644 index 00000000..7b7711c7 --- /dev/null +++ b/tests/Prime/Http/Csp/NonceGeneratorTest.php @@ -0,0 +1,63 @@ +nonceGenerator = new NonceGenerator(); + } + + /** + * testGenerateMethodUnique check that the nonce generated is unique. + */ + public function testGenerateMethodUnique(): void + { + $nonces = []; + + // Generate a list of nonces + for ($i = 0; $i < 10; ++$i) { + $nonces[] = $this->nonceGenerator->generate(); + } + + // Check that there are no duplicate values + $this->assertCount(10, array_unique($nonces)); + } + + /** + * testGenerateMethodHexadecimal check that the nonce generated is a valid hexadecimal string. + */ + public function testGenerateMethodHexadecimal(): void + { + // Generate a nonce + $nonce = $this->nonceGenerator->generate(); + + // Check that the nonce is a valid hexadecimal string + $this->assertTrue(ctype_xdigit($nonce)); + } + + /** + * testGenerateMethodLength check that the nonce generated is indeed 32 characters long. + */ + public function testGenerateMethodLength(): void + { + // Generate a nonce + $nonce = $this->nonceGenerator->generate(); + + // Check that the nonce is the correct length + $this->assertSame(32, \strlen($nonce)); + } +} diff --git a/tests/Prime/Http/RequestExtensionTest.php b/tests/Prime/Http/RequestExtensionTest.php new file mode 100644 index 00000000..4e1a3580 --- /dev/null +++ b/tests/Prime/Http/RequestExtensionTest.php @@ -0,0 +1,89 @@ + */ + private array $mapping = [ + 'success' => ['happy', 'joy'], + 'error' => ['sad', 'oops'], + ]; + + protected function setUp(): void + { + $this->flasher = \Mockery::mock(FlasherInterface::class); + $this->request = \Mockery::mock(RequestInterface::class); + $this->response = \Mockery::mock(ResponseInterface::class); + } + + public function testFlashWithoutSession(): void + { + $this->request->expects()->hasSession()->andReturns(false); + + $extension = new RequestExtension($this->flasher, $this->mapping); + $response = $extension->flash($this->request, $this->response); + + $this->assertSame($this->response, $response, 'Response should be returned unchanged if request has no session.'); + } + + public function testFlashWithSessionAndMessages(): void + { + $this->request->expects()->hasSession()->andReturns(true); + $this->request->allows('hasType')->andReturnUsing(fn ($type) => 'happy' === $type); + $this->request->allows('getType')->andReturnUsing(fn ($type) => 'happy' === $type ? ['Good job!'] : []); + + $this->flasher->expects()->flash('success', 'Good job!'); + $this->request->expects()->forgetType('happy')->once(); + + $extension = new RequestExtension($this->flasher, $this->mapping); + $extension->flash($this->request, $this->response); + } + + public function testProcessRequestIgnoresUnmappedTypes(): void + { + $this->request->expects()->hasSession()->andReturns(true); + $this->request->allows('hasType')->andReturnUsing(fn ($type) => 'unmappedType' === $type); + + $this->flasher->expects()->flash()->never(); + $this->request->expects()->forgetType('unmappedType')->never(); + + $extension = new RequestExtension($this->flasher, $this->mapping); + $extension->flash($this->request, $this->response); + } + + public function testConstructorFlattensMappingCorrectly(): void + { + $extension = new RequestExtension($this->flasher, $this->mapping); + + $reflectedClass = new \ReflectionClass($extension); + $flatMappingProperty = $reflectedClass->getProperty('mapping'); + + $expectedFlatMapping = [ + 'happy' => 'success', + 'joy' => 'success', + 'sad' => 'error', + 'oops' => 'error', + ]; + + $this->assertSame($expectedFlatMapping, $flatMappingProperty->getValue($extension), 'Mapping should be flattened correctly.'); + } +} diff --git a/tests/Prime/Http/ResponseExtensionTest.php b/tests/Prime/Http/ResponseExtensionTest.php new file mode 100644 index 00000000..546afdfd --- /dev/null +++ b/tests/Prime/Http/ResponseExtensionTest.php @@ -0,0 +1,205 @@ +Flasher HTML'; + + $contentBefore = 'before content '.HtmlPresenter::BODY_END_PLACE_HOLDER.' after content'; + + $cspHandler->expects()->updateResponseHeaders($request, $response)->once()->andReturn([ + 'csp_script_nonce' => 'script-nonce', + 'csp_style_nonce' => 'style-nonce', + ]); + + $flasher->expects()->render('html', [], [ + 'envelopes_only' => false, + 'csp_script_nonce' => 'script-nonce', + 'csp_style_nonce' => 'style-nonce', + ])->once()->andReturn($htmlResponse); + + $request->allows([ + 'isXmlHttpRequest' => false, + 'isHtmlRequestFormat' => true, + ]); + + $response->allows([ + 'isSuccessful' => true, + 'isHtml' => true, + 'isRedirection' => false, + 'isAttachment' => false, + 'isJson' => false, + 'getContent' => $contentBefore, + 'setContent' => \Mockery::on(function ($content) use ($htmlResponse) { + $expectedContent = 'before content '.$htmlResponse."\n".' after content'; + $this->assertSame($expectedContent, $content); + + return true; + }), + ]); + + $responseExtension = new ResponseExtension($flasher, $cspHandler); + $modifiedResponse = $responseExtension->render($request, $response); + + $this->assertInstanceOf(ResponseInterface::class, $modifiedResponse); + } + + public function testRenderNotRenderableDueToAjaxRequest(): void + { + $flasher = \Mockery::mock(FlasherInterface::class); + $cspHandler = \Mockery::mock(ContentSecurityPolicyHandlerInterface::class); + $request = \Mockery::mock(RequestInterface::class); + $response = \Mockery::mock(ResponseInterface::class); + + $request->allows([ + 'isXmlHttpRequest' => true, + 'isHtmlRequestFormat' => false, + ]); + + $response->allows('getContent')->never(); + $flasher->allows('render')->never(); + + $responseExtension = new ResponseExtension($flasher, $cspHandler); + $unmodifiedResponse = $responseExtension->render($request, $response); + + $this->assertSame($response, $unmodifiedResponse); + } + + public function testRenderWithoutPlaceholder(): void + { + $flasher = \Mockery::mock(FlasherInterface::class); + $cspHandler = \Mockery::mock(ContentSecurityPolicyHandlerInterface::class); + $request = \Mockery::mock(RequestInterface::class); + $response = \Mockery::mock(ResponseInterface::class); + + $contentBefore = 'content without placeholder'; + + $request->allows([ + 'isXmlHttpRequest' => false, + 'isHtmlRequestFormat' => true, + ]); + + $response->allows([ + 'isSuccessful' => true, + 'isHtml' => true, + 'isRedirection' => false, + 'isAttachment' => false, + 'isJson' => false, + 'getContent' => $contentBefore, + ]); + + $flasher->allows('render')->never(); + + $responseExtension = new ResponseExtension($flasher, $cspHandler); + $unmodifiedResponse = $responseExtension->render($request, $response); + + $this->assertSame($response, $unmodifiedResponse); + } + + #[DataProvider('placeholderProvider')] + public function testRenderWithDifferentPlaceholders(string $placeholder): void + { + $flasher = \Mockery::mock(FlasherInterface::class); + $cspHandler = \Mockery::mock(ContentSecurityPolicyHandlerInterface::class); + $request = \Mockery::mock(RequestInterface::class); + $response = \Mockery::mock(ResponseInterface::class); + $htmlResponse = '
      Flasher HTML
      '; + + $contentBefore = "before content {$placeholder} after content"; + + $cspHandler->allows()->updateResponseHeaders($request, $response)->andReturn([]); + $flasher->allows()->render('html', [], \Mockery::any())->andReturn($htmlResponse); + + $request->allows([ + 'isXmlHttpRequest' => false, + 'isHtmlRequestFormat' => true, + ]); + + $response->allows([ + 'isSuccessful' => true, + 'isHtml' => true, + 'isRedirection' => false, + 'isAttachment' => false, + 'isJson' => false, + 'getContent' => $contentBefore, + 'setContent' => \Mockery::any(), + ]); + + $responseExtension = new ResponseExtension($flasher, $cspHandler); + $responseExtension->render($request, $response); + + $htmlInjection = HtmlPresenter::FLASHER_REPLACE_ME === $placeholder ? sprintf('options.push(%s);', $htmlResponse) : $htmlResponse; + $expectedContent = str_replace($placeholder, "{$htmlInjection}\n{$placeholder}", $contentBefore); + + $response->shouldHaveReceived('setContent')->with($expectedContent)->once(); + } + + public function testRenderWithCspNonces(): void + { + $flasher = \Mockery::mock(FlasherInterface::class); + $cspHandler = \Mockery::mock(ContentSecurityPolicyHandlerInterface::class); + $request = \Mockery::mock(RequestInterface::class); + $response = \Mockery::mock(ResponseInterface::class); + + $cspNonceScript = 'nonce-script'; + $cspNonceStyle = 'nonce-style'; + $contentBefore = 'content '.HtmlPresenter::BODY_END_PLACE_HOLDER; + + $cspHandler->expects()->updateResponseHeaders($request, $response)->once()->andReturn([ + 'csp_script_nonce' => $cspNonceScript, + 'csp_style_nonce' => $cspNonceStyle, + ]); + + $flasher->expects()->render('html', [], [ + 'envelopes_only' => false, + 'csp_script_nonce' => $cspNonceScript, + 'csp_style_nonce' => $cspNonceStyle, + ])->once()->andReturn('
      Flasher HTML with CSP
      '); + + $request->allows([ + 'isXmlHttpRequest' => false, + 'isHtmlRequestFormat' => true, + ]); + + $response->allows([ + 'isSuccessful' => true, + 'isHtml' => true, + 'isRedirection' => false, + 'isAttachment' => false, + 'isJson' => false, + 'getContent' => $contentBefore, + 'setContent' => \Mockery::any(), + ]); + + $responseExtension = new ResponseExtension($flasher, $cspHandler); + $responseExtension->render($request, $response); + } + + public static function placeholderProvider(): \Iterator + { + yield [HtmlPresenter::FLASHER_REPLACE_ME]; + yield [HtmlPresenter::HEAD_END_PLACE_HOLDER]; + yield [HtmlPresenter::BODY_END_PLACE_HOLDER]; + } +} diff --git a/tests/Prime/Notification/EnvelopeTest.php b/tests/Prime/Notification/EnvelopeTest.php index ff015142..e1a5ea99 100644 --- a/tests/Prime/Notification/EnvelopeTest.php +++ b/tests/Prime/Notification/EnvelopeTest.php @@ -1,72 +1,59 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Notification; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Prime\Stamp\HandlerStamp; +use Flasher\Prime\Notification\NotificationInterface; use Flasher\Prime\Stamp\HopsStamp; +use Flasher\Prime\Stamp\PluginStamp; use Flasher\Prime\Stamp\PresetStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\StampInterface; +use PHPUnit\Framework\TestCase; final class EnvelopeTest extends TestCase { - /** - * @return void - */ - public function testConstruct() + public function testConstruct(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); - $stamp = $this->getMockBuilder('Flasher\Prime\Stamp\StampInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); + $stamp = $this->getMockBuilder(StampInterface::class)->getMock(); - $envelope = new Envelope($notification, array($stamp)); + $envelope = new Envelope($notification, [$stamp]); $this->assertEquals($notification, $envelope->getNotification()); - $this->assertEquals(array(\get_class($stamp) => $stamp), $envelope->all()); + $this->assertEquals([$stamp::class => $stamp], $envelope->all()); } - /** - * @return void - */ - public function testWrap() + public function testWrap(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); - $stamp = $this->getMockBuilder('Flasher\Prime\Stamp\StampInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); + $stamp = $this->getMockBuilder(StampInterface::class)->getMock(); - $envelope = Envelope::wrap($notification, array($stamp)); + $envelope = Envelope::wrap($notification, [$stamp]); $this->assertEquals($notification, $envelope->getNotification()); - $this->assertEquals(array(\get_class($stamp) => $stamp), $envelope->all()); + $this->assertEquals([$stamp::class => $stamp], $envelope->all()); } - /** - * @return void - */ - public function testWith() + public function testWith(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); - $stamp1 = $this->getMockBuilder('Flasher\Prime\Stamp\StampInterface')->getMock(); - $stamp2 = $this->getMockBuilder('Flasher\Prime\Stamp\StampInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); + $stamp1 = $this->getMockBuilder(StampInterface::class)->getMock(); + $stamp2 = $this->getMockBuilder(StampInterface::class)->getMock(); $envelope = new Envelope($notification); $envelope->with($stamp1, $stamp2); $this->assertEquals($notification, $envelope->getNotification()); - $this->assertEquals(array(\get_class($stamp1) => $stamp1, \get_class($stamp2) => $stamp2), $envelope->all()); + $this->assertEquals([$stamp1::class => $stamp1, $stamp2::class => $stamp2], $envelope->all()); } - /** - * @return void - */ - public function testWithStamp() + public function testWithStamp(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); - $stamp = $this->getMockBuilder('Flasher\Prime\Stamp\StampInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); + $stamp = $this->getMockBuilder(StampInterface::class)->getMock(); $envelope = new Envelope($notification); $envelope->withStamp($stamp); @@ -74,94 +61,79 @@ final class EnvelopeTest extends TestCase $this->assertContains($stamp, $envelope->all()); } - /** - * @return void - */ - public function testWithout() + public function testWithout(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $stamp1 = new HopsStamp(2); - $stamp2 = new HandlerStamp('flasher'); + $stamp2 = new PluginStamp('flasher'); $stamp3 = new PresetStamp('entity_saved'); $envelope = new Envelope($notification); $envelope->with($stamp1, $stamp2, $stamp3); $this->assertEquals($notification, $envelope->getNotification()); - $this->assertEquals(array(\get_class($stamp1) => $stamp1, \get_class($stamp2) => $stamp2, \get_class($stamp3) => $stamp3), $envelope->all()); + $this->assertEquals([$stamp1::class => $stamp1, $stamp2::class => $stamp2, $stamp3::class => $stamp3], $envelope->all()); $envelope->without($stamp1, $stamp3); - $this->assertEquals(array(\get_class($stamp2) => $stamp2), $envelope->all()); + $this->assertEquals([$stamp2::class => $stamp2], $envelope->all()); } - /** - * @return void - */ - public function testWithoutStamp() + public function testWithoutStamp(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $stamp1 = new HopsStamp(2); - $stamp2 = new HandlerStamp('flasher'); + $stamp2 = new PluginStamp('flasher'); $stamp3 = new PresetStamp('entity_saved'); $envelope = new Envelope($notification); $envelope->with($stamp1, $stamp2, $stamp3); $this->assertEquals($notification, $envelope->getNotification()); - $this->assertEquals(array(\get_class($stamp1) => $stamp1, \get_class($stamp2) => $stamp2, \get_class($stamp3) => $stamp3), $envelope->all()); + $this->assertEquals([$stamp1::class => $stamp1, $stamp2::class => $stamp2, $stamp3::class => $stamp3], $envelope->all()); $envelope->withoutStamp($stamp1); - $this->assertEquals(array(\get_class($stamp2) => $stamp2, \get_class($stamp3) => $stamp3), $envelope->all()); + $this->assertEquals([$stamp2::class => $stamp2, $stamp3::class => $stamp3], $envelope->all()); } - /** - * @return void - */ - public function testGet() + public function testGet(): void { - $notification = $this->getMockBuilder('\Flasher\Prime\Notification\NotificationInterface')->getMock(); - $stamps = array( + $notification = $this->createMock(NotificationInterface::class); + $stamps = [ new HopsStamp(2), - new HandlerStamp('flasher'), + new PluginStamp('flasher'), new PresetStamp('entity_saved'), - ); + ]; $envelope = new Envelope($notification, $stamps); $this->assertEquals($notification, $envelope->getNotification()); - $last = $envelope->get(\get_class($stamps[0])); + $last = $envelope->get($stamps[0]::class); $this->assertEquals($stamps[0], $last); - $this->assertEquals($last, $envelope->get(\get_class($stamps[0]))); + $this->assertEquals($last, $envelope->get($stamps[0]::class)); $this->assertNull($envelope->get('NotFoundStamp')); // @phpstan-ignore-line } - /** - * @return void - */ - public function testAll() + public function testAll(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); - $stamps = array( + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); + $stamps = [ new HopsStamp(2), - new HandlerStamp('flasher'), + new PluginStamp('flasher'), new PresetStamp('entity_saved'), - ); + ]; $envelope = new Envelope($notification, $stamps); $this->assertEquals($notification, $envelope->getNotification()); - $this->assertEquals(array(\get_class($stamps[0]) => $stamps[0], \get_class($stamps[1]) => $stamps[1], \get_class($stamps[2]) => $stamps[2]), $envelope->all()); + $this->assertEquals([$stamps[0]::class => $stamps[0], $stamps[1]::class => $stamps[1], $stamps[2]::class => $stamps[2]], $envelope->all()); } - /** - * @return void - */ - public function testGetNotification() + public function testGetNotification(): void { $notification = new Notification(); @@ -170,178 +142,130 @@ final class EnvelopeTest extends TestCase $this->assertEquals($notification, $envelope->getNotification()); } - /** - * @return void - */ - public function testGetType() + public function testGetType(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('getType')->willReturn('success'); $envelope = new Envelope($notification); - $this->assertEquals('success', $envelope->getType()); + $this->assertSame('success', $envelope->getType()); } - /** - * @return void - */ - public function testSetType() + public function testSetType(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('setType'); $envelope = new Envelope($notification); $envelope->setType('success'); } - /** - * @return void - */ - public function testGetMessage() + public function testGetMessage(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('getMessage')->willReturn('success message'); $envelope = new Envelope($notification); - $this->assertEquals('success message', $envelope->getMessage()); + $this->assertSame('success message', $envelope->getMessage()); } - /** - * @return void - */ - public function testSetMessage() + public function testSetMessage(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('setMessage'); $envelope = new Envelope($notification); $envelope->setMessage('success message'); } - /** - * @return void - */ - public function testGetTitle() + public function testGetTitle(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('getTitle')->willReturn('success title'); $envelope = new Envelope($notification); - $this->assertEquals('success title', $envelope->getTitle()); + $this->assertSame('success title', $envelope->getTitle()); } - /** - * @return void - */ - public function testSetTitle() + public function testSetTitle(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('setTitle'); $envelope = new Envelope($notification); $envelope->setTitle('success title'); } - /** - * @return void - */ - public function testGetOptions() + public function testGetOptions(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); - $notification->expects($this->once())->method('getOptions')->willReturn(array('timeout' => 2500)); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); + $notification->expects($this->once())->method('getOptions')->willReturn(['timeout' => 2500]); $envelope = new Envelope($notification); - $this->assertEquals(array('timeout' => 2500), $envelope->getOptions()); + $this->assertSame(['timeout' => 2500], $envelope->getOptions()); } - /** - * @return void - */ - public function testSetOptions() + public function testSetOptions(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('setOptions'); $envelope = new Envelope($notification); - $envelope->setOptions(array('timeout' => 2500)); + $envelope->setOptions(['timeout' => 2500]); } - /** - * @return void - */ - public function testGetOption() + public function testGetOption(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('getOption')->willReturn(2500); $envelope = new Envelope($notification); - $this->assertEquals(2500, $envelope->getOption('timeout')); + $this->assertSame(2500, $envelope->getOption('timeout')); } - /** - * @return void - */ - public function testSetOption() + public function testSetOption(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('setOption'); $envelope = new Envelope($notification); $envelope->setOption('timeout', 2500); } - /** - * @return void - */ - public function testUnsetOption() + public function testUnsetOption(): void { - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('unsetOption'); $envelope = new Envelope($notification); $envelope->unsetOption('timeout'); } - /** - * @return void - */ - public function testToArray() + public function testToArray(): void { - $array = array( + $array = [ 'title' => 'PHPFlasher', 'message' => 'success message', - 'options' => array('timeout' => 2500), - ); + 'options' => ['timeout' => 2500], + ]; - $notification = $this->getMockBuilder('Flasher\Prime\Notification\NotificationInterface')->getMock(); + $notification = $this->getMockBuilder(NotificationInterface::class)->getMock(); $notification->expects($this->once())->method('toArray')->willReturn($array); - $envelope = new Envelope($notification, new HandlerStamp('flasher')); + $envelope = new Envelope($notification, new PluginStamp('flasher')); - $this->assertEquals(array('notification' => $array, 'handler' => 'flasher'), $envelope->toArray()); - } - - /** - * @return void - */ - public function testCallDynamicCallToNotification() - { - $notification = new DynamicNotification(); - $envelope = new Envelope($notification); - - $this->assertEquals('foobar', $envelope->foo()); - } -} - -class DynamicNotification extends Notification -{ - public function foo() - { - return 'foobar'; + $this->assertSame([ + 'title' => 'PHPFlasher', + 'message' => 'success message', + 'options' => ['timeout' => 2500], + 'metadata' => [ + 'plugin' => 'flasher', + ], + ], $envelope->toArray()); } } diff --git a/tests/Prime/Notification/NotificationBuilderTest.php b/tests/Prime/Notification/NotificationBuilderTest.php index 2e5e5b7b..50a0d487 100644 --- a/tests/Prime/Notification/NotificationBuilderTest.php +++ b/tests/Prime/Notification/NotificationBuilderTest.php @@ -1,595 +1,479 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Notification; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Notification\NotificationBuilder; use Flasher\Prime\Notification\NotificationBuilderInterface; -use Flasher\Prime\Notification\NotificationInterface; +use Flasher\Prime\Notification\Type; +use Flasher\Prime\Stamp\ContextStamp; +use Flasher\Prime\Stamp\DelayStamp; use Flasher\Prime\Stamp\HopsStamp; +use Flasher\Prime\Stamp\PluginStamp; +use Flasher\Prime\Stamp\PresetStamp; use Flasher\Prime\Stamp\PriorityStamp; +use Flasher\Prime\Stamp\StampInterface; +use Flasher\Prime\Stamp\TranslationStamp; +use Flasher\Prime\Stamp\UnlessStamp; +use Flasher\Prime\Stamp\WhenStamp; use Flasher\Prime\Storage\StorageManagerInterface; -use Flasher\Tests\Prime\TestCase; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; -class NotificationBuilderTest extends TestCase +final class NotificationBuilderTest extends TestCase { - /** - * @return void - */ - public function testAddSuccessMessage() + public function testAddSuccessMessage(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addSuccess('success message'); + $builder->success('success message'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::SUCCESS, $envelope->getType()); - $this->assertEquals('success message', $envelope->getMessage()); + $this->assertSame(Type::SUCCESS, $envelope->getType()); + $this->assertSame('success message', $envelope->getMessage()); } - /** - * @return void - */ - public function testAddErrorMessage() + public function testAddErrorMessage(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addError('error message'); + $builder->error('error message'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::ERROR, $envelope->getType()); - $this->assertEquals('error message', $envelope->getMessage()); + $this->assertSame(Type::ERROR, $envelope->getType()); + $this->assertSame('error message', $envelope->getMessage()); } - /** - * @return void - */ - public function testAddWarningMessage() + public function testAddWarningMessage(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addWarning('warning message'); + $builder->warning('warning message'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::WARNING, $envelope->getType()); - $this->assertEquals('warning message', $envelope->getMessage()); + $this->assertSame(Type::WARNING, $envelope->getType()); + $this->assertSame('warning message', $envelope->getMessage()); } - /** - * @return void - */ - public function testAddInfoMessage() + public function testAddInfoMessage(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addInfo('info message'); + $builder->info('info message'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::INFO, $envelope->getType()); - $this->assertEquals('info message', $envelope->getMessage()); + $this->assertSame(Type::INFO, $envelope->getType()); + $this->assertSame('info message', $envelope->getMessage()); } - /** - * @return void - */ - public function testAddFlashMessage() + public function testAddFlashMessage(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addFlash('success', 'success message'); + $builder->flash('success', 'success message'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::SUCCESS, $envelope->getType()); - $this->assertEquals('success message', $envelope->getMessage()); + $this->assertSame(Type::SUCCESS, $envelope->getType()); + $this->assertSame('success message', $envelope->getMessage()); } - /** - * @return void - */ - public function testPushToStorage() + public function testPushToStorage(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); $builder->push(); } - /** - * @return void - */ - public function testNotificationType() + public function testNotificationType(): void { $builder = $this->getNotificationBuilder(); $builder->type('success'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::SUCCESS, $envelope->getType()); + $this->assertSame(Type::SUCCESS, $envelope->getType()); } - /** - * @return void - */ - public function testNotificationMessage() + public function testNotificationMessage(): void { $builder = $this->getNotificationBuilder(); $builder->message('some message'); $envelope = $builder->getEnvelope(); - $this->assertEquals('some message', $envelope->getMessage()); + $this->assertSame('some message', $envelope->getMessage()); } - /** - * @return void - */ - public function testNotificationTitle() + public function testNotificationTitle(): void { $builder = $this->getNotificationBuilder(); $builder->title('some title'); $envelope = $builder->getEnvelope(); - $this->assertEquals('some title', $envelope->getTitle()); + $this->assertSame('some title', $envelope->getTitle()); } - /** - * @return void - */ - public function testNotificationOptions() + public function testNotificationOptions(): void { $builder = $this->getNotificationBuilder(); - $builder->options(array('timeout' => 2000)); + $builder->options(['timeout' => 2000]); $envelope = $builder->getEnvelope(); - $this->assertEquals(array('timeout' => 2000), $envelope->getOptions()); + $this->assertSame(['timeout' => 2000], $envelope->getOptions()); } - /** - * @return void - */ - public function testNotificationOption() + public function testNotificationOption(): void { $builder = $this->getNotificationBuilder(); $builder->option('timeout', 2000); $envelope = $builder->getEnvelope(); - $this->assertEquals(2000, $envelope->getOption('timeout')); + $this->assertSame(2000, $envelope->getOption('timeout')); } - /** - * @return void - */ - public function testSuccessType() + public function testSuccessType(): void { $builder = $this->getNotificationBuilder(); - $builder->success(); + $builder->type('success'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::SUCCESS, $envelope->getType()); + $this->assertSame(Type::SUCCESS, $envelope->getType()); } - /** - * @return void - */ - public function testErrorType() + public function testErrorType(): void { $builder = $this->getNotificationBuilder(); - $builder->error(); + $builder->type('error'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::ERROR, $envelope->getType()); + $this->assertSame(Type::ERROR, $envelope->getType()); } - /** - * @return void - */ - public function testInfoType() + public function testInfoType(): void { $builder = $this->getNotificationBuilder(); - $builder->info(); + $builder->type('info'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::INFO, $envelope->getType()); + $this->assertSame(Type::INFO, $envelope->getType()); } - /** - * @return void - */ - public function testWarningType() + public function testWarningType(): void { $builder = $this->getNotificationBuilder(); - $builder->warning(); + $builder->type('warning'); $envelope = $builder->getEnvelope(); - $this->assertEquals(NotificationInterface::WARNING, $envelope->getType()); + $this->assertSame(Type::WARNING, $envelope->getType()); } - /** - * @return void - */ - public function testWhenCondition() + public function testWhenCondition(): void { $builder = $this->getNotificationBuilder(); $builder->when(true); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\WhenStamp'); + $stamp = $envelope->get(WhenStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\WhenStamp', $stamp); - $this->assertEquals(true, $stamp->getCondition()); + $this->assertInstanceOf(WhenStamp::class, $stamp); + $this->assertTrue($stamp->getCondition()); } - /** - * @return void - */ - public function testUnlessCondition() + public function testUnlessCondition(): void { $builder = $this->getNotificationBuilder(); $builder->unless(true); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\UnlessStamp'); + $stamp = $envelope->get(UnlessStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\UnlessStamp', $stamp); - $this->assertEquals(true, $stamp->getCondition()); + $this->assertInstanceOf(UnlessStamp::class, $stamp); + $this->assertTrue($stamp->getCondition()); } - /** - * @return void - */ - public function testPriority() + public function testPriority(): void { $builder = $this->getNotificationBuilder(); $builder->priority(2); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PriorityStamp'); + $stamp = $envelope->get(PriorityStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PriorityStamp', $stamp); - $this->assertEquals(2, $stamp->getPriority()); + $this->assertInstanceOf(PriorityStamp::class, $stamp); + $this->assertSame(2, $stamp->getPriority()); } - /** - * @return void - */ - public function testHops() + public function testHops(): void { $builder = $this->getNotificationBuilder(); $builder->hops(3); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\HopsStamp'); + $stamp = $envelope->get(HopsStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\HopsStamp', $stamp); - $this->assertEquals(3, $stamp->getAmount()); + $this->assertInstanceOf(HopsStamp::class, $stamp); + $this->assertSame(3, $stamp->getAmount()); } - /** - * @return void - */ - public function testKeep() + public function testKeep(): void { $builder = $this->getNotificationBuilder(); $builder->keep(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\HopsStamp'); + $stamp = $envelope->get(HopsStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\HopsStamp', $stamp); - $this->assertEquals(2, $stamp->getAmount()); + $this->assertInstanceOf(HopsStamp::class, $stamp); + $this->assertSame(2, $stamp->getAmount()); } - /** - * @return void - */ - public function testDelay() + public function testDelay(): void { $builder = $this->getNotificationBuilder(); $builder->delay(3); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\DelayStamp'); + $stamp = $envelope->get(DelayStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\DelayStamp', $stamp); - $this->assertEquals(3, $stamp->getDelay()); + $this->assertInstanceOf(DelayStamp::class, $stamp); + $this->assertSame(3, $stamp->getDelay()); } - /** - * @return void - */ - public function testNow() + public function testTranslate(): void { $builder = $this->getNotificationBuilder(); - $builder->now(); + $builder->translate(['foo' => 'bar'], 'ar'); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\DelayStamp'); + $stamp = $envelope->get(TranslationStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\DelayStamp', $stamp); - $this->assertEquals(0, $stamp->getDelay()); + $this->assertInstanceOf(TranslationStamp::class, $stamp); + $this->assertSame('ar', $stamp->getLocale()); + $this->assertSame(['foo' => 'bar'], $stamp->getParameters()); } - /** - * @return void - */ - public function testTranslate() + public function testAddPreset(): void { - $builder = $this->getNotificationBuilder(); - $builder->translate(array('foo' => 'bar'), 'ar'); - - $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\TranslationStamp'); - - $this->assertInstanceOf('Flasher\Prime\Stamp\TranslationStamp', $stamp); - $this->assertEquals('ar', $stamp->getLocale()); - $this->assertEquals(array('foo' => 'bar'), $stamp->getParameters()); - } - - /** - * @return void - */ - public function testAddPreset() - { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addPreset('entity_saved'); + $builder->preset('entity_saved'); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('entity_saved', $stamp->getPreset()); - $this->assertEquals(array(), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('entity_saved', $stamp->getPreset()); + $this->assertSame([], $stamp->getParameters()); } - /** - * @return void - */ - public function testAddOperation() + public function testAddOperation(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addPreset('saved'); + $builder->preset('saved'); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('saved', $stamp->getPreset()); - $this->assertEquals(array(), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('saved', $stamp->getPreset()); + $this->assertSame([], $stamp->getParameters()); } - /** - * @return void - */ - public function testAddCreated() + public function testAddCreated(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addCreated(); + $builder->created(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('created', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('created', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testAddUpdated() + public function testAddUpdated(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addUpdated(); + $builder->updated(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('updated', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('updated', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testAddSaved() + public function testAddSaved(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addSaved(); + $builder->saved(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('saved', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('saved', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testAddDeleted() + public function testAddDeleted(): void { - $storageManager = $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $this->getMockBuilder(StorageManagerInterface::class)->getMock(); $storageManager->expects($this->once())->method('add'); $builder = $this->getNotificationBuilder($storageManager); - $builder->addDeleted(); + $builder->deleted(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('deleted', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('deleted', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testPreset() + public function testPreset(): void { $builder = $this->getNotificationBuilder(); $builder->preset('entity_saved'); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('entity_saved', $stamp->getPreset()); - $this->assertEquals(array(), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('entity_saved', $stamp->getPreset()); + $this->assertSame([], $stamp->getParameters()); } - /** - * @return void - */ - public function testOperation() + public function testOperation(): void { $builder = $this->getNotificationBuilder(); $builder->operation('someOperation'); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('someOperation', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('someOperation', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testCreated() + public function testCreated(): void { $builder = $this->getNotificationBuilder(); $builder->created(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('created', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('created', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testUpdated() + public function testUpdated(): void { $builder = $this->getNotificationBuilder(); $builder->updated(); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $envelope->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('updated', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('updated', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testSaved() + public function testSaved(): void { $builder = $this->getNotificationBuilder(); $builder->saved(); - $stamp = $builder->getEnvelope()->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $builder->getEnvelope()->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('saved', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('saved', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testDeleted() + public function testDeleted(): void { $builder = $this->getNotificationBuilder(); $builder->deleted(); - $stamp = $builder->getEnvelope()->get('Flasher\Prime\Stamp\PresetStamp'); + $stamp = $builder->getEnvelope()->get(PresetStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresetStamp', $stamp); - $this->assertEquals('deleted', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $this->assertInstanceOf(PresetStamp::class, $stamp); + $this->assertSame('deleted', $stamp->getPreset()); + $this->assertSame(['resource' => 'resource'], $stamp->getParameters()); } - /** - * @return void - */ - public function testWithStamps() + public function testWithStamps(): void { $builder = $this->getNotificationBuilder(); - $stamps = array( + $stamps = [ new PriorityStamp(1), new HopsStamp(0), - ); + ]; $builder->with($stamps); $envelope = $builder->getEnvelope(); $all = $envelope->all(); + array_unshift($stamps, new PluginStamp('flasher')); + $this->assertEquals($stamps, array_values($all)); } - /** - * @return void - */ - public function testWithStamp() + public function testWithStamp(): void { $builder = $this->getNotificationBuilder(); - $stamp = $this->getMockBuilder('Flasher\Prime\Stamp\StampInterface')->getMock(); - $builder->withStamp($stamp); + $stamp = $this->createMock(StampInterface::class); + $builder->with($stamp); $envelope = $builder->getEnvelope(); $stamps = $envelope->all(); @@ -597,66 +481,51 @@ class NotificationBuilderTest extends TestCase $this->assertContains($stamp, $stamps); } - /** - * @return void - */ - public function testHandler() + public function testHandler(): void { $builder = $this->getNotificationBuilder(); $builder->handler('flasher'); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\HandlerStamp'); + $stamp = $envelope->get(PluginStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\HandlerStamp', $stamp); - $this->assertEquals('flasher', $stamp->getHandler()); + $this->assertInstanceOf(PluginStamp::class, $stamp); + $this->assertSame('flasher', $stamp->getPlugin()); } - /** - * @return void - */ - public function testContext() + public function testContext(): void { $builder = $this->getNotificationBuilder(); - $builder->context(array('foo' => 'bar')); + $builder->context(['foo' => 'bar']); $envelope = $builder->getEnvelope(); - $stamp = $envelope->get('Flasher\Prime\Stamp\ContextStamp'); + $stamp = $envelope->get(ContextStamp::class); - $this->assertInstanceOf('Flasher\Prime\Stamp\ContextStamp', $stamp); - $this->assertEquals(array('foo' => 'bar'), $stamp->getContext()); + $this->assertInstanceOf(ContextStamp::class, $stamp); + $this->assertSame(['foo' => 'bar'], $stamp->getContext()); } - /** - * @return void - */ - public function testMacro() + public function testMacro(): void { - if (version_compare(PHP_VERSION, '5.4', '<')) { - $this->markTestSkipped('Not working for PHP 5.3'); - } - - NotificationBuilder::macro('foo', function () { - return 'Called from a macro'; - }); + NotificationBuilder::macro('foo', fn (): string => 'Called from a macro'); $builder = $this->getNotificationBuilder(); - $response = $builder->foo(); + $response = $builder->foo(); // @phpstan-ignore-line $this->assertTrue(NotificationBuilder::hasMacro('foo')); - $this->assertEquals('Called from a macro', $response); + $this->assertSame('Called from a macro', $response); } /** * @phpstan-param MockObject|StorageManagerInterface $storageManager * - * @return NotificationBuilderInterface + * @phpstan-ignore-next-line */ - private function getNotificationBuilder(StorageManagerInterface $storageManager = null) + private function getNotificationBuilder(?StorageManagerInterface $storageManager = null): NotificationBuilderInterface { /** @var StorageManagerInterface $storageManager */ - $storageManager = $storageManager ?: $this->getMockBuilder('Flasher\Prime\Storage\StorageManagerInterface')->getMock(); + $storageManager = $storageManager ?: $this->createMock(StorageManagerInterface::class); - return new NotificationBuilder($storageManager, new Notification()); + return new NotificationBuilder(new Notification(), $storageManager); } } diff --git a/tests/Prime/Notification/NotificationTest.php b/tests/Prime/Notification/NotificationTest.php index 396a05f2..4e24bb2e 100644 --- a/tests/Prime/Notification/NotificationTest.php +++ b/tests/Prime/Notification/NotificationTest.php @@ -1,77 +1,59 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Notification; use Flasher\Prime\Notification\Notification; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class NotificationTest extends TestCase +final class NotificationTest extends TestCase { - /** - * @return void - */ - public function testType() + public function testType(): void { $notification = new Notification(); - $this->assertNull($notification->getType()); + $this->assertSame('', $notification->getType()); $notification->setType('success'); - $this->assertEquals('success', $notification->getType()); + $this->assertSame('success', $notification->getType()); } - /** - * @return void - */ - public function testMessage() + public function testMessage(): void { $notification = new Notification(); - $this->assertNull($notification->getMessage()); + $this->assertSame('', $notification->getMessage()); $notification->setMessage('success message'); - $this->assertEquals('success message', $notification->getMessage()); + $this->assertSame('success message', $notification->getMessage()); } - /** - * @return void - */ - public function testTitle() + public function testTitle(): void { $notification = new Notification(); - $this->assertNull($notification->getTitle()); + $this->assertSame('', $notification->getTitle()); $notification->setTitle('success title'); - $this->assertEquals('success title', $notification->getTitle()); + $this->assertSame('success title', $notification->getTitle()); } - /** - * @return void - */ - public function testOptions() + public function testOptions(): void { $notification = new Notification(); - $this->assertEquals(array(), $notification->getOptions()); + $this->assertSame([], $notification->getOptions()); - $notification->setOptions(array('timeout' => 2500)); + $notification->setOptions(['timeout' => 2500]); - $this->assertEquals(array('timeout' => 2500), $notification->getOptions()); + $this->assertSame(['timeout' => 2500], $notification->getOptions()); } - /** - * @return void - */ - public function testOption() + public function testOption(): void { $notification = new Notification(); @@ -79,40 +61,34 @@ class NotificationTest extends TestCase $notification->setOption('timeout', 2500); - $this->assertEquals(2500, $notification->getOption('timeout')); + $this->assertSame(2500, $notification->getOption('timeout')); } - /** - * @return void - */ - public function testUnsetOption() + public function testUnsetOption(): void { $notification = new Notification(); - $notification->setOptions(array('timeout' => 2500, 'position' => 'center')); + $notification->setOptions(['timeout' => 2500, 'position' => 'center']); - $this->assertEquals(array('timeout' => 2500, 'position' => 'center'), $notification->getOptions()); + $this->assertSame(['timeout' => 2500, 'position' => 'center'], $notification->getOptions()); $notification->unsetOption('timeout'); - $this->assertEquals(array('position' => 'center'), $notification->getOptions()); + $this->assertSame(['position' => 'center'], $notification->getOptions()); } - /** - * @return void - */ - public function testToArray() + public function testToArray(): void { $notification = new Notification(); $notification->setType('success'); $notification->setTitle('PHPFlasher'); $notification->setMessage('success message'); - $notification->setOptions(array('timeout' => 2500, 'position' => 'center')); + $notification->setOptions(['timeout' => 2500, 'position' => 'center']); - $this->assertEquals(array( - 'type' => 'success', + $this->assertSame([ 'title' => 'PHPFlasher', 'message' => 'success message', - 'options' => array('timeout' => 2500, 'position' => 'center'), - ), $notification->toArray()); + 'type' => 'success', + 'options' => ['timeout' => 2500, 'position' => 'center'], + ], $notification->toArray()); } } diff --git a/tests/Prime/Plugin/FlasherPluginTest.php b/tests/Prime/Plugin/FlasherPluginTest.php index 1e154d4b..2df3833c 100644 --- a/tests/Prime/Plugin/FlasherPluginTest.php +++ b/tests/Prime/Plugin/FlasherPluginTest.php @@ -1,209 +1,96 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Plugin; use Flasher\Prime\Plugin\FlasherPlugin; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class FlasherPluginTest extends TestCase +final class FlasherPluginTest extends TestCase { - /** - * @return void - */ - public function testGetName() + public function testGetName(): void { $plugin = new FlasherPlugin(); - $this->assertEquals('flasher', $plugin->getName()); + $this->assertSame('flasher', $plugin->getName()); } - /** - * @return void - */ - public function testGetServiceID() + public function testGetServiceID(): void { $plugin = new FlasherPlugin(); - $this->assertEquals('flasher', $plugin->getServiceID()); + $this->assertSame('flasher', $plugin->getServiceId()); } - /** - * @return void - */ - public function testGetDefault() + public function testGetDefault(): void { $plugin = new FlasherPlugin(); - $this->assertEquals('flasher', $plugin->getDefault()); + $this->assertSame('flasher', $plugin->getDefault()); } - /** - * @return void - */ - public function testGetRootScript() + public function testGetRootScript(): void { $plugin = new FlasherPlugin(); - $rootScript = array( - 'cdn' => 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.js', - 'local' => '/vendor/flasher/flasher.min.js', - ); + $rootScript = '/vendor/flasher/flasher.min.js'; - $this->assertEquals($rootScript, $plugin->getRootScript()); + $this->assertSame($rootScript, $plugin->getRootScript()); } - /** - * @return void - */ - public function testGetScripts() + public function testGetScripts(): void { $plugin = new FlasherPlugin(); - $scripts = array( - 'cdn' => array('https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.js'), - 'local' => array('/vendor/flasher/flasher.min.js'), - ); - $this->assertEquals($scripts, $plugin->getScripts()); + $this->assertSame([], $plugin->getScripts()); } - /** - * @return void - */ - public function testGetResourcesDir() + public function testProcessConfiguration(): void { $plugin = new FlasherPlugin(); - $resourceDir = realpath(__DIR__.'/../../../src/Prime/Resources'); - - $this->assertEquals($resourceDir, $plugin->getResourcesDir()); - } - - /** - * @return void - */ - public function testGetFlashBagMapping() - { - $plugin = new FlasherPlugin(); - $mapping = array( - 'success' => array('success'), - 'error' => array('error', 'danger'), - 'warning' => array('warning', 'alarm'), - 'info' => array('info', 'notice', 'alert'), - ); - - $this->assertEquals($mapping, $plugin->getFlashBagMapping()); - } - - /** - * @return void - */ - public function testProcessConfiguration() - { - $plugin = new FlasherPlugin(); - $config = array( + $config = [ 'default' => 'flasher', - 'root_script' => array( - 'cdn' => 'https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.js', - 'local' => '/vendor/flasher/flasher.min.js', - ), - 'scripts' => array(), - 'styles' => array( - 'cdn' => array('https://cdn.jsdelivr.net/npm/@flasher/flasher@1.3.2/dist/flasher.min.css'), - 'local' => array('/vendor/flasher/flasher.min.css'), - ), - 'options' => array(), - 'use_cdn' => true, - 'auto_translate' => true, - 'auto_render' => true, - 'flash_bag' => array( - 'enabled' => true, - 'mapping' => array( - 'success' => array('success'), - 'error' => array('error', 'danger'), - 'warning' => array('warning', 'alarm'), - 'info' => array('info', 'notice', 'alert'), - ), - ), - 'filter_criteria' => array(), - 'presets' => array( - 'created' => array( + 'main_script' => '/vendor/flasher/flasher.min.js', + 'scripts' => [], + 'styles' => ['/vendor/flasher/flasher.min.css'], + 'options' => [], + 'translate' => true, + 'inject_assets' => true, + 'flash_bag' => [ + 'success' => ['success'], + 'error' => ['error', 'danger'], + 'warning' => ['warning', 'alarm'], + 'info' => ['info', 'notice', 'alert'], + ], + 'presets' => [ + 'created' => [ 'type' => 'success', 'message' => 'The resource was created', - ), - 'updated' => array( + 'options' => [], + ], + 'updated' => [ 'type' => 'success', 'message' => 'The resource was updated', - ), - 'saved' => array( + 'options' => [], + ], + 'saved' => [ 'type' => 'success', 'message' => 'The resource was saved', - ), - 'deleted' => array( + 'options' => [], + ], + 'deleted' => [ 'type' => 'success', 'message' => 'The resource was deleted', - ), - ), - ); + 'options' => [], + ], + ], + 'plugins' => [ + 'flasher' => [ + 'scripts' => [], + 'styles' => ['/vendor/flasher/flasher.min.css'], + 'options' => [], + ], + ], + 'filter' => [], + ]; - $this->assertEquals($config, $plugin->processConfiguration()); - } - - /** - * @return void - */ - public function testNormalizeConfig() - { - $plugin = new FlasherPlugin(); - - $inputConfig = array( - 'template_factory' => array( - 'default' => 'flasher', - 'templates' => array( - 'flasher' => array( - 'options' => array(), - 'styles' => array(), - ), - ), - ), - 'auto_create_from_session' => true, - 'types_mapping' => array(), - 'observer_events' => array(), - 'translate_by_default' => true, - 'flash_bag' => array(), - ); - - $outputConfig = array( - 'options' => array(), - 'themes' => array( - 'flasher' => array( - 'styles' => array(), - ), - ), - 'flash_bag' => array( - 'enabled' => true, - 'mapping' => array(), - ), - 'auto_translate' => true, - 'presets' => array( - 'created' => array( - 'type' => 'success', - 'message' => 'The resource was created', - ), - 'updated' => array( - 'type' => 'success', - 'message' => 'The resource was updated', - ), - 'saved' => array( - 'type' => 'success', - 'message' => 'The resource was saved', - ), - 'deleted' => array( - 'type' => 'success', - 'message' => 'The resource was deleted', - ), - ), - ); - - $this->assertEquals($outputConfig, $plugin->normalizeConfig($inputConfig)); + $this->assertEquals($config, $plugin->normalizeConfig()); } } diff --git a/tests/Prime/Response/Presenter/ArrayPresenterTest.php b/tests/Prime/Response/Presenter/ArrayPresenterTest.php index 7159f16a..8afae7a7 100644 --- a/tests/Prime/Response/Presenter/ArrayPresenterTest.php +++ b/tests/Prime/Response/Presenter/ArrayPresenterTest.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Response\Presenter; @@ -11,16 +8,13 @@ use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Response\Presenter\ArrayPresenter; use Flasher\Prime\Response\Response; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class ArrayPresenterTest extends TestCase +final class ArrayPresenterTest extends TestCase { - /** - * @return void - */ - public function testArrayPresenter() + public function testArrayPresenter(): void { - $envelopes = array(); + $envelopes = []; $notification = new Notification(); $notification->setMessage('success message'); @@ -34,32 +28,31 @@ class ArrayPresenterTest extends TestCase $notification->setType('warning'); $envelopes[] = new Envelope($notification); - $response = array( - 'envelopes' => array( - array( - 'notification' => array( - 'type' => 'success', - 'title' => 'PHPFlasher', - 'message' => 'success message', - 'options' => array(), - ), - ), - array( - 'notification' => array( - 'type' => 'warning', - 'title' => 'yoeunes/toastr', - 'message' => 'warning message', - 'options' => array(), - ), - ), - ), - 'scripts' => array(), - 'styles' => array(), - 'options' => array(), - ); + $response = [ + 'envelopes' => [ + [ + 'title' => 'PHPFlasher', + 'message' => 'success message', + 'type' => 'success', + 'options' => [], + 'metadata' => [], + ], + [ + 'title' => 'yoeunes/toastr', + 'message' => 'warning message', + 'type' => 'warning', + 'options' => [], + 'metadata' => [], + ], + ], + 'scripts' => [], + 'styles' => [], + 'options' => [], + 'context' => [], + ]; $presenter = new ArrayPresenter(); - $this->assertEquals($response, $presenter->render(new Response($envelopes, array()))); + $this->assertSame($response, $presenter->render(new Response($envelopes, []))); } } diff --git a/tests/Prime/Response/Presenter/HtmlPresenterTest.php b/tests/Prime/Response/Presenter/HtmlPresenterTest.php index 4a8ad0fd..1e6c64fe 100644 --- a/tests/Prime/Response/Presenter/HtmlPresenterTest.php +++ b/tests/Prime/Response/Presenter/HtmlPresenterTest.php @@ -1,9 +1,6 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Response\Presenter; @@ -11,16 +8,14 @@ use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Response\Presenter\HtmlPresenter; use Flasher\Prime\Response\Response; -use Flasher\Tests\Prime\TestCase; +use Livewire\LivewireManager; +use PHPUnit\Framework\TestCase; -class HtmlPresenterTest extends TestCase +final class HtmlPresenterTest extends TestCase { - /** - * @return void - */ - public function testArrayPresenter() + public function testArrayPresenter(): void { - $envelopes = array(); + $envelopes = []; $notification = new Notification(); $notification->setMessage('success message'); @@ -34,93 +29,100 @@ class HtmlPresenterTest extends TestCase $notification->setType('warning'); $envelopes[] = new Envelope($notification); + $scriptTagWithNonce = ''; $livewireListener = $this->getLivewireListenerScript(); $response = << -(function() { - var rootScript = ''; - var FLASHER_FLASH_BAG_PLACE_HOLDER = {}; - var options = mergeOptions({"envelopes":[{"notification":{"type":"success","message":"success message","title":"PHPFlasher","options":[]}},{"notification":{"type":"warning","message":"warning message","title":"yoeunes\/toastr","options":[]}}]}, FLASHER_FLASH_BAG_PLACE_HOLDER); + -JAVASCRIPT; + document.head.appendChild(tag); + } + }; + + const addRenderListener = () => { + if (1 === document.querySelectorAll('script.flasher-js').length) { + document.addEventListener('flasher:render', render); + } + + {$livewireListener} + }; + + const options = []; + options.push({"envelopes":[{"title":"PHPFlasher","message":"success message","type":"success","options":[],"metadata":[]},{"title":"yoeunes\/toastr","message":"warning message","type":"warning","options":[],"metadata":[]}],"scripts":[],"styles":[],"options":[],"context":[]}); + /** {--FLASHER_REPLACE_ME--} **/ + addScriptAndRender(mergeOptions(...options)); + addRenderListener(); + })(window, document); + + JAVASCRIPT; $presenter = new HtmlPresenter(); - $this->assertEquals($response, $presenter->render(new Response($envelopes, array()))); + $this->assertSame($response, $presenter->render(new Response($envelopes, []))); } - /** - * @return void - */ - public function testItRenderOnlyEnvelopesAsJsonObject() + public function testItRenderOnlyEnvelopesAsJsonObject(): void { - $envelopes = array(); + $envelopes = []; $notification = new Notification(); $notification->setMessage('success message'); @@ -134,31 +136,26 @@ JAVASCRIPT; $notification->setType('warning'); $envelopes[] = new Envelope($notification); - $response = '{"envelopes":[{"notification":{"type":"success","message":"success message","title":"PHPFlasher","options":[]}},{"notification":{"type":"warning","message":"warning message","title":"yoeunes\/toastr","options":[]}}]}'; + $response = '{"envelopes":[{"title":"PHPFlasher","message":"success message","type":"success","options":[],"metadata":[]},{"title":"yoeunes\/toastr","message":"warning message","type":"warning","options":[],"metadata":[]}],"scripts":[],"styles":[],"options":[],"context":{"envelopes_only":true}}'; $presenter = new HtmlPresenter(); - $this->assertEquals($response, $presenter->render(new Response($envelopes, array('envelopes_only' => true)))); + $this->assertSame($response, $presenter->render(new Response($envelopes, ['envelopes_only' => true]))); } /** * Generate the script for Livewire event handling. - * - * @return string */ - private function getLivewireListenerScript() + private function getLivewireListenerScript(): string { - if (!class_exists('Livewire\LivewireManager')) { + if (!class_exists(LivewireManager::class)) { return ''; } return << { + document.querySelectorAll('.fl-no-cache').forEach(el => el.remove()); + }); + JAVASCRIPT; } } diff --git a/tests/Prime/Response/Resource/ResourceManagerTest.php b/tests/Prime/Response/Resource/ResourceManagerTest.php index bb4ebdab..81cfbdb3 100644 --- a/tests/Prime/Response/Resource/ResourceManagerTest.php +++ b/tests/Prime/Response/Resource/ResourceManagerTest.php @@ -1,77 +1,76 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Response\Resource; -use Flasher\Prime\Config\Config; +use Flasher\Prime\Asset\AssetManagerInterface; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Response\Resource\ResourceManager; use Flasher\Prime\Response\Response; use Flasher\Prime\Stamp\CreatedAtStamp; -use Flasher\Prime\Stamp\HandlerStamp; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\IdStamp; +use Flasher\Prime\Stamp\PluginStamp; +use Flasher\Prime\Template\TemplateEngineInterface; +use PHPUnit\Framework\TestCase; -class ResourceManagerTest extends TestCase +final class ResourceManagerTest extends TestCase { - /** - * @return void - */ - public function testItPopulateResponseFromResources() + public function testItPopulateResponseFromResources(): void { - $config = new Config(array( - 'default' => 'flasher', - 'root_script' => 'root_script.min.js', - )); - $resourceManager = new ResourceManager($config); + $templateEngine = $this->createMock(TemplateEngineInterface::class); - $resourceManager->addScripts('flasher', array('flasher.min.js')); - $resourceManager->addStyles('flasher', array('flasher.min.css')); - $resourceManager->addOptions('flasher', array('timeout' => 2500, 'position' => 'center')); + $assetManager = $this->createMock(AssetManagerInterface::class); + $assetManager->method('getPath')->willReturnArgument(0); + $assetManager->method('getPaths')->willReturnArgument(0); - $resourceManager->addScripts('toastr', array('toastr.min.js', 'jquery.min.js')); - $resourceManager->addStyles('toastr', array('toastr.min.css')); - $resourceManager->addOptions('toastr', array('sounds' => false)); + $resourceManager = new ResourceManager($templateEngine, $assetManager, 'main_script.min.js', [ + 'flasher' => [ + 'scripts' => ['flasher.min.js'], + 'styles' => ['flasher.min.css'], + 'options' => ['timeout' => 2500, 'position' => 'center'], + ], + 'toastr' => [ + 'scripts' => ['toastr.min.js', 'jquery.min.js'], + 'styles' => ['toastr.min.css'], + 'options' => ['sounds' => false], + ], + ]); - $envelopes = array(); + $envelopes = []; $notification = new Notification(); $notification->setMessage('success message'); $notification->setTitle('PHPFlasher'); $notification->setType('success'); - $envelopes[] = new Envelope($notification, array( - new HandlerStamp('flasher'), - new CreatedAtStamp(new \DateTime('2023-02-05 16:22:50')), - new UuidStamp('1111'), - )); + $envelopes[] = new Envelope($notification, [ + new PluginStamp('flasher'), + new CreatedAtStamp(new \DateTimeImmutable('2023-02-05 16:22:50')), + new IdStamp('1111'), + ]); $notification = new Notification(); $notification->setMessage('warning message'); $notification->setTitle('yoeunes/toastr'); $notification->setType('warning'); - $envelopes[] = new Envelope($notification, array( - new HandlerStamp('toastr'), - new CreatedAtStamp(new \DateTime('2023-02-05 16:22:50')), - new UuidStamp('2222'), - )); + $envelopes[] = new Envelope($notification, [ + new PluginStamp('toastr'), + new CreatedAtStamp(new \DateTimeImmutable('2023-02-05 16:22:50')), + new IdStamp('2222'), + ]); - $response = new Response($envelopes, array()); + $response = new Response($envelopes, []); - $response = $resourceManager->buildResponse($response); + $response = $resourceManager->populateResponse($response); $this->assertEquals($envelopes, $response->getEnvelopes()); - $this->assertEquals('root_script.min.js', $response->getRootScript()); - $this->assertEquals(array('flasher.min.js', 'toastr.min.js', 'jquery.min.js'), $response->getScripts()); - $this->assertEquals(array('flasher.min.css', 'toastr.min.css'), $response->getStyles()); - $this->assertEquals(array( - 'theme.flasher' => array('timeout' => 2500, 'position' => 'center'), - 'toastr' => array('sounds' => false), - ), $response->getOptions()); - $this->assertEquals($config, $resourceManager->getConfig()); + $this->assertSame('main_script.min.js', $response->getMainScript()); + $this->assertSame(['flasher.min.js', 'toastr.min.js', 'jquery.min.js'], $response->getScripts()); + $this->assertSame(['flasher.min.css', 'toastr.min.css'], $response->getStyles()); + $this->assertEquals([ + 'toastr' => ['sounds' => false], + 'flasher' => ['timeout' => 2500, 'position' => 'center'], + ], $response->getOptions()); } } diff --git a/tests/Prime/Response/ResponseManagerTest.php b/tests/Prime/Response/ResponseManagerTest.php index 910198bd..7fcaf900 100644 --- a/tests/Prime/Response/ResponseManagerTest.php +++ b/tests/Prime/Response/ResponseManagerTest.php @@ -1,159 +1,169 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Response; +use Flasher\Prime\EventDispatcher\EventDispatcherInterface; +use Flasher\Prime\Exception\PresenterNotFoundException; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; +use Flasher\Prime\Response\Resource\ResourceManagerInterface; use Flasher\Prime\Response\ResponseManager; use Flasher\Prime\Stamp\CreatedAtStamp; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Prime\Storage\StorageManager; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\IdStamp; +use Flasher\Prime\Storage\StorageManagerInterface; +use Livewire\LivewireManager; +use PHPUnit\Framework\TestCase; -class ResponseManagerTest extends TestCase +final class ResponseManagerTest extends TestCase { - /** - * @return void - */ - public function testRenderSavedNotifications() + public function testRenderSavedNotifications(): void { - $envelopes = array(); + $envelopes = []; $notification = new Notification(); $notification->setMessage('success message'); $notification->setTitle('PHPFlasher'); $notification->setType('success'); - $envelopes[] = new Envelope($notification, array( - new CreatedAtStamp(new \DateTime('2023-02-05 16:22:50')), - new UuidStamp('1111'), - )); + $envelopes[] = new Envelope($notification, [ + new CreatedAtStamp(new \DateTimeImmutable('2023-02-05 16:22:50')), + new IdStamp('1111'), + ]); $notification = new Notification(); $notification->setMessage('warning message'); $notification->setTitle('yoeunes/toastr'); $notification->setType('warning'); - $envelopes[] = new Envelope($notification, array( - new CreatedAtStamp(new \DateTime('2023-02-06 16:22:50')), - new UuidStamp('2222'), - )); + $envelopes[] = new Envelope($notification, [ + new CreatedAtStamp(new \DateTimeImmutable('2023-02-06 16:22:50')), + new IdStamp('2222'), + ]); - $storageManager = new StorageManager(); - $storageManager->add($envelopes); + $resourceManager = $this->createMock(ResourceManagerInterface::class); + $resourceManager->method('populateResponse')->willReturnArgument(0); - $responseManager = new ResponseManager(null, $storageManager); + $storageManager = $this->createMock(StorageManagerInterface::class); + $eventDispatcher = $this->createMock(EventDispatcherInterface::class); + + $responseManager = new ResponseManager($resourceManager, $storageManager, $eventDispatcher); + $scriptTagWithNonce = ''; $livewireListener = $this->getLivewireListenerScript(); $response = << -(function() { - var rootScript = ''; - var FLASHER_FLASH_BAG_PLACE_HOLDER = {}; - var options = mergeOptions({"envelopes":[{"notification":{"type":"success","message":"success message","title":"PHPFlasher","options":[]},"created_at":"2023-02-05 16:22:50","uuid":"1111","priority":0},{"notification":{"type":"warning","message":"warning message","title":"yoeunes\/toastr","options":[]},"created_at":"2023-02-06 16:22:50","uuid":"2222","priority":0}]}, FLASHER_FLASH_BAG_PLACE_HOLDER); + + JAVASCRIPT; + + $this->assertSame($response, $responseManager->render('html')); } - function merge(first, second) { - if (Array.isArray(first) && Array.isArray(second)) { - return first.concat(second).filter(function(item, index, array) { - return array.indexOf(item) === index; - }); - } - - return Object.assign({}, first, second); - } - - function renderOptions(options) { - if(!window.hasOwnProperty('flasher')) { - console.error('Flasher is not loaded'); - return; - } - - requestAnimationFrame(function () { - window.flasher.render(options); - }); - } - - function render(options) { - if ('loading' !== document.readyState) { - renderOptions(options); - - return; - } - - document.addEventListener('DOMContentLoaded', function() { - renderOptions(options); - }); - } - - if (1 === document.querySelectorAll('script.flasher-js').length) { - document.addEventListener('flasher:render', function (event) { - render(event.detail); - }); - - {$livewireListener} - } - - if (window.hasOwnProperty('flasher') || !rootScript || document.querySelector('script[src="' + rootScript + '"]')) { - render(options); - } else { - var tag = document.createElement('script'); - tag.setAttribute('src', rootScript); - tag.setAttribute('type', 'text/javascript'); - tag.onload = function () { - render(options); - }; - - document.head.appendChild(tag); - } -})(); - -JAVASCRIPT; - - $this->assertEquals($response, $responseManager->render()); - } - - /** - * @return void - */ - public function testItThrowsExceptionIfPresenterNotFound() + public function testItThrowsExceptionIfPresenterNotFound(): void { - $this->setExpectedException('\InvalidArgumentException', 'Presenter [xml] not supported.'); + $this->expectException(PresenterNotFoundException::class); + $this->expectExceptionMessage('Presenter "xml" not found, did you forget to register it? Available presenters: [html, json, array]'); - $responseManager = new ResponseManager(); - $responseManager->render(array(), 'xml'); + $resourceManager = $this->createMock(ResourceManagerInterface::class); + $resourceManager->method('populateResponse')->willReturnArgument(0); + + $storageManager = $this->createMock(StorageManagerInterface::class); + $eventDispatcher = $this->createMock(EventDispatcherInterface::class); + + $responseManager = new ResponseManager($resourceManager, $storageManager, $eventDispatcher); + $responseManager->render('xml'); } /** * Generate the script for Livewire event handling. - * - * @return string */ - private function getLivewireListenerScript() + private function getLivewireListenerScript(): string { - if (!class_exists('Livewire\LivewireManager')) { + if (!class_exists(LivewireManager::class)) { return ''; } return << { + document.querySelectorAll('.fl-no-cache').forEach(el => el.remove()); + }); + JAVASCRIPT; } } diff --git a/tests/Prime/Response/ResponseTest.php b/tests/Prime/Response/ResponseTest.php index 2bcf17d0..c79d11ec 100644 --- a/tests/Prime/Response/ResponseTest.php +++ b/tests/Prime/Response/ResponseTest.php @@ -1,79 +1,61 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Response; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Response\Response; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class ResponseTest extends TestCase +final class ResponseTest extends TestCase { - /** - * @return void - */ - public function testAddRootScriptToResponse() + public function testAddRootScriptToResponse(): void { - $response = new Response(array(), array()); + $response = new Response([], []); - $response->setRootScript('flasher.min.js'); + $response->setMainScript('flasher.min.js'); - $this->assertEquals('flasher.min.js', $response->getRootScript()); + $this->assertSame('flasher.min.js', $response->getMainScript()); } - /** - * @return void - */ - public function testItAddsScriptToResponse() + public function testItAddsScriptToResponse(): void { - $response = new Response(array(), array()); + $response = new Response([], []); - $response->addScripts(array('flasher.min.js', 'toastr.min.js')); - $response->addScripts(array('flasher.min.js', 'noty.min.js')); + $response->addScripts(['flasher.min.js', 'toastr.min.js']); + $response->addScripts(['flasher.min.js', 'noty.min.js']); - $this->assertEquals(array('flasher.min.js', 'toastr.min.js', 'noty.min.js'), $response->getScripts()); + $this->assertSame(['flasher.min.js', 'toastr.min.js', 'noty.min.js'], $response->getScripts()); } - /** - * @return void - */ - public function testItAddsStylesToResponse() + public function testItAddsStylesToResponse(): void { - $response = new Response(array(), array()); + $response = new Response([], []); - $response->addStyles(array('flasher.min.css', 'toastr.min.css')); - $response->addStyles(array('flasher.min.css', 'noty.min.css')); + $response->addStyles(['flasher.min.css', 'toastr.min.css']); + $response->addStyles(['flasher.min.css', 'noty.min.css']); - $this->assertEquals(array('flasher.min.css', 'toastr.min.css', 'noty.min.css'), $response->getStyles()); + $this->assertSame(['flasher.min.css', 'toastr.min.css', 'noty.min.css'], $response->getStyles()); } - /** - * @return void - */ - public function testItAddsAdaptersOptionsToResponse() + public function testItAddsAdaptersOptionsToResponse(): void { - $response = new Response(array(), array()); + $response = new Response([], []); - $response->addOptions('flasher', array('position' => 'center', 'timeout' => 2500)); - $response->addOptions('toastr', array('sounds' => false)); + $response->addOptions('flasher', ['position' => 'center', 'timeout' => 2500]); + $response->addOptions('toastr', ['sounds' => false]); - $this->assertEquals(array( - 'flasher' => array('position' => 'center', 'timeout' => 2500), - 'toastr' => array('sounds' => false), - ), $response->getOptions()); + $this->assertEquals([ + 'flasher' => ['position' => 'center', 'timeout' => 2500], + 'toastr' => ['sounds' => false], + ], $response->getOptions()); } - /** - * @return void - */ - public function testItTurnsTheResponseIntoAnArray() + public function testItTurnsTheResponseIntoAnArray(): void { - $envelopes = array(); + $envelopes = []; $notification = new Notification(); $notification->setMessage('success message'); @@ -87,39 +69,38 @@ class ResponseTest extends TestCase $notification->setType('warning'); $envelopes[] = new Envelope($notification); - $response = new Response($envelopes, array()); - $response->setRootScript('flasher.min.js'); - $response->addScripts(array('noty.min.js', 'toastr.min.js')); - $response->addStyles(array('noty.min.css', 'toastr.min.css')); - $response->addOptions('flasher', array('position' => 'center', 'timeout' => 2500)); - $response->addOptions('toastr', array('sounds' => false)); + $response = new Response($envelopes, []); + $response->setMainScript('flasher.min.js'); + $response->addScripts(['noty.min.js', 'toastr.min.js']); + $response->addStyles(['noty.min.css', 'toastr.min.css']); + $response->addOptions('flasher', ['position' => 'center', 'timeout' => 2500]); + $response->addOptions('toastr', ['sounds' => false]); - $expected = array( - 'envelopes' => array( - array( - 'notification' => array( - 'type' => 'success', - 'title' => 'PHPFlasher', - 'message' => 'success message', - 'options' => array(), - ), - ), - array( - 'notification' => array( - 'type' => 'warning', - 'title' => 'yoeunes/toastr', - 'message' => 'warning message', - 'options' => array(), - ), - ), - ), - 'scripts' => array('noty.min.js', 'toastr.min.js'), - 'styles' => array('noty.min.css', 'toastr.min.css'), - 'options' => array( - 'flasher' => array('position' => 'center', 'timeout' => 2500), - 'toastr' => array('sounds' => false), - ), - ); + $expected = [ + 'envelopes' => [ + [ + 'type' => 'success', + 'title' => 'PHPFlasher', + 'message' => 'success message', + 'options' => [], + 'metadata' => [], + ], + [ + 'type' => 'warning', + 'title' => 'yoeunes/toastr', + 'message' => 'warning message', + 'options' => [], + 'metadata' => [], + ], + ], + 'scripts' => ['noty.min.js', 'toastr.min.js'], + 'styles' => ['noty.min.css', 'toastr.min.css'], + 'options' => [ + 'flasher' => ['position' => 'center', 'timeout' => 2500], + 'toastr' => ['sounds' => false], + ], + 'context' => [], + ]; $this->assertEquals($expected, $response->toArray()); } diff --git a/tests/Prime/Stamp/ContextStampTest.php b/tests/Prime/Stamp/ContextStampTest.php index 3b3dc893..a35afdab 100644 --- a/tests/Prime/Stamp/ContextStampTest.php +++ b/tests/Prime/Stamp/ContextStampTest.php @@ -1,27 +1,63 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\ContextStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class ContextStampTest extends TestCase +final class ContextStampTest extends TestCase { - /** - * @return void - */ - public function testContextStamp() + public function testGetContextReturnsTheCorrectArray(): void { - $stamp = new ContextStamp(array('component' => 'livewire')); + $contextArray = ['key1' => 'value1', 'key2' => 'value2']; - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresentableStampInterface', $stamp); - $this->assertEquals(array('component' => 'livewire'), $stamp->getContext()); - $this->assertEquals(array('context' => array('component' => 'livewire')), $stamp->toArray()); + $contextStamp = new ContextStamp($contextArray); + + $this->assertSame( + $contextArray, + $contextStamp->getContext(), + 'The getContext method did not return the expected array.' + ); + } + + public function testGetContextWithEmptyArray(): void + { + $contextArray = []; + + $contextStamp = new ContextStamp($contextArray); + + $this->assertSame( + $contextArray, + $contextStamp->getContext(), + 'The getContext method did not return an empty array with empty context.' + ); + } + + public function testToArrayReturnsContextInArray(): void + { + $contextArray = ['key1' => 'value1', 'key2' => 'value2']; + + $contextStamp = new ContextStamp($contextArray); + + $this->assertSame( + ['context' => $contextArray], + $contextStamp->toArray(), + 'The toArray method did not return the expected array.' + ); + } + + public function testToArrayWithEmptyArray(): void + { + $contextArray = []; + + $contextStamp = new ContextStamp($contextArray); + + $this->assertSame( + ['context' => $contextArray], + $contextStamp->toArray(), + 'The toArray method did not return an array with empty context as expected.' + ); } } diff --git a/tests/Prime/Stamp/CreatedAtStampTest.php b/tests/Prime/Stamp/CreatedAtStampTest.php index 6fb05ac1..3fd35c50 100644 --- a/tests/Prime/Stamp/CreatedAtStampTest.php +++ b/tests/Prime/Stamp/CreatedAtStampTest.php @@ -1,43 +1,74 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\CreatedAtStamp; -use Flasher\Prime\Stamp\HopsStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; final class CreatedAtStampTest extends TestCase { - /** - * @return void - */ - public function testCreatedAtStamp() - { - $createdAt = new \DateTime('2023-01-30 23:33:51'); - $stamp = new CreatedAtStamp($createdAt, 'Y-m-d H:i:s'); + private \DateTimeImmutable $time; - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresentableStampInterface', $stamp); - $this->assertInstanceOf('Flasher\Prime\Stamp\OrderableStampInterface', $stamp); - $this->assertInstanceOf('DateTime', $stamp->getCreatedAt()); - $this->assertEquals('2023-01-30 23:33:51', $stamp->getCreatedAt()->format('Y-m-d H:i:s')); - $this->assertEquals(array('created_at' => '2023-01-30 23:33:51'), $stamp->toArray()); + private CreatedAtStamp $createdAtStamp; + + private string $format; + + protected function setUp(): void + { + $this->time = new \DateTimeImmutable('2023-01-01 12:00:00'); + $this->format = 'Y-m-d H:i:s'; + $this->createdAtStamp = new CreatedAtStamp($this->time, $this->format); } /** - * @return void + * Test getCreatedAt method to ensure it returns correct DateTimeImmutable object. */ - public function testCompare() + public function testGetCreatedAt(): void { - $createdAt1 = new CreatedAtStamp(new \DateTime('2023-01-30 23:35:49')); - $createdAt2 = new CreatedAtStamp(new \DateTime('2023-01-30 23:36:06')); + $createdAt = $this->createdAtStamp->getCreatedAt(); + $this->assertInstanceOf(\DateTimeImmutable::class, $createdAt); + } - $this->assertEquals(-17, $createdAt1->compare($createdAt2)); - $this->assertEquals(1, $createdAt1->compare(new HopsStamp(1))); + /** + * Test if the format of the datetime object returned by getCreatedAt matches the expected format. + */ + public function testGetCreatedAtFormat(): void + { + $createdAt = $this->createdAtStamp->getCreatedAt(); + $formattedDate = $createdAt->format($this->format); + $expectedDate = $this->time->format($this->format); + $this->assertSame($expectedDate, $formattedDate); + } + + /** + * Test compare method to compare timestamps correctly. + */ + public function testCompare(): void + { + // Testing with a time exactly 1 second later + $laterTime = $this->time->modify('+1 second'); + $laterStamp = new CreatedAtStamp($laterTime, $this->format); + + // Testing with the same time + $sameStamp = new CreatedAtStamp($this->time, $this->format); + + // laterStamp should be "greater" than createdAtStamp + $this->assertSame(-1, $this->createdAtStamp->compare($laterStamp)); + $this->assertSame(1, $laterStamp->compare($this->createdAtStamp)); + + // Comparing with the same time should result in 0 + $this->assertSame(0, $this->createdAtStamp->compare($sameStamp)); + } + + /** + * Test toArray method to return correct array format. + */ + public function testToArray(): void + { + $arrayForm = $this->createdAtStamp->toArray(); + $this->assertArrayHasKey('created_at', $arrayForm); + $this->assertSame($this->time->format($this->format), $arrayForm['created_at']); } } diff --git a/tests/Prime/Stamp/DelayStampTest.php b/tests/Prime/Stamp/DelayStampTest.php index 325f06a0..b64f63a8 100644 --- a/tests/Prime/Stamp/DelayStampTest.php +++ b/tests/Prime/Stamp/DelayStampTest.php @@ -1,25 +1,27 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\DelayStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class DelayStampTest extends TestCase +final class DelayStampTest extends TestCase { - /** - * @return void - */ - public function testDelayStamp() - { - $stamp = new DelayStamp(2); + private int $testDelay; + private DelayStamp $instance; - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertEquals(2, $stamp->getDelay()); + protected function setUp(): void + { + $this->testDelay = 100; + $this->instance = new DelayStamp($this->testDelay); + } + + public function testGetDelay(): void + { + $delay = $this->instance->getDelay(); + + $this->assertSame($this->testDelay, $delay); } } diff --git a/tests/Prime/Stamp/HandlerStampTest.php b/tests/Prime/Stamp/HandlerStampTest.php index 8275e4d5..8401cead 100644 --- a/tests/Prime/Stamp/HandlerStampTest.php +++ b/tests/Prime/Stamp/HandlerStampTest.php @@ -1,27 +1,23 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; -use Flasher\Prime\Stamp\HandlerStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\PluginStamp; +use Flasher\Prime\Stamp\PresentableStampInterface; +use Flasher\Prime\Stamp\StampInterface; +use PHPUnit\Framework\TestCase; final class HandlerStampTest extends TestCase { - /** - * @return void - */ - public function testHandlerStamp() + public function testHandlerStamp(): void { - $stamp = new HandlerStamp('toastr'); + $stamp = new PluginStamp('toastr'); - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresentableStampInterface', $stamp); - $this->assertEquals('toastr', $stamp->getHandler()); - $this->assertEquals(array('handler' => 'toastr'), $stamp->toArray()); + $this->assertInstanceOf(StampInterface::class, $stamp); + $this->assertInstanceOf(PresentableStampInterface::class, $stamp); + $this->assertSame('toastr', $stamp->getPlugin()); + $this->assertSame(['plugin' => 'toastr'], $stamp->toArray()); } } diff --git a/tests/Prime/Stamp/HopsStampTest.php b/tests/Prime/Stamp/HopsStampTest.php index 6e9d3663..5f47e273 100644 --- a/tests/Prime/Stamp/HopsStampTest.php +++ b/tests/Prime/Stamp/HopsStampTest.php @@ -1,25 +1,23 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\HopsStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; final class HopsStampTest extends TestCase { - /** - * @return void + /* + * Test to verify that calling getAmount on a HopsStamp instance + * with a certain initial amount correctly returns that amount. */ - public function testHopsStamp() + public function testGetAmount(): void { - $stamp = new HopsStamp(5); + $initialAmount = 5; + $hopsStamp = new HopsStamp($initialAmount); - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertEquals(5, $stamp->getAmount()); + $this->assertSame($initialAmount, $hopsStamp->getAmount()); } } diff --git a/tests/Prime/Stamp/HtmlStampTest.php b/tests/Prime/Stamp/HtmlStampTest.php new file mode 100644 index 00000000..b507b9ee --- /dev/null +++ b/tests/Prime/Stamp/HtmlStampTest.php @@ -0,0 +1,37 @@ +htmlString = '
      Hello World
      '; + $this->htmlStamp = new HtmlStamp($this->htmlString); + } + + /** + * Testing the getHtml method of the HtmlStamp class. + */ + public function testGetHtml(): void + { + $this->assertSame($this->htmlString, $this->htmlStamp->getHtml()); + } + + /** + * Testing the toArray method of the HtmlStamp class. + */ + public function testToArray(): void + { + $expected = ['html' => $this->htmlString]; + $this->assertSame($expected, $this->htmlStamp->toArray()); + } +} diff --git a/tests/Prime/Stamp/IdStampTest.php b/tests/Prime/Stamp/IdStampTest.php new file mode 100644 index 00000000..b28aeb73 --- /dev/null +++ b/tests/Prime/Stamp/IdStampTest.php @@ -0,0 +1,64 @@ +assertIsString($ifStamp->getId()); + + // Test with known ID + $knownId = 'KnownID123'; + $StampWithKnownId = new IdStamp($knownId); + + $this->assertSame($knownId, $StampWithKnownId->getId()); + } + + /** + * Test `toArray` method. + */ + public function testToArray(): void + { + $ifStamp = new IdStamp(); + $arrayRepresentation = $ifStamp->toArray(); + $this->assertIsArray($arrayRepresentation); + $this->assertArrayHasKey('id', $arrayRepresentation); + $this->assertSame($arrayRepresentation['id'], $ifStamp->getId()); + } + + /** + * Tests `indexById` function. + */ + public function testIndexById(): void + { + $stamp1 = new IdStamp('1111'); + $stamp2 = new IdStamp('2222'); + + $envelope1 = new Envelope(new Notification(), $stamp1); + $envelope2 = new Envelope(new Notification(), $stamp2); + + $map = IdStamp::indexById([$envelope1, $envelope2]); + + $this->assertCount(2, $map); + $this->assertArrayHasKey($stamp1->getId(), $map); + $this->assertSame($envelope1, $map[$stamp1->getId()]); + $this->assertArrayHasKey($stamp2->getId(), $map); + $this->assertSame($envelope2, $map[$stamp2->getId()]); + } +} diff --git a/tests/Prime/Stamp/PluginStampTest.php b/tests/Prime/Stamp/PluginStampTest.php new file mode 100644 index 00000000..069ddf6c --- /dev/null +++ b/tests/Prime/Stamp/PluginStampTest.php @@ -0,0 +1,42 @@ +getPlugin(); + + $this->assertSame($plugin, $result); + } + + /** + * Test that the toArray method in PluginStamp class returns the correct + * array with 'plugin' key that was passed to the class constructor during instantiation. + */ + public function testToArrayMethod(): void + { + $plugin = 'myPlugin'; + $pluginStamp = new PluginStamp($plugin); + + $result = $pluginStamp->toArray(); + + $this->assertIsArray($result); + $this->assertCount(1, $result); + $this->assertArrayHasKey('plugin', $result); + $this->assertSame($plugin, $result['plugin']); + } +} diff --git a/tests/Prime/Stamp/PresenterStampTest.php b/tests/Prime/Stamp/PresenterStampTest.php new file mode 100644 index 00000000..370f7dde --- /dev/null +++ b/tests/Prime/Stamp/PresenterStampTest.php @@ -0,0 +1,27 @@ +assertSame($pattern, $presenterStamp->getPattern()); + } + + // Test for invalid pattern in PresenterStamp class + public function testInvalidPatternThrowsException(): void + { + $this->expectException(\InvalidArgumentException::class); + $invalidPattern = '[invalid-pattern'; + $presenterStamp = new PresenterStamp($invalidPattern); + } +} diff --git a/tests/Prime/Stamp/PresetStampTest.php b/tests/Prime/Stamp/PresetStampTest.php index 8a865d60..3e8526f0 100644 --- a/tests/Prime/Stamp/PresetStampTest.php +++ b/tests/Prime/Stamp/PresetStampTest.php @@ -1,26 +1,41 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\PresetStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class PresetStampTest extends TestCase +final class PresetStampTest extends TestCase { /** - * @return void + * getPreset method test. + * + * This test case focuses on the proper retrieval of the preset value from the PresetStamp class. */ - public function testPresetStamp() + public function testGetPreset(): void { - $stamp = new PresetStamp('entity_saved', array('resource' => 'resource')); + $preset = 'preset_value'; + $parameters = ['parameter1' => 'value1']; - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertEquals('entity_saved', $stamp->getPreset()); - $this->assertEquals(array('resource' => 'resource'), $stamp->getParameters()); + $presetStamp = new PresetStamp($preset, $parameters); + + $this->assertSame($preset, $presetStamp->getPreset()); + } + + /** + * getParameters method test. + * + * This test case focuses on the proper retrieval of parameters from the PresetStamp class. + */ + public function testGetParameters(): void + { + $preset = 'preset_value'; + $parameters = ['parameter1' => 'value1']; + + $presetStamp = new PresetStamp($preset, $parameters); + + $this->assertSame($parameters, $presetStamp->getParameters()); } } diff --git a/tests/Prime/Stamp/PriorityStampTest.php b/tests/Prime/Stamp/PriorityStampTest.php index 67c45cdc..5fd46882 100644 --- a/tests/Prime/Stamp/PriorityStampTest.php +++ b/tests/Prime/Stamp/PriorityStampTest.php @@ -1,41 +1,59 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; -use Flasher\Prime\Stamp\HopsStamp; use Flasher\Prime\Stamp\PriorityStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; final class PriorityStampTest extends TestCase { /** - * @return void + * Test case for getPriority method of PriorityStamp class. */ - public function testPriorityStamp() + public function testGetPriority(): void { - $stamp = new PriorityStamp(5); + // Define test priority + $priority = 10; - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertInstanceOf('Flasher\Prime\Stamp\OrderableStampInterface', $stamp); - $this->assertInstanceOf('Flasher\Prime\Stamp\PresentableStampInterface', $stamp); - $this->assertEquals(5, $stamp->getPriority()); - $this->assertEquals(array('priority' => 5), $stamp->toArray()); + // Instantiate PriorityStamp + $stamp = new PriorityStamp($priority); + + // Check if the result of getPriority is as expected + $this->assertSame($priority, $stamp->getPriority()); } /** - * @return void + * Test case for compare method of PriorityStamp class. */ - public function testCompare() + public function testCompare(): void { - $stamp1 = new PriorityStamp(1); - $stamp2 = new PriorityStamp(2); + // Define test priorities + $priority1 = 10; + $priority2 = 20; - $this->assertEquals(-1, $stamp1->compare($stamp2)); - $this->assertEquals(1, $stamp1->compare(new HopsStamp(1))); + // Instantiate PriorityStamps + $stamp1 = new PriorityStamp($priority1); + $stamp2 = new PriorityStamp($priority2); + + // Check if the result of compare is as expected + $this->assertSame($priority1 - $priority2, $stamp1->compare($stamp2)); + $this->assertSame($priority2 - $priority1, $stamp2->compare($stamp1)); + } + + /** + * Test case for toArray method of PriorityStamp class. + */ + public function testToArray(): void + { + // Define test priority + $priority = 10; + + // Instantiate PriorityStamp + $stamp = new PriorityStamp($priority); + + // Check if the result of toArray is as expected + $this->assertSame(['priority' => $priority], $stamp->toArray()); } } diff --git a/tests/Prime/Stamp/TranslationStampTest.php b/tests/Prime/Stamp/TranslationStampTest.php index d669b198..540fc7b1 100644 --- a/tests/Prime/Stamp/TranslationStampTest.php +++ b/tests/Prime/Stamp/TranslationStampTest.php @@ -1,36 +1,63 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\TranslationStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class TranslationStampTest extends TestCase +final class TranslationStampTest extends TestCase { /** - * @return void + * Test if the getParameters method returns correct parameters. */ - public function testTranslationStamp() + public function testGetParameters(): void { - $stamp = new TranslationStamp(array('foo' => 'bar'), 'ar'); + $parameters = ['param1' => 'value1', 'param2' => 'value2']; - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertEquals(array('foo' => 'bar'), $stamp->getParameters()); - $this->assertEquals('ar', $stamp->getLocale()); + // Create a TranslationStamp instance with parameters + $translationStamp = new TranslationStamp($parameters); + + // Assert that the getParameters method should return the same parameters as those given to the constructor + $this->assertSame($parameters, $translationStamp->getParameters()); } /** - * @return void + * Test if the getParameters method returns an empty array when no parameters are provided. */ - public function testParametersOrder() + public function testGetParametersEmpty(): void { - $parameters = TranslationStamp::parametersOrder('ar'); + // Create a TranslationStamp instance without providing parameters + $translationStamp = new TranslationStamp(); - $this->assertEquals(array('locale' => 'ar', 'parameters' => array()), $parameters); + // Assert that the getParameters method should return an empty array + $this->assertSame([], $translationStamp->getParameters()); + } + + /** + * Test if the getLocale method returns the correct locale. + */ + public function testGetLocale(): void + { + $locale = 'en_US'; + + // Create a TranslationStamp instance with a locale + $translationStamp = new TranslationStamp([], $locale); + + // Assert that the getLocale method should return the same locale as that given to the constructor + $this->assertSame($locale, $translationStamp->getLocale()); + } + + /** + * Test if the getLocale method returns null when no locale is provided. + */ + public function testGetLocaleNull(): void + { + // Create a TranslationStamp instance without providing a locale + $translationStamp = new TranslationStamp(); + + // Assert that the getLocale method should return null + $this->assertNull($translationStamp->getLocale()); } } diff --git a/tests/Prime/Stamp/UnlessStampTest.php b/tests/Prime/Stamp/UnlessStampTest.php index c3a921d1..c36252ad 100644 --- a/tests/Prime/Stamp/UnlessStampTest.php +++ b/tests/Prime/Stamp/UnlessStampTest.php @@ -1,25 +1,27 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\UnlessStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class UnlessStampTest extends TestCase +final class UnlessStampTest extends TestCase { - /** - * @return void - */ - public function testUnlessStamp() + // Test case for getCondition() method + public function testGetCondition(): void { - $stamp = new UnlessStamp(true); + // Create a testable instance of UnlessStamp class + $unlessStamp = new UnlessStamp(true); - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertTrue($stamp->getCondition()); + // Assert that getCondition correctly returns the value passed in the constructor + $this->assertTrue($unlessStamp->getCondition()); + + // Create another testable instance of UnlessStamp class + $unlessStamp = new UnlessStamp(false); + + // Again assert that getCondition correctly returns the value passed in the constructor + $this->assertFalse($unlessStamp->getCondition()); } } diff --git a/tests/Prime/Stamp/UuidStampTest.php b/tests/Prime/Stamp/UuidStampTest.php index 13d33a88..33eb179e 100644 --- a/tests/Prime/Stamp/UuidStampTest.php +++ b/tests/Prime/Stamp/UuidStampTest.php @@ -1,29 +1,24 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\IdStamp; +use Flasher\Prime\Stamp\StampInterface; +use PHPUnit\Framework\TestCase; final class UuidStampTest extends TestCase { - /** - * @return void - */ - public function testUuidStamp() + public function testUuidStamp(): void { - $stamp = new UuidStamp(); + $stamp = new IdStamp(); - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertNotEmpty($stamp->getUuid()); + $this->assertInstanceOf(StampInterface::class, $stamp); + $this->assertNotEmpty($stamp->getId()); - $stamp = new UuidStamp('aaaa-bbbb-cccc'); - $this->assertEquals('aaaa-bbbb-cccc', $stamp->getUuid()); - $this->assertEquals(array('uuid' => 'aaaa-bbbb-cccc'), $stamp->toArray()); + $stamp = new IdStamp('aaaa-bbbb-cccc'); + $this->assertSame('aaaa-bbbb-cccc', $stamp->getId()); + $this->assertSame(['id' => 'aaaa-bbbb-cccc'], $stamp->toArray()); } } diff --git a/tests/Prime/Stamp/ViewStampTest.php b/tests/Prime/Stamp/ViewStampTest.php deleted file mode 100644 index 82e4b2ee..00000000 --- a/tests/Prime/Stamp/ViewStampTest.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Flasher\Tests\Prime\Stamp; - -use Flasher\Prime\Stamp\ViewStamp; -use Flasher\Tests\Prime\TestCase; - -class ViewStampTest extends TestCase -{ - /** - * @return void - */ - public function testViewStamp() - { - $stamp = new ViewStamp('template.html.twig'); - - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertEquals('template.html.twig', $stamp->getView()); - $this->assertEquals(array('view' => 'template.html.twig'), $stamp->toArray()); - } -} diff --git a/tests/Prime/Stamp/WhenStampTest.php b/tests/Prime/Stamp/WhenStampTest.php index 06461c02..dac718d4 100644 --- a/tests/Prime/Stamp/WhenStampTest.php +++ b/tests/Prime/Stamp/WhenStampTest.php @@ -1,25 +1,20 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Stamp; use Flasher\Prime\Stamp\WhenStamp; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class WhenStampTest extends TestCase +final class WhenStampTest extends TestCase { - /** - * @return void - */ - public function testWhenStamp() + public function testGetCondition(): void { - $stamp = new WhenStamp(true); + $whenStamp = new WhenStamp(true); + $this->assertTrue($whenStamp->getCondition()); - $this->assertInstanceOf('Flasher\Prime\Stamp\StampInterface', $stamp); - $this->assertTrue($stamp->getCondition()); + $whenStamp = new WhenStamp(false); + $this->assertFalse($whenStamp->getCondition()); } } diff --git a/tests/Prime/Storage/Bag/ArrayBagTest.php b/tests/Prime/Storage/Bag/ArrayBagTest.php index 3b574dac..571afc39 100644 --- a/tests/Prime/Storage/Bag/ArrayBagTest.php +++ b/tests/Prime/Storage/Bag/ArrayBagTest.php @@ -1,33 +1,47 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Storage\Bag; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Storage\Bag\ArrayBag; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class ArrayBagTest extends TestCase +final class ArrayBagTest extends TestCase { - /** - * @return void - */ - public function testArrayBag() + private ArrayBag $bag; + + protected function setUp(): void { - $bag = new ArrayBag(); + $this->bag = new ArrayBag(); + } - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification()), - ); + /** + * Test the `get` method of the `ArrayBag` class. + * It should return an array of envelopes that have been set. + */ + public function testGet(): void + { + $this->assertSame([], $this->bag->get()); - $bag->set($envelopes); + $envelope = new Envelope(new Notification()); + $this->bag->set([$envelope]); + $this->assertSame([$envelope], $this->bag->get()); + } - $this->assertEquals($envelopes, $bag->get()); + /** + * Test the `set` method of the `ArrayBag` class. + * It should set the envelopes in the bag. + */ + public function testSet(): void + { + $envelope = new Envelope(new Notification()); + + $this->bag->set([$envelope]); + + $envelopes = $this->bag->get(); + $this->assertSame([$envelope], $envelopes); } } diff --git a/tests/Prime/Storage/Bag/StaticBagTest.php b/tests/Prime/Storage/Bag/StaticBagTest.php index 8c6636e3..43a8fa15 100644 --- a/tests/Prime/Storage/Bag/StaticBagTest.php +++ b/tests/Prime/Storage/Bag/StaticBagTest.php @@ -1,33 +1,34 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Storage\Bag; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Storage\Bag\StaticBag; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class StaticBagTest extends TestCase +final class StaticBagTest extends TestCase { - /** - * @return void - */ - public function testStaticBag() + private StaticBag $staticBag; + + protected function setUp(): void { - $bag = new StaticBag(); + $this->staticBag = new StaticBag(); + } - $envelopes = array( + public function testGetAndSetMethods(): void + { + $this->assertSame([], $this->staticBag->get()); + + $envelopes = [ new Envelope(new Notification()), new Envelope(new Notification()), - ); + ]; - $bag->set($envelopes); + $this->staticBag->set($envelopes); - $this->assertEquals($envelopes, $bag->get()); + $this->assertEquals($envelopes, $this->staticBag->get()); } } diff --git a/tests/Prime/Storage/Filter/FilterFactoryTest.php b/tests/Prime/Storage/Filter/FilterFactoryTest.php new file mode 100644 index 00000000..82cca9af --- /dev/null +++ b/tests/Prime/Storage/Filter/FilterFactoryTest.php @@ -0,0 +1,83 @@ +filterFactory = new FilterFactory(); + } + + public function testConstructor(): void + { + $reflect = new \ReflectionClass(FilterFactory::class); + $reflectValue = $reflect->getProperty('criteria'); + + /** @var array $value */ + $value = $reflectValue->getValue($this->filterFactory); + + $this->assertArrayHasKey('priority', $value); + $this->assertArrayHasKey('hops', $value); + $this->assertArrayHasKey('delay', $value); + $this->assertArrayHasKey('order_by', $value); + $this->assertArrayHasKey('limit', $value); + $this->assertArrayHasKey('stamps', $value); + $this->assertArrayHasKey('filter', $value); + $this->assertArrayHasKey('presenter', $value); + } + + public function testCreateFilter(): void + { + $config = [ + 'limit' => 5, + ]; + + $filter = $this->filterFactory->createFilter($config); + + $reflect = new \ReflectionClass(Filter::class); + $reflectValue = $reflect->getProperty('criteriaChain'); + + /** @var CriteriaInterface[] $value */ + $value = $reflectValue->getValue($filter); + + $this->assertInstanceOf(LimitCriteria::class, $value[0]); + } + + public function testCreateFilterWithInvalidCriteriaName(): void + { + $this->expectException(CriteriaNotRegisteredException::class); + + $config = ['invalid_criteria_name' => 'invalid_criteria_value']; + $this->filterFactory->createFilter($config); + } + + public function testAddCriteria(): void + { + $reflect = new \ReflectionClass(FilterFactory::class); + $reflectValue = $reflect->getProperty('criteria'); + + $this->filterFactory->addCriteria('custom_criteria', fn () => new class() implements CriteriaInterface { + public function apply(array $envelopes): array + { + return $envelopes; + } + }); + + /** @var array $value */ + $value = $reflectValue->getValue($this->filterFactory); + + $this->assertArrayHasKey('custom_criteria', $value); + } +} diff --git a/tests/Prime/Storage/Filter/FilterTest.php b/tests/Prime/Storage/Filter/FilterTest.php new file mode 100644 index 00000000..828fddc4 --- /dev/null +++ b/tests/Prime/Storage/Filter/FilterTest.php @@ -0,0 +1,59 @@ +filter = new Filter(); + } + + public function testApply(): void + { + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $expectedEnvelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $criteria = \Mockery::mock(CriteriaInterface::class); + $criteria->allows() + ->apply($envelopes) + ->andReturns($expectedEnvelopes); + + $this->filter->addCriteria($criteria); + + $this->assertSame($expectedEnvelopes, $this->filter->apply($envelopes)); + } + + public function testAddCriteria(): void + { + $criteria = \Mockery::mock(CriteriaInterface::class); + + $this->filter->addCriteria($criteria); + + $reflection = new \ReflectionClass($this->filter); + $property = $reflection->getProperty('criteriaChain'); + + /** @var CriteriaInterface[] $criteriaChain */ + $criteriaChain = $property->getValue($this->filter); + + $this->assertContains($criteria, $criteriaChain); + } +} diff --git a/tests/Prime/Storage/StorageBagTest.php b/tests/Prime/Storage/StorageBagTest.php index d279bbea..88d4ad43 100644 --- a/tests/Prime/Storage/StorageBagTest.php +++ b/tests/Prime/Storage/StorageBagTest.php @@ -1,84 +1,71 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Storage; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Prime\Storage\StorageBag; -use Flasher\Tests\Prime\TestCase; +use Flasher\Prime\Stamp\IdStamp; +use Flasher\Prime\Storage\Bag\ArrayBag; +use Flasher\Prime\Storage\Storage; +use PHPUnit\Framework\TestCase; -class StorageBagTest extends TestCase +final class StorageBagTest extends TestCase { - /** - * @return void - */ - public function testAddEnvelopes() + public function testAddEnvelopes(): void { - $envelopes = array( - array( - new Envelope(new Notification(), new UuidStamp('1111')), - new Envelope(new Notification(), new UuidStamp('2222')), - ), - array( - new Envelope(new Notification(), new UuidStamp('3333')), - new Envelope(new Notification(), new UuidStamp('4444')), - ), - ); + $envelopes = [ + [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ], + [ + new Envelope(new Notification(), new IdStamp('3333')), + new Envelope(new Notification(), new IdStamp('4444')), + ], + ]; - $storageBag = new StorageBag(); - $storageBag->add($envelopes[0]); - $storageBag->add($envelopes[1]); + $storageBag = new Storage(new ArrayBag()); + $storageBag->add(...$envelopes[0]); + $storageBag->add(...$envelopes[1]); - $this->assertEquals(array_merge($envelopes[0], $envelopes[1]), $storageBag->all()); + $this->assertEquals([...$envelopes[0], ...$envelopes[1]], $storageBag->all()); } - /** - * @return void - */ - public function testUpdateEnvelopes() + public function testUpdateEnvelopes(): void { - $envelopes = array( - array( - new Envelope(new Notification(), new UuidStamp('1111')), - new Envelope(new Notification(), new UuidStamp('2222')), - ), - array( - new Envelope(new Notification(), new UuidStamp('3333')), - new Envelope(new Notification(), new UuidStamp('4444')), - ), - ); + $envelopes = [ + [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ], + [ + new Envelope(new Notification(), new IdStamp('3333')), + new Envelope(new Notification(), new IdStamp('4444')), + ], + ]; - $storageBag = new StorageBag(); - $storageBag->update($envelopes[0]); - $storageBag->update($envelopes[1]); + $storageBag = new Storage(new ArrayBag()); + $storageBag->update(...$envelopes[0]); + $storageBag->update(...$envelopes[1]); - $this->assertEquals(array_merge($envelopes[0], $envelopes[1]), $storageBag->all()); + $this->assertEquals([...$envelopes[0], ...$envelopes[1]], $storageBag->all()); } - /** - * @return void - */ - public function testRemoveEnvelopes() + public function testRemoveEnvelopes(): void { - $envelopes = array( - new Envelope(new Notification(), new UuidStamp('1111')), - new Envelope(new Notification(), new UuidStamp('2222')), - new Envelope(new Notification(), new UuidStamp('3333')), - new Envelope(new Notification(), new UuidStamp('4444')), - ); + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + new Envelope(new Notification(), new IdStamp('3333')), + new Envelope(new Notification(), new IdStamp('4444')), + ]; - $storageBag = new StorageBag(); - $storageBag->add($envelopes); + $storageBag = new Storage(new ArrayBag()); + $storageBag->add(...$envelopes); - $storageBag->remove(array( - new Envelope(new Notification(), new UuidStamp('2222')), - )); + $storageBag->remove(new Envelope(new Notification(), new IdStamp('2222'))); unset($envelopes[1]); diff --git a/tests/Prime/Storage/StorageManagerTest.php b/tests/Prime/Storage/StorageManagerTest.php index 3b955b9f..97527780 100644 --- a/tests/Prime/Storage/StorageManagerTest.php +++ b/tests/Prime/Storage/StorageManagerTest.php @@ -1,138 +1,125 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Storage; +use Flasher\Prime\EventDispatcher\Event\FilterEvent; +use Flasher\Prime\EventDispatcher\Event\PersistEvent; +use Flasher\Prime\EventDispatcher\Event\PostPersistEvent; +use Flasher\Prime\EventDispatcher\Event\PostRemoveEvent; +use Flasher\Prime\EventDispatcher\Event\PostUpdateEvent; +use Flasher\Prime\EventDispatcher\Event\RemoveEvent; +use Flasher\Prime\EventDispatcher\Event\UpdateEvent; +use Flasher\Prime\EventDispatcher\EventDispatcherInterface; use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Notification; use Flasher\Prime\Stamp\DelayStamp; use Flasher\Prime\Stamp\HopsStamp; -use Flasher\Prime\Stamp\UuidStamp; +use Flasher\Prime\Stamp\IdStamp; +use Flasher\Prime\Storage\Filter\Filter; +use Flasher\Prime\Storage\Filter\FilterFactoryInterface; +use Flasher\Prime\Storage\StorageInterface; use Flasher\Prime\Storage\StorageManager; -use Flasher\Tests\Prime\TestCase; +use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use Mockery\MockInterface; +use PHPUnit\Framework\TestCase; -class StorageManagerTest extends TestCase +final class StorageManagerTest extends TestCase { - /** - * @return void - */ - public function testGetAllStoredEnvelopes() + use MockeryPHPUnitIntegration; + + private MockInterface&StorageInterface $storageMock; + private MockInterface&FilterFactoryInterface $filterFactoryMock; + private MockInterface&EventDispatcherInterface $eventDispatcherMock; + private StorageManager $storageManager; + + protected function setUp(): void { - $envelopes = array( - new Envelope(new Notification(), new UuidStamp('1111')), - new Envelope(new Notification(), new UuidStamp('2222')), - new Envelope(new Notification(), new UuidStamp('3333')), - new Envelope(new Notification(), new UuidStamp('4444')), - ); + $this->storageMock = \Mockery::mock(StorageInterface::class); + $this->filterFactoryMock = \Mockery::mock(FilterFactoryInterface::class); + $this->eventDispatcherMock = \Mockery::mock(EventDispatcherInterface::class); - $storage = $this->getMockBuilder('Flasher\Prime\Storage\StorageInterface')->getMock(); - $storage->expects($this->once())->method('all')->willReturn($envelopes); - - $storageManager = new StorageManager($storage); - - $this->assertEquals($envelopes, $storageManager->all()); + $this->storageManager = new StorageManager($this->storageMock, $this->eventDispatcherMock, $this->filterFactoryMock); } - /** - * @return void - */ - public function testGetFilteredEnvelopes() + public function testAll(): void { - $envelopes = array( - new Envelope(new Notification(), new UuidStamp('1111')), - new Envelope(new Notification(), new UuidStamp('2222'), new HopsStamp(1), new DelayStamp(0)), - new Envelope(new Notification(), new UuidStamp('3333')), - new Envelope(new Notification(), new UuidStamp('4444')), - ); + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + new Envelope(new Notification(), new IdStamp('3333')), + new Envelope(new Notification(), new IdStamp('4444')), + ]; - $storage = $this->getMockBuilder('Flasher\Prime\Storage\StorageInterface')->getMock(); - $storage->expects($this->once())->method('all')->willReturn($envelopes); + $this->storageMock->expects()->all()->once()->andReturns($envelopes); - $storageManager = new StorageManager($storage); - - $this->assertEquals(array($envelopes[1]), $storageManager->filter()); + $this->assertSame($envelopes, $this->storageManager->all()); } - /** - * @return void - */ - public function testAddEnvelopes() + public function testGetFilteredEnvelopes(): void { - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification()), - new Envelope(new Notification()), - new Envelope(new Notification()), - ); + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), [new IdStamp('2222'), new HopsStamp(1), new DelayStamp(0)]), + new Envelope(new Notification(), new IdStamp('3333')), + new Envelope(new Notification(), new IdStamp('4444')), + ]; - $storageManager = new StorageManager(); - $storageManager->add($envelopes); + $this->storageMock->expects()->all()->once()->andReturns($envelopes); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(FilterEvent::class))->once(); + $this->filterFactoryMock->expects()->createFilter([])->andReturns(new Filter()); - $this->assertEquals($envelopes, $storageManager->all()); + $this->assertSame($envelopes, $this->storageManager->filter()); } - /** - * @return void - */ - public function testUpdateEnvelopes() + public function testAdd(): void { - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification()), - new Envelope(new Notification()), - new Envelope(new Notification()), - ); + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; - $storageManager = new StorageManager(); - $storageManager->update($envelopes); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(PersistEvent::class))->once(); + $this->storageMock->expects()->add(...$envelopes)->once(); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(PostPersistEvent::class))->once(); - $this->assertEquals($envelopes, $storageManager->all()); + $this->storageManager->add(...$envelopes); } - /** - * @return void - */ - public function testRemoveEnvelopes() + public function testUpdate(): void { - $envelopes = array( - new Envelope(new Notification(), new UuidStamp('1111')), - new Envelope(new Notification(), new UuidStamp('2222')), - new Envelope(new Notification(), new UuidStamp('3333')), - new Envelope(new Notification(), new UuidStamp('4444')), - ); + $envelopes = [ + new Envelope(new Notification(), new IdStamp('5555')), + new Envelope(new Notification(), new IdStamp('6666')), + ]; - $storageManager = new StorageManager(); - $storageManager->add($envelopes); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(UpdateEvent::class))->once(); + $this->storageMock->expects()->update(...$envelopes)->once(); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(PostUpdateEvent::class))->once(); - $storageManager->remove(array( - new Envelope(new Notification(), new UuidStamp('2222')), - new Envelope(new Notification(), new UuidStamp('3333')), - )); - - $this->assertEquals(array($envelopes[0], $envelopes[3]), $storageManager->all()); + $this->storageManager->update(...$envelopes); } - /** - * @return void - */ - public function testClearEnvelopes() + public function testRemove(): void { - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification()), - new Envelope(new Notification()), - new Envelope(new Notification()), - ); + $envelopesToRemove = [ + new Envelope(new Notification(), new IdStamp('7777')), + new Envelope(new Notification(), new IdStamp('8888')), + ]; - $storageManager = new StorageManager(); - $storageManager->add($envelopes); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(RemoveEvent::class))->once(); + $this->storageMock->expects()->remove(...$envelopesToRemove)->once(); + $this->storageMock->expects()->update()->once(); + $this->eventDispatcherMock->expects()->dispatch(\Mockery::type(PostRemoveEvent::class))->once(); - $storageManager->clear(); + $this->storageManager->remove(...$envelopesToRemove); + } - $this->assertEquals(array(), $storageManager->all()); + public function testClear(): void + { + $this->storageMock->expects()->clear()->once(); + + $this->storageManager->clear(); } } diff --git a/tests/Prime/Storage/StorageTest.php b/tests/Prime/Storage/StorageTest.php new file mode 100644 index 00000000..be01eba7 --- /dev/null +++ b/tests/Prime/Storage/StorageTest.php @@ -0,0 +1,100 @@ +storage = new Storage(new ArrayBag()); + } + + public function testAllMethod(): void + { + $envelopes = [ + [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ], + [ + new Envelope(new Notification(), new IdStamp('3333')), + new Envelope(new Notification(), new IdStamp('4444')), + ], + ]; + + $this->storage->add(...$envelopes[0]); + $this->storage->add(...$envelopes[1]); + + $this->assertEquals([...$envelopes[0], ...$envelopes[1]], $this->storage->all()); + $this->assertNotEquals(array_reverse([...$envelopes[0], ...$envelopes[1]]), $this->storage->all()); + } + + public function testAddMethod(): void + { + $envelope = new Envelope(new Notification(), new IdStamp('1111')); + + $this->storage->add($envelope); + + $this->assertContains($envelope, $this->storage->all()); + } + + public function testUpdateMethod(): void + { + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $this->storage->add(...$envelopes); + $this->assertContains($envelopes[1], $this->storage->all()); + + $envelopes[1] = new Envelope(new Notification(), new IdStamp('3333')); + + $this->storage->update(...$envelopes); + $this->assertContains($envelopes[1], $this->storage->all()); + $this->assertNotContains('Notification2', $this->storage->all()); + } + + public function testRemoveMethod(): void + { + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $this->storage->add(...$envelopes); + + $this->assertContains($envelopes[1], $this->storage->all()); + + $this->storage->remove($envelopes[1]); + + $this->assertNotContains($envelopes[1], $this->storage->all()); + } + + public function testClearMethod(): void + { + $envelopes = [ + new Envelope(new Notification(), new IdStamp('1111')), + new Envelope(new Notification(), new IdStamp('2222')), + ]; + + $this->storage->add(...$envelopes); + + $this->assertNotEmpty($this->storage->all()); + + $this->storage->clear(); + + $this->assertEmpty($this->storage->all()); + } +} diff --git a/tests/Prime/Support/Traits/ForwardsCallsTest.php b/tests/Prime/Support/Traits/ForwardsCallsTest.php new file mode 100644 index 00000000..2c01b2dd --- /dev/null +++ b/tests/Prime/Support/Traits/ForwardsCallsTest.php @@ -0,0 +1,71 @@ +getMethod('forwardCallTo'); + + $result = $method->invokeArgs($testable, [$secondary, 'someMethod', []]); + $this->assertSame('method result', $result); + } + + public function testForwardingAndReturningThis(): void + { + $testable = new class() { + use ForwardsCalls; + }; + + $secondary = new class() { + public function selfReturningMethod(): self + { + return $this; + } + }; + + $reflection = new \ReflectionClass($testable::class); + $method = $reflection->getMethod('forwardDecoratedCallTo'); + + $result = $method->invokeArgs($testable, [$secondary, 'selfReturningMethod', []]); + $this->assertNotSame($secondary, $result); + $this->assertInstanceOf($testable::class, $result); + } + + public function testUndefinedMethodCall(): void + { + $testable = new class() { + use ForwardsCalls; + }; + + $secondary = new class() { + // This class intentionally left blank to simulate an undefined method call. + }; + + // Use reflection to change visibility + $reflection = new \ReflectionClass($testable::class); + $method = $reflection->getMethod('forwardCallTo'); + + $this->expectException(\Error::class); + $this->expectExceptionMessage('Call to undefined method class@anonymous::undefinedMethod()'); + $method->invokeArgs($testable, [$secondary, 'undefinedMethod', []]); + } +} diff --git a/tests/Prime/Support/Traits/MacroableTest.php b/tests/Prime/Support/Traits/MacroableTest.php new file mode 100644 index 00000000..cd3fb478 --- /dev/null +++ b/tests/Prime/Support/Traits/MacroableTest.php @@ -0,0 +1,67 @@ +assertTrue($macroableClass::hasMacro('testMacro')); + $this->assertSame('macro result', $macroableClass::testMacro()); // @phpstan-ignore-line + } + + public function testMixin(): void + { + $macroableClass = new class() { + use Macroable; + }; + + $mixin = new class() { + public function mixedInMethod(): callable + { + return static function () { + return 'mixed in'; + }; + } + }; + + $macroableClass::mixin($mixin); + + $this->assertTrue($macroableClass::hasMacro('mixedInMethod')); + $this->assertSame('mixed in', $macroableClass::mixedInMethod()); // @phpstan-ignore-line + } + + public function testExceptionForNonExistingMacro(): void + { + $macroableClass = new class() { + use Macroable; + }; + + $this->expectException(\BadMethodCallException::class); + $macroableClass::nonExistingMacro(); // @phpstan-ignore-line + } + + public function testExceptionForNonCallableMacro(): void + { + $macroableClass = new class() { + use Macroable; + }; + + $macroableClass::macro('nonCallable', new \stdClass()); + $this->expectException(\BadMethodCallException::class); + $macroableClass::nonCallable(); // @phpstan-ignore-line + } +} diff --git a/tests/Prime/Template/PHPTemplateEngineTest.php b/tests/Prime/Template/PHPTemplateEngineTest.php new file mode 100644 index 00000000..53900e47 --- /dev/null +++ b/tests/Prime/Template/PHPTemplateEngineTest.php @@ -0,0 +1,47 @@ +templateEngine = new PHPTemplateEngine(); + } + + /** + * Test case for testing the render method with a valid filename and context. + */ + public function testRenderWithValidFilenameContext(): void + { + $name = 'someTemplateFile.php'; + $context = ['key' => 'value']; + + // Create a fake template file for the purpose of this test. + file_put_contents($name, 'templateEngine->render($name, $context); + + // Cleanup the fake template file + unlink($name); + + $this->assertSame('value', trim($result), "Rendered template content doesn't match expected content."); + } + + /** + * Test case for testing the render method with an invalid filename. + */ + public function testRenderWithInvalidFilename(): void + { + $this->expectException(\InvalidArgumentException::class); + + $this->templateEngine->render('invalidFileName.php'); + } +} diff --git a/tests/Prime/TestCase.php b/tests/Prime/TestCase.php deleted file mode 100644 index 0f286c2f..00000000 --- a/tests/Prime/TestCase.php +++ /dev/null @@ -1,102 +0,0 @@ - - */ - -namespace Flasher\Tests\Prime; - -class TestCase extends \PHPUnit\Framework\TestCase -{ - /** - * @param class-string<\Throwable> $exceptionName - * @param string $exceptionMessage - * @param int $exceptionCode - * - * @return void - */ - public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = null) - { - if (method_exists($this, 'expectException')) { - $this->expectException($exceptionName); - $this->expectExceptionMessage($exceptionMessage); - } else { - parent::setExpectedException($exceptionName, $exceptionMessage, $exceptionCode); // @phpstan-ignore-line - } - } - - /** - * Call a protected or private method of a class using reflection. - * - * @param object|string $object instantiated object or FQCN that we will run method - * @param string $methodName method name to call - * @param array|mixed $parameters array of parameters to pass into method - * - * @return mixed method return - * - * @throws \ReflectionException - */ - protected function invokeMethod($object, $methodName, $parameters = array()) - { - $class = is_string($object) ? $object : get_class($object); - - $reflection = new \ReflectionClass($class); - - $method = $reflection->getMethod($methodName); - $method->setAccessible(true); - - $object = is_string($object) ? null : $object; - $parameters = \is_array($parameters) ? $parameters : \array_slice(\func_get_args(), 2); - - return $method->invokeArgs($object, $parameters); - } - - /** - * Get the value of a protected or private property of a class using reflection. - * - * @param object|string $object instantiated object or FQCN that we will access property from - * @param string $propertyName name of property to access - * - * @return mixed property value - * - * @throws \ReflectionException - */ - protected function getProperty($object, $propertyName) - { - $class = is_string($object) ? $object : get_class($object); - - $reflection = new \ReflectionClass($class); - - $property = $reflection->getProperty($propertyName); - $property->setAccessible(true); - - $object = is_string($object) ? null : $object; - - return $property->getValue($object); - } - - /** - * Set the value of a protected or private property of a class using reflection. - * - * @param object|string $object instantiated object or FQCN that we will run method - * @param string $propertyName name of property to set - * @param mixed $value value to set the property to - * - * @return void - * - * @throws \ReflectionException - */ - protected function setProperty($object, $propertyName, $value) - { - $class = is_string($object) ? $object : get_class($object); - - $reflection = new \ReflectionClass($class); - - $property = $reflection->getProperty($propertyName); - $property->setAccessible(true); - - $object = is_string($object) ? null : $object; - $property->setValue($object, $value); - } -} diff --git a/tests/Prime/Translation/EchoTranslatorTest.php b/tests/Prime/Translation/EchoTranslatorTest.php index 71625c89..9466913d 100644 --- a/tests/Prime/Translation/EchoTranslatorTest.php +++ b/tests/Prime/Translation/EchoTranslatorTest.php @@ -1,25 +1,43 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Translation; use Flasher\Prime\Translation\EchoTranslator; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\TestCase; -class EchoTranslatorTest extends TestCase +final class EchoTranslatorTest extends TestCase { - /** - * @return void - */ - public function testEchoTranslator() - { - $translator = new EchoTranslator(); + private EchoTranslator $translator; - $this->assertEquals('en', $translator->getLocale()); - $this->assertEquals('PHPFlasher', $translator->translate('PHPFlasher')); + protected function setUp(): void + { + $this->translator = new EchoTranslator(); + } + + /** + * This method is for testing if the Translate method in EchoTranslator class returns the same + * id it received as input without any transformations. + */ + public function testTranslate(): void + { + $id = 'TestID'; + $parameters = []; + $locale = null; + + $result = $this->translator->translate($id, $parameters, $locale); + + $this->assertSame($id, $result, 'The Translate method should return the same id it received as input'); + } + + /** + * This method is for testing if the getLocale method in EchoTranslator class always returns 'en'. + */ + public function testGetLocale(): void + { + $locale = $this->translator->getLocale(); + + $this->assertSame('en', $locale, "The getLocale method should return 'en'"); } } diff --git a/tests/Prime/Translation/Language/ArabicTest.php b/tests/Prime/Translation/Language/ArabicTest.php new file mode 100644 index 00000000..a0d9f7a6 --- /dev/null +++ b/tests/Prime/Translation/Language/ArabicTest.php @@ -0,0 +1,33 @@ + 'نجاح', + 'error' => 'خطأ', + 'warning' => 'تحذير', + 'info' => 'معلومة', + + 'The resource was created' => 'تم إنشاء :resource', + 'The resource was updated' => 'تم تعديل :resource', + 'The resource was saved' => 'تم حفظ :resource', + 'The resource was deleted' => 'تم حذف :resource', + + 'resource' => 'الملف', + ]; + + $this->assertSame($expectedTranslations, Arabic::translations()); + } +} diff --git a/tests/Prime/Translation/Language/ChineseTest.php b/tests/Prime/Translation/Language/ChineseTest.php new file mode 100644 index 00000000..9295c4fe --- /dev/null +++ b/tests/Prime/Translation/Language/ChineseTest.php @@ -0,0 +1,33 @@ + '成功', + 'error' => '错误', + 'warning' => '警告', + 'info' => '信息', + + 'The resource was created' => ':resource 已创建', + 'The resource was updated' => ':resource 已更新', + 'The resource was saved' => ':resource 已保存', + 'The resource was deleted' => ':resource 已删除', + + 'resource' => '资源', + ]; + + $this->assertSame($expectedTranslations, Chinese::translations()); + } +} diff --git a/tests/Prime/Translation/Language/EnglishTest.php b/tests/Prime/Translation/Language/EnglishTest.php new file mode 100644 index 00000000..3bd8b20d --- /dev/null +++ b/tests/Prime/Translation/Language/EnglishTest.php @@ -0,0 +1,33 @@ + 'Success', + 'error' => 'Error', + 'warning' => 'Warning', + 'info' => 'Info', + + 'The resource was created' => 'The :resource was created', + 'The resource was updated' => 'The :resource was updated', + 'The resource was saved' => 'The :resource was saved', + 'The resource was deleted' => 'The :resource was deleted', + + 'resource' => 'resource', + ]; + + $this->assertSame($expectedTranslations, English::translations()); + } +} diff --git a/tests/Prime/Translation/Language/FrenchTest.php b/tests/Prime/Translation/Language/FrenchTest.php new file mode 100644 index 00000000..f1d32814 --- /dev/null +++ b/tests/Prime/Translation/Language/FrenchTest.php @@ -0,0 +1,33 @@ + 'Succès', + 'error' => 'Erreur', + 'warning' => 'Avertissement', + 'info' => 'Information', + + 'The resource was created' => 'La ressource :resource a été ajoutée', + 'The resource was updated' => 'La ressource :resource a été mise à jour', + 'The resource was saved' => 'La ressource :resource a été enregistrée', + 'The resource was deleted' => 'La ressource :resource a été supprimée', + + 'resource' => '', + ]; + + $this->assertSame($expectedTranslations, French::translations()); + } +} diff --git a/tests/Prime/Translation/Language/GermanTest.php b/tests/Prime/Translation/Language/GermanTest.php new file mode 100644 index 00000000..5dde467a --- /dev/null +++ b/tests/Prime/Translation/Language/GermanTest.php @@ -0,0 +1,33 @@ + 'Erfolg', + 'error' => 'Fehler', + 'warning' => 'Warnung', + 'info' => 'Info', + + 'The resource was created' => 'Die Ressource :resource wurde erstellt', + 'The resource was updated' => 'Die Ressource :resource wurde aktualisiert', + 'The resource was saved' => 'Die Ressource :resource wurde gespeichert', + 'The resource was deleted' => 'Die Ressource :resource wurde gelöscht', + + 'resource' => 'Ressource', + ]; + + $this->assertSame($expectedTranslations, German::translations()); + } +} diff --git a/tests/Prime/Translation/Language/PortugueseTest.php b/tests/Prime/Translation/Language/PortugueseTest.php new file mode 100644 index 00000000..cb5906af --- /dev/null +++ b/tests/Prime/Translation/Language/PortugueseTest.php @@ -0,0 +1,33 @@ + 'Sucesso', + 'error' => 'Erro', + 'warning' => 'Aviso', + 'info' => 'Informação', + + 'The resource was created' => 'O :resource foi criado', + 'The resource was updated' => 'O :resource foi atualizado', + 'The resource was saved' => 'O :resource foi salvo', + 'The resource was deleted' => 'O :resource foi deletado', + + 'resource' => 'recurso', + ]; + + $this->assertSame($expectedTranslations, Portuguese::translations()); + } +} diff --git a/tests/Prime/Translation/Language/RussianTest.php b/tests/Prime/Translation/Language/RussianTest.php new file mode 100644 index 00000000..2348c397 --- /dev/null +++ b/tests/Prime/Translation/Language/RussianTest.php @@ -0,0 +1,33 @@ + 'Успех', + 'error' => 'Ошибка', + 'warning' => 'Предупреждение', + 'info' => 'Информация', + + 'The resource was created' => ':resource был создан', + 'The resource was updated' => ':resource был обновлен', + 'The resource was saved' => ':resource был сохранен', + 'The resource was deleted' => ':resource был удален', + + 'resource' => 'ресурс', + ]; + + $this->assertSame($expectedTranslations, Russian::translations()); + } +} diff --git a/tests/Prime/Translation/Language/SpanishTest.php b/tests/Prime/Translation/Language/SpanishTest.php new file mode 100644 index 00000000..122fa929 --- /dev/null +++ b/tests/Prime/Translation/Language/SpanishTest.php @@ -0,0 +1,33 @@ + 'Éxito', + 'error' => 'Error', + 'warning' => 'Advertencia', + 'info' => 'Información', + + 'The resource was created' => 'El :resource fue creado', + 'The resource was updated' => 'El :resource fue actualizado', + 'The resource was saved' => 'El :resource fue guardado', + 'The resource was deleted' => 'El :resource fue eliminado', + + 'resource' => 'recurso', + ]; + + $this->assertSame($expectedTranslations, Spanish::translations()); + } +} diff --git a/tests/Prime/Translation/LanguageTest.php b/tests/Prime/Translation/LanguageTest.php index ab904e9d..50c2fb1a 100644 --- a/tests/Prime/Translation/LanguageTest.php +++ b/tests/Prime/Translation/LanguageTest.php @@ -1,42 +1,59 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Prime\Translation; use Flasher\Prime\Translation\Language; -use Flasher\Tests\Prime\TestCase; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\TestCase; -class LanguageTest extends TestCase +final class LanguageTest extends TestCase { - /** - * @return void - */ - public function testLanguageDirection() + #[DataProvider('provideLocaleData')] + public function testDirectionMethod(string $locale, string $expectedDirection): void { - $this->assertEquals(Language::RTL, Language::direction('ar')); - $this->assertEquals(Language::LTR, Language::direction('fr')); - $this->assertEquals(Language::LTR, Language::direction('unknown')); + $this->assertSame($expectedDirection, Language::direction($locale)); } /** - * @return void + * Provide test cases for testDirectionMethod. */ - public function testIsRTL() + public static function provideLocaleData(): \Iterator { - $this->assertTrue(Language::isRTL('ar_AE')); - $this->assertFalse(Language::isRTL('en_US')); + yield ['en', Language::LTR]; + yield ['ar', Language::RTL]; + yield ['unknown', Language::LTR]; + } + + #[DataProvider('provideLocaleDataForIsRTL')] + public function testIsRTLMethod(string $locale, bool $expectedResult): void + { + $this->assertSame($expectedResult, Language::isRTL($locale)); } /** - * @return void + * Provide test cases for testIsRTLMethod. */ - public function testIsLTR() + public static function provideLocaleDataForIsRTL(): \Iterator { - $this->assertTrue(Language::isLTR('en_US')); - $this->assertFalse(Language::isLTR('ar_AE')); + yield ['en', false]; + yield ['en_US', false]; + yield ['ar', true]; + } + + #[DataProvider('provideLocaleDataForIsLTR')] + public function testIsLTRMethod(string $locale, bool $expectedResult): void + { + $this->assertSame($expectedResult, Language::isLTR($locale)); + } + + /** + * Provide test cases for testIsLTRMethod. + */ + public static function provideLocaleDataForIsLTR(): \Iterator + { + yield ['en', true]; + yield ['ar', false]; } } diff --git a/tests/Prime/Translation/MessagesTest.php b/tests/Prime/Translation/MessagesTest.php new file mode 100644 index 00000000..4b1cfc4c --- /dev/null +++ b/tests/Prime/Translation/MessagesTest.php @@ -0,0 +1,34 @@ +assertIsArray($actual); + $this->assertSame($empty, empty($actual)); + } + + public static function provideLanguages(): \Iterator + { + yield 'Arabic' => ['ar', false]; + yield 'German' => ['de', false]; + yield 'English' => ['en', false]; + yield 'Spanish' => ['es', false]; + yield 'French' => ['fr', false]; + yield 'Portuguese' => ['pt', false]; + yield 'Non-Existing' => ['non-existing', true]; + } +} diff --git a/tests/SweetAlert/Laravel/FlasherSweetAlertServiceProviderTest.php b/tests/SweetAlert/Laravel/FlasherSweetAlertServiceProviderTest.php new file mode 100644 index 00000000..468fdc45 --- /dev/null +++ b/tests/SweetAlert/Laravel/FlasherSweetAlertServiceProviderTest.php @@ -0,0 +1,79 @@ +app = \Mockery::mock(Application::class); + $this->serviceProvider = new FlasherSweetAlertServiceProvider($this->app); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(SweetAlertPlugin::class, $this->serviceProvider->createPlugin()); + } + + public function testRegister(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('configurationIsCached')->never(); + + $this->serviceProvider->register(); + $this->addToAssertionCount(1); + } + + public function testBoot(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('singleton'); + $this->app->expects('alias'); + $this->app->expects('extend'); + $this->app->expects('bound'); + + $this->serviceProvider->register(); + $this->serviceProvider->boot(); + $this->addToAssertionCount(1); + } + + public function testGetConfigurationFile(): void + { + $expectedPath = $this->getResourcesPathFromServiceProvider(); + $this->assertStringEndsWith('/Resources/config.php', $this->serviceProvider->getConfigurationFile()); + $this->assertStringContainsString($expectedPath, $this->serviceProvider->getConfigurationFile()); + } + + private function getResourcesPathFromServiceProvider(): string + { + $reflection = new \ReflectionClass(FlasherSweetAlertServiceProvider::class); + $method = $reflection->getMethod('getResourcesDir'); + $method->setAccessible(true); + + /** @var string $string */ + $string = $method->invoke($this->serviceProvider); + + return rtrim($string, '/').'/'; + } +} diff --git a/tests/SweetAlert/Prime/SweetAlertBuilderTest.php b/tests/SweetAlert/Prime/SweetAlertBuilderTest.php new file mode 100644 index 00000000..5360d1c5 --- /dev/null +++ b/tests/SweetAlert/Prime/SweetAlertBuilderTest.php @@ -0,0 +1,616 @@ +storageManagerMock = \Mockery::mock(StorageManagerInterface::class); + $this->sweetAlertBuilder = new SweetAlertBuilder('sweetAlert', $this->storageManagerMock); + } + + public function testQuestion(): void + { + $this->sweetAlertBuilder->question('Are you sure?', ['option1' => 'value1']); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['showCancelButton' => true, 'text' => 'Are you sure?'], $options); + } + + public function testTitle(): void + { + $this->sweetAlertBuilder->title('My Title'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['title' => 'My Title'], $options); + } + + public function testTitleText(): void + { + $this->sweetAlertBuilder->titleText('Title Text'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['titleText' => 'Title Text'], $options); + } + + public function testHtml(): void + { + $this->sweetAlertBuilder->html('

      HTML Content

      '); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['html' => '

      HTML Content

      '], $options); + } + + public function testText(): void + { + $this->sweetAlertBuilder->text('Simple text'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['text' => 'Simple text'], $options); + } + + public function testIcon(): void + { + $this->sweetAlertBuilder->icon('success'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['icon' => 'success'], $options); + } + + public function testIconColor(): void + { + $this->sweetAlertBuilder->iconColor('#FF0000'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['iconColor' => '#FF0000'], $options); + } + + public function testIconHtml(): void + { + $this->sweetAlertBuilder->iconHtml('*'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['iconHtml' => '*'], $options); + } + + public function testShowClass(): void + { + $this->sweetAlertBuilder->showClass('popup', 'animate__animated animate__fadeInDown'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = ['showClass' => ['popup' => 'animate__animated animate__fadeInDown']]; + $this->assertSame($expected, $options); + } + + public function testHideClass(): void + { + $this->sweetAlertBuilder->hideClass('popup', 'animate__animated animate__fadeOutUp'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = ['hideClass' => ['popup' => 'animate__animated animate__fadeOutUp']]; + $this->assertSame($expected, $options); + } + + public function testFooter(): void + { + $this->sweetAlertBuilder->footer('Footer text'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['footer' => 'Footer text'], $options); + } + + public function testBackdrop(): void + { + $this->sweetAlertBuilder->backdrop(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['backdrop' => false], $options); + } + + public function testToast(): void + { + $this->sweetAlertBuilder->toast(true, 'top-end', false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = ['toast' => true, 'position' => 'top-end', 'showConfirmButton' => false, 'title' => ' ']; + $this->assertEquals($expected, $options); + } + + public function testTarget(): void + { + $this->sweetAlertBuilder->target('#my-target'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['target' => '#my-target'], $options); + } + + public function testInputLabel(): void + { + $this->sweetAlertBuilder->inputLabel('Input Label'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputLabel' => 'Input Label'], $options); + } + + public function testInputPlaceholder(): void + { + $this->sweetAlertBuilder->inputPlaceholder('Placeholder'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputPlaceholder' => 'Placeholder'], $options); + } + + public function testInputValue(): void + { + $this->sweetAlertBuilder->inputValue('Value'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputValue' => 'Value'], $options); + } + + public function testInputOptions(): void + { + $this->sweetAlertBuilder->inputOptions('Options'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputOptions' => 'Options'], $options); + } + + public function testInputAutoTrim(): void + { + $this->sweetAlertBuilder->inputAutoTrim(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputAutoTrim' => false], $options); + } + + public function testInputAttributes(): void + { + $this->sweetAlertBuilder->inputAttributes('Attributes'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputAttributes' => 'Attributes'], $options); + } + + public function testInputValidator(): void + { + $this->sweetAlertBuilder->inputValidator('Validator'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['inputValidator' => 'Validator'], $options); + } + + public function testValidationMessage(): void + { + $this->sweetAlertBuilder->validationMessage('Validation Message'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['validationMessage' => 'Validation Message'], $options); + } + + public function testInput(): void + { + $this->sweetAlertBuilder->input('text'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['input' => 'text'], $options); + } + + public function testWidth(): void + { + $this->sweetAlertBuilder->width('400px'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['width' => '400px'], $options); + } + + public function testPadding(): void + { + $this->sweetAlertBuilder->padding('20px'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['padding' => '20px'], $options); + } + + public function testBackground(): void + { + $this->sweetAlertBuilder->background('#000'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['background' => '#000'], $options); + } + + public function testGrow(): void + { + $this->sweetAlertBuilder->grow('row'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['grow' => 'row'], $options); + } + + public function testCustomClass(): void + { + $this->sweetAlertBuilder->customClass('confirmButton', 'btn btn-primary'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = ['customClass' => ['confirmButton' => 'btn btn-primary']]; + $this->assertSame($expected, $options); + } + + public function testTimer(): void + { + $this->sweetAlertBuilder->timer(5000); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['timer' => 5000], $options); + } + + public function testTimerProgressBar(): void + { + $this->sweetAlertBuilder->timerProgressBar(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['timerProgressBar' => true], $options); + } + + public function testHeightAuto(): void + { + $this->sweetAlertBuilder->heightAuto(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['heightAuto' => false], $options); + } + + public function testAllowOutsideClick(): void + { + $this->sweetAlertBuilder->allowOutsideClick(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['allowOutsideClick' => false], $options); + } + + public function testAllowEscapeKey(): void + { + $this->sweetAlertBuilder->allowEscapeKey(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['allowEscapeKey' => false], $options); + } + + public function testAllowEnterKey(): void + { + $this->sweetAlertBuilder->allowEnterKey(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['allowEnterKey' => false], $options); + } + + public function testStopKeydownPropagation(): void + { + $this->sweetAlertBuilder->stopKeydownPropagation(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['stopKeydownPropagation' => false], $options); + } + + public function testKeydownListenerCapture(): void + { + $this->sweetAlertBuilder->keydownListenerCapture(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['keydownListenerCapture' => true], $options); + } + + public function testPreConfirm(): void + { + $this->sweetAlertBuilder->preConfirm('function() { return true; }'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['preConfirm' => 'function() { return true; }'], $options); + } + + public function testPreDeny(): void + { + $this->sweetAlertBuilder->preDeny('function() { return true; }'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['preDeny' => 'function() { return true; }'], $options); + } + + public function testReturnInputValueOnDeny(): void + { + $this->sweetAlertBuilder->returnInputValueOnDeny(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['returnInputValueOnDeny' => true], $options); + } + + public function testAnimation(): void + { + $this->sweetAlertBuilder->animation(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['animation' => false], $options); + } + + public function testPersistent(): void + { + $this->sweetAlertBuilder->persistent(true, true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['allowEscapeKey' => false, 'allowOutsideClick' => false, 'timer' => 0, 'showConfirmButton' => true, 'showCloseButton' => true], $options); + } + + public function testImageUrl(): void + { + $this->sweetAlertBuilder->imageUrl('path/to/image.jpg', 100, 100, 'Image Alt'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = ['imageUrl' => 'path/to/image.jpg', 'imageWidth' => 100, 'imageHeight' => 100, 'imageAlt' => 'Image Alt']; + $this->assertSame($expected, $options); + } + + public function testImageWidth(): void + { + $this->sweetAlertBuilder->imageWidth(200); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['imageWidth' => 200], $options); + } + + public function testImageHeight(): void + { + $this->sweetAlertBuilder->imageHeight(200); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['imageHeight' => 200], $options); + } + + public function testImageAlt(): void + { + $this->sweetAlertBuilder->imageAlt('Alternative Text'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['imageAlt' => 'Alternative Text'], $options); + } + + public function testImage(): void + { + $this->sweetAlertBuilder->image('Title', 'Text', 'path/to/image.jpg', 300, 150, 'Alt Text'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = ['title' => 'Title', 'text' => 'Text', 'imageUrl' => 'path/to/image.jpg', 'imageWidth' => 300, 'imageHeight' => 150, 'animation' => false, 'imageAlt' => 'Alt Text']; + $this->assertEquals($expected, $options); + } + + public function testAddImage(): void + { + $this->storageManagerMock->expects('add'); + + $envelope = $this->sweetAlertBuilder->addImage('Title', 'Text', 'path/to/image.jpg', 300, 150, 'Alt Text'); + + $options = $envelope->getNotification()->getOptions(); + + $expected = ['title' => 'Title', 'text' => 'Text', 'imageUrl' => 'path/to/image.jpg', 'imageWidth' => 300, 'imageHeight' => 150, 'animation' => false, 'imageAlt' => 'Alt Text']; + $this->assertEquals($expected, $options); + } + + public function testShowDenyButton(): void + { + $this->sweetAlertBuilder->showDenyButton(true, 'Deny', '#FF0000', 'Deny this'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $expected = [ + 'showDenyButton' => true, + 'denyButtonText' => 'Deny', + 'denyButtonColor' => '#FF0000', + 'denyButtonAriaLabel' => 'Deny this', + ]; + $this->assertSame($expected, $options); + } + + public function testButtonsStyling(): void + { + $this->sweetAlertBuilder->buttonsStyling(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['buttonsStyling' => false], $options); + } + + public function testReverseButtons(): void + { + $this->sweetAlertBuilder->reverseButtons(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['reverseButtons' => true], $options); + } + + public function testFocusConfirm(): void + { + $this->sweetAlertBuilder->focusConfirm(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['focusConfirm' => false], $options); + } + + public function testFocusDeny(): void + { + $this->sweetAlertBuilder->focusDeny(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['focusDeny' => true], $options); + } + + public function testFocusCancel(): void + { + $this->sweetAlertBuilder->focusCancel(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['focusCancel' => true], $options); + } + + public function testCloseButtonHtml(): void + { + $this->sweetAlertBuilder->closeButtonHtml('Close'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeButtonHtml' => 'Close'], $options); + } + + public function testCloseButtonAriaLabel(): void + { + $this->sweetAlertBuilder->closeButtonAriaLabel('Close this popup'); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeButtonAriaLabel' => 'Close this popup'], $options); + } + + public function testLoaderHtml(): void + { + $this->sweetAlertBuilder->loaderHtml('
      Loading...
      '); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['loaderHtml' => '
      Loading...
      '], $options); + } + + public function testShowLoaderOnConfirm(): void + { + $this->sweetAlertBuilder->showLoaderOnConfirm(true); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['showLoaderOnConfirm' => true], $options); + } + + public function testScrollbarPadding(): void + { + $this->sweetAlertBuilder->scrollbarPadding(false); + + $envelope = $this->sweetAlertBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['scrollbarPadding' => false], $options); + } +} diff --git a/tests/SweetAlert/Prime/SweetAlertPluginTest.php b/tests/SweetAlert/Prime/SweetAlertPluginTest.php new file mode 100644 index 00000000..b356210d --- /dev/null +++ b/tests/SweetAlert/Prime/SweetAlertPluginTest.php @@ -0,0 +1,72 @@ +sweetAlertPlugin = new SweetAlertPlugin(); + } + + public function testGetAlias(): void + { + $this->assertSame('sweetalert', $this->sweetAlertPlugin->getAlias()); + } + + public function testGetFactory(): void + { + $this->assertSame(SweetAlert::class, $this->sweetAlertPlugin->getFactory()); + } + + public function testGetServiceAliases(): void + { + $this->assertSame(SweetAlertInterface::class, $this->sweetAlertPlugin->getServiceAliases()); + } + + public function testGetScripts(): void + { + $this->assertSame([ + '/vendor/flasher/sweetalert2.min.js', + '/vendor/flasher/flasher-sweetalert.min.js', + ], $this->sweetAlertPlugin->getScripts()); + } + + public function testGetStyles(): void + { + $this->assertSame(['/vendor/flasher/sweetalert2.min.css'], $this->sweetAlertPlugin->getStyles()); + } + + public function testGetName(): void + { + $this->assertSame('flasher_sweetalert', $this->sweetAlertPlugin->getName()); + } + + public function testGetServiceId(): void + { + $this->assertSame('flasher.sweetalert', $this->sweetAlertPlugin->getServiceId()); + } + + public function testNormalizeConfig(): void + { + $expected = [ + 'scripts' => [ + '/vendor/flasher/sweetalert2.min.js', + '/vendor/flasher/flasher-sweetalert.min.js', + ], + 'styles' => ['/vendor/flasher/sweetalert2.min.css'], + 'options' => [], + ]; + + $this->assertSame($expected, $this->sweetAlertPlugin->normalizeConfig([])); + } +} diff --git a/tests/SweetAlert/Prime/SweetAlertTest.php b/tests/SweetAlert/Prime/SweetAlertTest.php new file mode 100644 index 00000000..ee697d28 --- /dev/null +++ b/tests/SweetAlert/Prime/SweetAlertTest.php @@ -0,0 +1,39 @@ +createNotificationBuilder(); + + $this->assertInstanceOf(SweetAlertBuilder::class, $result); + } + + public function testSweetAlertBuilderTextMethod(): void + { + $storageManager = \Mockery::mock(StorageManagerInterface::class); + + $sweetAlert = new SweetAlert($storageManager); + + $builder = $sweetAlert->createNotificationBuilder(); + $response = $sweetAlert->target('#my-target'); + + $this->assertInstanceOf(SweetAlertBuilder::class, $response); + $this->assertInstanceOf(SweetAlertBuilder::class, $builder); + } +} diff --git a/tests/SweetAlert/Symfony/FlasherSweetAlertBundleTest.php b/tests/SweetAlert/Symfony/FlasherSweetAlertBundleTest.php new file mode 100644 index 00000000..2e027a0e --- /dev/null +++ b/tests/SweetAlert/Symfony/FlasherSweetAlertBundleTest.php @@ -0,0 +1,40 @@ +flasherSweetAlertBundle = new FlasherSweetAlertBundle(); + } + + public function testInstance(): void + { + $this->assertInstanceOf(PluginBundle::class, $this->flasherSweetAlertBundle); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(SweetAlertPlugin::class, $this->flasherSweetAlertBundle->createPlugin()); + } + + public function testGetConfigurationFileReturnsExpectedPath(): void + { + $expectedPath = $this->flasherSweetAlertBundle->getPath().'/Resources/config/config.yaml'; + + $this->assertSame($expectedPath, $this->flasherSweetAlertBundle->getConfigurationFile()); + } +} diff --git a/tests/Symfony/Command/InstallCommandTest.php b/tests/Symfony/Command/InstallCommandTest.php new file mode 100644 index 00000000..ac50d955 --- /dev/null +++ b/tests/Symfony/Command/InstallCommandTest.php @@ -0,0 +1,78 @@ +boot(); + + $this->configureCommandTester($kernel); + } + + public function testExecute(): void + { + $this->commandTester->execute([]); + + $output = $this->commandTester->getDisplay(); + + $this->assertStringContainsString('PHPFlasher resources have been successfully installed.', $output); + } + + public function testExecuteWithConfigOption(): void + { + $this->commandTester->execute([ + '--config' => true, + ]); + + $output = $this->commandTester->getDisplay(); + + $this->assertStringContainsString('Configuration files have been published.', $output); + } + + public function testExecuteWithSymlinkOption(): void + { + $this->commandTester->execute([ + '--symlink' => true, + ]); + + $output = $this->commandTester->getDisplay(); + + $this->assertStringContainsString('Assets were symlinked.', $output); + } + + public function testExecuteWithAllOptions(): void + { + $this->commandTester->execute([ + '--config' => true, + '--symlink' => true, + ]); + + $output = $this->commandTester->getDisplay(); + + $this->assertStringContainsString('PHPFlasher resources have been successfully installed.', $output); + $this->assertStringContainsString('Configuration files have been published.', $output); + $this->assertStringContainsString('Assets were symlinked.', $output); + } + + private function configureCommandTester(Kernel $kernel): void + { + $application = new Application($kernel); + $application->setCatchExceptions(false); + + $command = $application->find('flasher:install'); + $this->commandTester = new CommandTester($command); + } +} diff --git a/tests/Symfony/DependencyInjection/Compiler/EventListenerCompilerPassTest.php b/tests/Symfony/DependencyInjection/Compiler/EventListenerCompilerPassTest.php new file mode 100644 index 00000000..54d7ca82 --- /dev/null +++ b/tests/Symfony/DependencyInjection/Compiler/EventListenerCompilerPassTest.php @@ -0,0 +1,61 @@ +compilerPass = new EventListenerCompilerPass(); + $this->container = new ContainerBuilder(); + } + + /** + * Test process method with services tagged as 'flasher.event_listener'. + */ + public function testProcessWithTaggedServices(): void + { + $definition = new Definition(); + $this->container->setDefinition('flasher.event_dispatcher', $definition); + + $this->container->register('service1')->addTag('flasher.event_listener'); + $this->container->register('service2')->addTag('flasher.event_listener'); + + $this->compilerPass->process($this->container); + + $calls = $definition->getMethodCalls(); + $this->assertCount(2, $calls); + $this->assertSame('addListener', $calls[0][0]); + $this->assertInstanceOf(Reference::class, $calls[0][1][0]); + $this->assertSame('addListener', $calls[1][0]); + $this->assertInstanceOf(Reference::class, $calls[1][1][0]); + } + + /** + * Test process method with no services tagged as 'flasher.event_listener'. + */ + public function testProcessWithNoTaggedServices(): void + { + $definition = new Definition(); + $this->container->setDefinition('flasher.event_dispatcher', $definition); + + $this->compilerPass->process($this->container); + + $this->assertCount(0, $definition->getMethodCalls(), 'No method calls should be made when no tagged services exist.'); + } +} diff --git a/tests/Symfony/DependencyInjection/Compiler/PresenterCompilerPassTest.php b/tests/Symfony/DependencyInjection/Compiler/PresenterCompilerPassTest.php new file mode 100644 index 00000000..3ccd0f91 --- /dev/null +++ b/tests/Symfony/DependencyInjection/Compiler/PresenterCompilerPassTest.php @@ -0,0 +1,55 @@ +compilerPass = new PresenterCompilerPass(); + $this->container = new ContainerBuilder(); + } + + public function testProcessWithTaggedPresenters(): void + { + $definition = new Definition(); + $this->container->setDefinition('flasher.response_manager', $definition); + + // Register two services with the 'flasher.presenter' tag and custom attributes + $this->container->register('presenter1')->addTag('flasher.presenter', ['alias' => 'presenter1_alias']); + $this->container->register('presenter2')->addTag('flasher.presenter', ['alias' => 'presenter2_alias']); + + $this->compilerPass->process($this->container); + + $calls = $definition->getMethodCalls(); + $this->assertCount(2, $calls); + $this->assertSame('addPresenter', $calls[0][0]); + $this->assertSame('presenter1_alias', $calls[0][1][0]); + $this->assertInstanceOf(Reference::class, $calls[0][1][1]->getValues()[0]); + + $this->assertSame('addPresenter', $calls[1][0]); + $this->assertSame('presenter2_alias', $calls[1][1][0]); + $this->assertInstanceOf(Reference::class, $calls[1][1][1]->getValues()[0]); + } + + public function testProcessWithNoTaggedPresenters(): void + { + $definition = new Definition(); + $this->container->setDefinition('flasher.response_manager', $definition); + + $this->compilerPass->process($this->container); + + $this->assertCount(0, $definition->getMethodCalls(), 'No method calls should be made when no tagged services exist.'); + } +} diff --git a/tests/Symfony/DependencyInjection/ConfigurationTest.php b/tests/Symfony/DependencyInjection/ConfigurationTest.php new file mode 100644 index 00000000..9da8af47 --- /dev/null +++ b/tests/Symfony/DependencyInjection/ConfigurationTest.php @@ -0,0 +1,134 @@ + [ + 'default' => 'flasher', + 'main_script' => 'assets/flasher.js', + 'translate' => true, + 'inject_assets' => true, + 'filter' => ['limit' => 5], + ], + ]; + + $processedConfig = $this->processConfiguration($configs); + + $this->assertSame('flasher', $processedConfig['default']); + $this->assertSame('assets/flasher.js', $processedConfig['main_script']); + $this->assertTrue($processedConfig['translate']); + $this->assertTrue($processedConfig['inject_assets']); + $this->assertSame(['limit' => 5], $processedConfig['filter']); + } + + public function testConfigurationWithDefaults(): void + { + $configs = [ + 'flasher' => [], + ]; + + $processedConfig = $this->processConfiguration($configs); + + $this->assertSame('flasher', $processedConfig['default']); + $this->assertSame('/vendor/flasher/flasher.min.js', $processedConfig['main_script']); + $this->assertTrue($processedConfig['translate']); + $this->assertTrue($processedConfig['inject_assets']); + } + + public function testInvalidConfiguration(): void + { + $this->expectException(\Exception::class); + + $configs = [ + 'flasher' => [ + 'default' => null, + ], + ]; + + $this->processConfiguration($configs); + } + + public function testMergedConfiguration(): void + { + $configs = [ + 'flasher' => [ + 'main_script' => 'assets/flasher.js', + 'styles' => ['assets/flasher.css'], + ], + ]; + + $expectedConfig = [ + 'default' => 'flasher', + 'main_script' => 'assets/flasher.js', + 'scripts' => [], + 'styles' => ['assets/flasher.css'], + 'options' => [], + 'plugins' => [ + 'flasher' => [ + 'styles' => ['assets/flasher.css'], + 'scripts' => [], + 'options' => [], + ], + ], + 'translate' => true, + 'inject_assets' => true, + 'filter' => [], + 'presets' => [ + 'created' => [ + 'type' => 'success', + 'message' => 'The resource was created', + 'options' => [], + ], + 'updated' => [ + 'type' => 'success', + 'message' => 'The resource was updated', + 'options' => [], + ], + 'saved' => [ + 'type' => 'success', + 'message' => 'The resource was saved', + 'options' => [], + ], + 'deleted' => [ + 'type' => 'success', + 'message' => 'The resource was deleted', + 'options' => [], + ], + ], + 'flash_bag' => [ + 'success' => ['success'], + 'error' => ['error', 'danger'], + 'warning' => ['warning', 'alarm'], + 'info' => ['info', 'notice', 'alert'], + ], + ]; + + $processedConfig = $this->processConfiguration($configs); + + $this->assertEquals($expectedConfig, $processedConfig); + } + + /** + * @param array $configs + * + * @return array + */ + private function processConfiguration(array $configs): array + { + $processor = new Processor(); + $configuration = new Configuration(new FlasherPlugin()); + + return $processor->processConfiguration($configuration, $configs); + } +} diff --git a/tests/Symfony/DependencyInjection/FlasherExtensionTest.php b/tests/Symfony/DependencyInjection/FlasherExtensionTest.php new file mode 100644 index 00000000..c6dd0978 --- /dev/null +++ b/tests/Symfony/DependencyInjection/FlasherExtensionTest.php @@ -0,0 +1,97 @@ +container = new ContainerBuilder(); + $this->extension = new FlasherExtension(new FlasherPlugin()); + + $this->container->setParameter('kernel.environment', 'test'); + $this->container->setParameter('kernel.build_dir', __DIR__.'/../Fixtures/project/build'); + $this->container->setParameter('kernel.project_dir', __DIR__.'/../Fixtures/project'); + } + + public function testConfigurationIsLoadedAndParametersAreSet(): void + { + $config = [ + 'default' => 'flasher', + 'main_script' => 'assets/flasher.js', + 'inject_assets' => true, + ]; + + $this->extension->load([$config], $this->container); + + $this->assertSame('flasher', $this->container->getParameter('flasher.default')); + $this->assertTrue($this->container->getParameter('flasher.inject_assets')); + } + + public function testServiceDefinitionsAreRegistered(): void + { + $config = [ + 'default' => 'flasher', + 'main_script' => 'assets/flasher.js', + 'inject_assets' => true, + ]; + + $this->extension->load([$config], $this->container); + $this->extension->process($this->container); + + // Assert core services are registered + $this->assertTrue($this->container->has('flasher')); + $this->assertTrue($this->container->has('flasher.asset_manager')); + $this->assertTrue($this->container->has('flasher.event_dispatcher')); + } + + public function testAutoConfigurationAppliesTagsCorrectly(): void + { + $config = [ + 'inject_assets' => true, + ]; + + $this->extension->load([$config], $this->container); + $this->extension->process($this->container); + + $this->container->register('dummy.event_listener', \stdClass::class) + ->addTag('flasher.event_listener'); + + $this->extension->process($this->container); + + $tags = $this->container->getDefinition('dummy.event_listener')->getTags(); + $this->assertArrayHasKey('flasher.event_listener', $tags); + } + + public function testConditionalServiceRemoval(): void + { + $config = [ + 'default' => 'flasher', + 'inject_assets' => false, // This should lead to the removal of 'flasher.flasher_listener'. + 'flash_bag' => false, // This should affect session services. + ]; + + $this->extension->load([$config], $this->container); + $this->extension->process($this->container); + + // Assert that 'flasher.flasher_listener' is removed. + $this->assertFalse($this->container->has('flasher.flasher_listener')); + } + + public function testPluginNameAliasIsSetCorrectly(): void + { + $alias = $this->extension->getAlias(); + $this->assertSame('flasher', $alias); + } +} diff --git a/tests/Symfony/EventListener/FlasherListenerTest.php b/tests/Symfony/EventListener/FlasherListenerTest.php new file mode 100644 index 00000000..5d2c4d7c --- /dev/null +++ b/tests/Symfony/EventListener/FlasherListenerTest.php @@ -0,0 +1,54 @@ +responseExtensionMock = \Mockery::mock(ResponseExtensionInterface::class); + $this->flasherListener = new FlasherListener($this->responseExtensionMock); + } + + public function testOnKernelResponse(): void + { + $kernelMock = \Mockery::mock(HttpKernelInterface::class); + $requestMock = \Mockery::mock(SymfonyRequest::class); + $responseMock = \Mockery::mock(SymfonyResponse::class); + + $this->responseExtensionMock->expects() + ->render(\Mockery::type(RequestInterface::class), \Mockery::type(ResponseInterface::class)) + ->once(); + + $event = new ResponseEvent($kernelMock, $requestMock, HttpKernelInterface::MAIN_REQUEST, $responseMock); + $this->flasherListener->onKernelResponse($event); + } + + public function testGetSubscribedEvents(): void + { + $expectedEvents = [ResponseEvent::class => ['onKernelResponse', -256]]; + $subscribedEvents = FlasherListener::getSubscribedEvents(); + + // Verify that the FlasherListener is subscribed to the correct event and priority. + $this->assertSame($expectedEvents, $subscribedEvents); + } +} diff --git a/tests/Symfony/EventListener/SessionListenerTest.php b/tests/Symfony/EventListener/SessionListenerTest.php new file mode 100644 index 00000000..7d929a07 --- /dev/null +++ b/tests/Symfony/EventListener/SessionListenerTest.php @@ -0,0 +1,55 @@ +requestExtensionMock = \Mockery::mock(RequestExtensionInterface::class); + $this->sessionListener = new SessionListener($this->requestExtensionMock); + } + + public function testOnKernelResponse(): void + { + $kernelMock = \Mockery::mock(HttpKernelInterface::class); + $requestMock = \Mockery::mock(SymfonyRequest::class); + $responseMock = \Mockery::mock(SymfonyResponse::class); + + // Assuming the flash method does not return a value and is just called to perform an action. + $this->requestExtensionMock->expects() + ->flash(\Mockery::type(RequestInterface::class), \Mockery::type(ResponseInterface::class)) + ->once(); + + $event = new ResponseEvent($kernelMock, $requestMock, HttpKernelInterface::MAIN_REQUEST, $responseMock); + $this->sessionListener->onKernelResponse($event); + } + + public function testGetSubscribedEvents(): void + { + $expectedEvents = [ResponseEvent::class => ['onKernelResponse', 0]]; + $subscribedEvents = SessionListener::getSubscribedEvents(); + + // Verify that the SessionListener is subscribed to the correct event with the right priority. + $this->assertSame($expectedEvents, $subscribedEvents); + } +} diff --git a/tests/Symfony/Factory/NotificationFactoryLocatorTest.php b/tests/Symfony/Factory/NotificationFactoryLocatorTest.php new file mode 100644 index 00000000..7ee8c829 --- /dev/null +++ b/tests/Symfony/Factory/NotificationFactoryLocatorTest.php @@ -0,0 +1,74 @@ + */ + private MockInterface&ServiceLocator $serviceLocatorMock; + private NotificationFactoryLocator $notificationFactoryLocator; + + protected function setUp(): void + { + $this->serviceLocatorMock = \Mockery::mock(ServiceLocator::class); + $this->notificationFactoryLocator = new NotificationFactoryLocator($this->serviceLocatorMock); + } + + public function testHasReturnsFalseWhenServiceDoesNotExist(): void + { + $this->serviceLocatorMock->expects() + ->has('non_existing_service') + ->andReturns(false); + + $this->assertFalse($this->notificationFactoryLocator->has('non_existing_service')); + } + + public function testHasReturnsTrueWhenServiceExists(): void + { + $this->serviceLocatorMock + ->expects() + ->has('existing_service') + ->andReturns(true); + + $this->assertTrue($this->notificationFactoryLocator->has('existing_service')); + } + + public function testGetShouldReturnExistingNotificationFactoryInterface(): void + { + $notificationFactory = \Mockery::mock(NotificationFactoryInterface::class); + + $this->serviceLocatorMock + ->expects() + ->get('existing_service') + ->andReturns($notificationFactory); + + $actual = $this->notificationFactoryLocator->get('existing_service'); + + $this->assertSame($notificationFactory, $actual); + } + + public function testGetThrowsWhenServiceDoesNotExist(): void + { + $this->serviceLocatorMock + ->expects() + ->get('non_existing_service') + ->andThrow(new ServiceNotFoundException('non_existing_service')); + + $this->expectException(ServiceNotFoundException::class); + $this->expectExceptionMessage('non_existing_service'); + + $this->notificationFactoryLocator->get('non_existing_service'); + } +} diff --git a/tests/Symfony/Fixtures/FlasherKernel.php b/tests/Symfony/Fixtures/FlasherKernel.php new file mode 100644 index 00000000..41f3d2a0 --- /dev/null +++ b/tests/Symfony/Fixtures/FlasherKernel.php @@ -0,0 +1,73 @@ +load(function (ContainerBuilder $container): void { + $container->register('kernel', static::class) + ->setPublic(true); + + $this->configureContainer($container); + $container->addObjectResource($this); + }); + } + + public function configureContainer(ContainerBuilder $container): void + { + $container->loadFromExtension('framework', [ + 'secret' => 'foo', + 'test' => true, + 'session' => [ + 'handler_id' => null, + 'storage_factory_id' => 'session.storage.factory.mock_file', + ], + ]); + + $container->loadFromExtension('twig', [ + 'debug' => true, + 'strict_variables' => true, + ]); + } + + public function getProjectDir(): string + { + return __DIR__.'/project'; + } + + public function getCacheDir(): string + { + return sys_get_temp_dir().'/cache'.spl_object_hash($this); + } + + public function getLogDir(): string + { + return sys_get_temp_dir().'/logs'.spl_object_hash($this); + } +} diff --git a/src/Cli/Prime/Resources/bin/toaster/Microsoft.WindowsAPICodePack.dll b/tests/Symfony/Fixtures/project/public/.gitkeep similarity index 100% rename from src/Cli/Prime/Resources/bin/toaster/Microsoft.WindowsAPICodePack.dll rename to tests/Symfony/Fixtures/project/public/.gitkeep diff --git a/tests/Symfony/FlasherBundleTest.php b/tests/Symfony/FlasherBundleTest.php index 2b7bf487..87e55ad2 100644 --- a/tests/Symfony/FlasherBundleTest.php +++ b/tests/Symfony/FlasherBundleTest.php @@ -1,36 +1,69 @@ - */ +declare(strict_types=1); namespace Flasher\Tests\Symfony; -use Flasher\Symfony\Bridge\Bridge; +use Flasher\Prime\Plugin\FlasherPlugin; +use Flasher\Symfony\FlasherBundle; +use Flasher\Tests\Symfony\Fixtures\FlasherKernel; +use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -class FlasherBundleTest extends TestCase +final class FlasherBundleTest extends TestCase { - public function testFlasherIntegration() - { - if (Bridge::versionCompare('2.1', '<')) { - self::markTestSkipped('ErrorException: 8192: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/RegisterKernelListenersPass.php line 39'); - } + use MockeryPHPUnitIntegration; - $container = $this->getContainer(); + private FlasherBundle $flasherBundle; + + protected function setUp(): void + { + $this->flasherBundle = new FlasherBundle(); + } + + public function testFlasherIntegration(): void + { + $kernel = new FlasherKernel(); + $kernel->boot(); + + $container = $kernel->getContainer(); $this->assertTrue($container->has('flasher')); $this->assertTrue($container->has('flasher.noty')); $this->assertTrue($container->has('flasher.notyf')); - $this->assertTrue($container->has('flasher.pnotify')); $this->assertTrue($container->has('flasher.sweetalert')); $this->assertTrue($container->has('flasher.toastr')); - $this->assertInstanceOf('Flasher\Prime\Flasher', $container->get('flasher')); - $this->assertInstanceOf('Flasher\Noty\Prime\NotyFactory', $container->get('flasher.noty')); - $this->assertInstanceOf('Flasher\Notyf\Prime\NotyfFactory', $container->get('flasher.notyf')); - $this->assertInstanceOf('Flasher\Pnotify\Prime\PnotifyFactory', $container->get('flasher.pnotify')); - $this->assertInstanceOf('Flasher\SweetAlert\Prime\SweetAlertFactory', $container->get('flasher.sweetalert')); - $this->assertInstanceOf('Flasher\Toastr\Prime\ToastrFactory', $container->get('flasher.toastr')); + $this->assertInstanceOf(\Flasher\Prime\FlasherInterface::class, $container->get('flasher')); + $this->assertInstanceOf(\Flasher\Noty\Prime\NotyInterface::class, $container->get('flasher.noty')); + $this->assertInstanceOf(\Flasher\Notyf\Prime\NotyfInterface::class, $container->get('flasher.notyf')); + $this->assertInstanceOf(\Flasher\SweetAlert\Prime\SweetAlertInterface::class, $container->get('flasher.sweetalert')); + $this->assertInstanceOf(\Flasher\Toastr\Prime\ToastrInterface::class, $container->get('flasher.toastr')); + } + + public function testBuild(): void + { + $containerBuilder = \Mockery::mock(ContainerBuilder::class); + $containerBuilder->expects('addCompilerPass') + ->twice() + ->andReturns($containerBuilder); + + $this->flasherBundle->build($containerBuilder); + } + + public function testGetContainerExtension(): void + { + $containerExtension = $this->flasherBundle->getContainerExtension(); + + $this->assertInstanceOf(ExtensionInterface::class, $containerExtension); + } + + public function testCreatePlugin(): void + { + $flasherPlugin = $this->flasherBundle->createPlugin(); + + $this->assertInstanceOf(FlasherPlugin::class, $flasherPlugin); } } diff --git a/tests/Symfony/FlasherKernel.php b/tests/Symfony/FlasherKernel.php deleted file mode 100644 index 8cd90147..00000000 --- a/tests/Symfony/FlasherKernel.php +++ /dev/null @@ -1,152 +0,0 @@ - - */ - -namespace Flasher\Tests\Symfony; - -use Flasher\Noty\Symfony\FlasherNotySymfonyBundle; -use Flasher\Notyf\Symfony\FlasherNotyfSymfonyBundle; -use Flasher\Pnotify\Symfony\FlasherPnotifySymfonyBundle; -use Flasher\SweetAlert\Symfony\FlasherSweetAlertSymfonyBundle; -use Flasher\Symfony\Bridge\Bridge; -use Flasher\Symfony\FlasherSymfonyBundle; -use Flasher\Toastr\Symfony\FlasherToastrSymfonyBundle; -use Symfony\Bundle\FrameworkBundle\FrameworkBundle; -use Symfony\Bundle\TwigBundle\TwigBundle; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpKernel\Kernel; -use Symfony\Component\Routing\RouteCollectionBuilder; - -abstract class AbstractFlasherKernel extends Kernel -{ - public function __construct() - { - parent::__construct('test', true); - } - - public function doRegisterBundles() - { - return array( - new FrameworkBundle(), - new TwigBundle(), - new FlasherSymfonyBundle(), - new FlasherNotySymfonyBundle(), - new FlasherNotyfSymfonyBundle(), - new FlasherPnotifySymfonyBundle(), - new FlasherSweetAlertSymfonyBundle(), - new FlasherToastrSymfonyBundle(), - ); - } - - public function configureContainer(ContainerBuilder $container, LoaderInterface $loader) - { - $framework = array( - 'secret' => 'foo', - 'test' => true, - 'session' => array('handler_id' => null, 'storage_factory_id' => 'session.storage.factory.mock_file'), - 'router' => array('resource' => 'kernel:loadRoutes', 'type' => 'service'), - ); - - if (Bridge::versionCompare('6.0', '<')) { - unset($framework['session']); - $framework['session']['storage_id'] = 'session.storage.filesystem'; - } - - if (Bridge::versionCompare('3', '<')) { - $framework['templating']['engines'] = 'twig'; - } - - $container->loadFromExtension('framework', $framework); - - $twig = array('debug' => true, 'strict_variables' => true); - $container->loadFromExtension('twig', $twig); - } - - public function doGetCacheDir() - { - return sys_get_temp_dir().'/cache'.spl_object_hash($this); - } - - public function doGetLogDir() - { - return sys_get_temp_dir().'/logs'.spl_object_hash($this); - } - - /** - * {@inheritDoc} - */ - public function registerContainerConfiguration(LoaderInterface $loader) - { - $that = $this; - $loader->load(function (ContainerBuilder $container) use ($loader, $that) { - if ($that instanceof EventSubscriberInterface) { - $class = get_class($that); - $container->register('kernel', $class) - ->setSynthetic(true) - ->setPublic(true) - ->addTag('kernel.event_subscriber') - ; - } - - $that->configureContainer($container, $loader); - - $container->addObjectResource($that); - }); - } - - protected function configureRoutes(RouteCollectionBuilder $routes) - { - } -} - -if (Bridge::versionCompare('6.0', '>=')) { - eval(' - namespace Flasher\Tests\Symfony; - - class FlasherKernel extends AbstractFlasherKernel - { - public function registerBundles(): iterable - { - return $this->doRegisterBundles(); - } - - public function getCacheDir(): string - { - return $this->doGetLogDir(); - } - - public function getLogDir(): string - { - return $this->doGetLogDir(); - } - - public function getProjectDir(): string - { - return \dirname(__DIR__); - } - } - '); -} else { - class FlasherKernel extends AbstractFlasherKernel - { - public function registerBundles() - { - return $this->doRegisterBundles(); - } - - public function getCacheDir() - { - return $this->doGetLogDir(); - } - - public function getLogDir() - { - return $this->doGetLogDir(); - } - } -} diff --git a/tests/Symfony/Http/RequestTest.php b/tests/Symfony/Http/RequestTest.php new file mode 100644 index 00000000..49111530 --- /dev/null +++ b/tests/Symfony/Http/RequestTest.php @@ -0,0 +1,161 @@ +symfonyRequestMock = \Mockery::mock(SymfonyRequest::class); + } + + public static function xmlHttpRequestProvider(): \Iterator + { + yield 'XML HTTP Request' => [true]; + yield 'Not XML HTTP Request' => [false]; + } + + #[DataProvider('xmlHttpRequestProvider')] + public function testIsXmlHttpRequest(bool $isXmlHttpRequest): void + { + $this->symfonyRequestMock->expects('isXmlHttpRequest')->once()->andReturns($isXmlHttpRequest); + + $request = new Request($this->symfonyRequestMock); + + $this->assertSame($isXmlHttpRequest, $request->isXmlHttpRequest()); + } + + /** + * Test isHtmlRequestFormat method. + */ + public function testIsHtmlRequestFormat(): void + { + $this->symfonyRequestMock->expects('getRequestFormat')->once()->andReturns('html'); + + $request = new Request($this->symfonyRequestMock); + + $this->assertTrue($request->isHtmlRequestFormat()); + } + + /** + * Test hasSession method. + */ + public function testHasSession(): void + { + $this->symfonyRequestMock->expects('hasSession')->andReturns(true); + + $request = new Request($this->symfonyRequestMock); + + $this->assertTrue($request->hasSession()); + } + + public static function sessionStatusProvider(): \Iterator + { + yield 'Session Started' => [true]; + yield 'Session Not Started' => [false]; + yield 'No Session' => [false]; + } + + /** + * Test getSession method. + */ + #[DataProvider('sessionStatusProvider')] + public function testIsSessionStarted(bool $isStarted): void + { + $sessionMock = \Mockery::mock(SessionInterface::class); + $sessionMock->expects()->isStarted()->andReturns($isStarted); + + $this->symfonyRequestMock->expects()->getSession()->andReturns($sessionMock); + + $request = new Request($this->symfonyRequestMock); + $this->assertSame($isStarted, $request->isSessionStarted()); + } + + /** + * Test hasType method. + */ + public function testHasType(): void + { + $type = 'info'; + + $flashBagMock = \Mockery::mock(FlashBagInterface::class); + $flashBagMock->expects()->has($type)->andReturns(true); + + $sessionMock = \Mockery::mock(FlashBagAwareSessionInterface::class); + $sessionMock->expects()->getFlashBag()->andReturns($flashBagMock); + $sessionMock->expects()->isStarted()->andReturnTrue(); + + $this->symfonyRequestMock->expects()->getSession()->twice()->andReturns($sessionMock); + $this->symfonyRequestMock->expects()->hasSession()->once()->andReturnTrue(); + + $request = new Request($this->symfonyRequestMock); + $this->assertTrue($request->hasType($type)); + } + + public function testGetType(): void + { + $expected = ['message']; + + $flashBagMock = \Mockery::mock(FlashBagInterface::class); + $flashBagMock->expects()->get('info')->andReturns($expected); + + $sessionMock = \Mockery::mock(FlashBagAwareSessionInterface::class); + $sessionMock->expects()->getFlashBag()->andReturns($flashBagMock); + + $this->symfonyRequestMock->expects()->getSession()->once()->andReturns($sessionMock); + + $request = new Request($this->symfonyRequestMock); + + $this->assertSame($expected, $request->getType('info')); + } + + /** + * Test hasHeader method. + */ + public function testHasHeader(): void + { + $headersMock = \Mockery::mock(HeaderBag::class); + $headersMock->expects()->has('Authorization')->andReturns('Bearer token'); + + $this->symfonyRequestMock->headers = $headersMock; + + $request = new Request($this->symfonyRequestMock); + + $this->assertTrue($request->hasHeader('Authorization')); + } + + /** + * Test getHeader method. + */ + public function testGetHeader(): void + { + $headersMock = \Mockery::mock(HeaderBag::class); + $headersMock->expects('get')->with('Authorization')->andReturns('Bearer token'); + + $this->symfonyRequestMock->headers = $headersMock; + + $request = new Request($this->symfonyRequestMock); + + $this->assertSame('Bearer token', $request->getHeader('Authorization')); + } +} diff --git a/tests/Symfony/Http/ResponseTest.php b/tests/Symfony/Http/ResponseTest.php new file mode 100644 index 00000000..c7570510 --- /dev/null +++ b/tests/Symfony/Http/ResponseTest.php @@ -0,0 +1,133 @@ +responseHeaderBagMock = \Mockery::mock(ResponseHeaderBag::class); + + $this->responseMock = \Mockery::mock(SymfonyResponse::class); + $this->responseMock->headers = $this->responseHeaderBagMock; + } + + public function testIsRedirection(): void + { + $this->responseMock->expects()->isRedirection()->andReturns(true); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isRedirection()); + } + + public function testIsJson(): void + { + $jsonResponseMock = \Mockery::mock(JsonResponse::class); + + $response = new Response($jsonResponseMock); + + $this->assertTrue($response->isJson()); + } + + public function testIsHtml(): void + { + $this->responseHeaderBagMock->expects()->get('Content-Type')->andReturns('text/html; charset=UTF-8'); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isHtml()); + } + + public function testIsAttachment(): void + { + $this->responseHeaderBagMock->expects()->get('Content-Disposition', '')->andReturns('attachment; filename="filename.jpg"'); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isAttachment()); + } + + public function testIsSuccessful(): void + { + $this->responseMock->expects()->isSuccessful()->andReturns(true); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->isSuccessful()); + } + + public function testGetContent(): void + { + $expectedContent = 'response content'; + $this->responseMock->expects()->getContent()->andReturns($expectedContent); + + $response = new Response($this->responseMock); + + $this->assertSame($expectedContent, $response->getContent()); + } + + public function testSetContent(): void + { + $newContent = 'new content'; + $this->responseMock->expects()->setContent($newContent); + + $response = new Response($this->responseMock); + $response->setContent($newContent); + } + + public function testHasHeader(): void + { + $headerKey = 'X-Custom-Header'; + $this->responseHeaderBagMock->expects()->has($headerKey)->andReturns(true); + + $response = new Response($this->responseMock); + + $this->assertTrue($response->hasHeader($headerKey)); + } + + public function testGetHeader(): void + { + $headerKey = 'X-Custom-Header'; + $headerValue = 'Value'; + $this->responseHeaderBagMock->expects()->get($headerKey)->andReturns($headerValue); + + $response = new Response($this->responseMock); + + $this->assertSame($headerValue, $response->getHeader($headerKey)); + } + + public function testSetHeader(): void + { + $headerKey = 'X-Custom-Header'; + $headerValue = 'Value'; + $this->responseHeaderBagMock->expects()->set($headerKey, $headerValue); + + $response = new Response($this->responseMock); + $response->setHeader($headerKey, $headerValue); + } + + public function testRemoveHeader(): void + { + $headerKey = 'X-Custom-Header'; + $this->responseHeaderBagMock->expects()->remove($headerKey); + + $response = new Response($this->responseMock); + $response->removeHeader($headerKey); + } +} diff --git a/tests/Symfony/Storage/FallbackSessionTest.php b/tests/Symfony/Storage/FallbackSessionTest.php new file mode 100644 index 00000000..b8c199e4 --- /dev/null +++ b/tests/Symfony/Storage/FallbackSessionTest.php @@ -0,0 +1,48 @@ +session = new FallbackSession(); + } + + public function testGetReturnsSetValue(): void + { + $this->session->set('test_name', 'test_value'); + $value = $this->session->get('test_name'); + $this->assertSame('test_value', $value); + } + + public function testGetReturnsDefaultValueIfNameNotExists(): void + { + $value = $this->session->get('not_existing_name', 'default_value'); + $this->assertSame('default_value', $value); + } + + public function testGetReturnsNullIfNameNotExistsAndNoDefaultValueProvided(): void + { + $value = $this->session->get('not_existing_name'); + $this->assertNull($value); + } + + public function testSetStoresValueInSession(): void + { + $this->session->set('test_name', 'test_value'); + $value = $this->session->get('test_name', 'default_value'); + $this->assertSame('test_value', $value); + } +} diff --git a/tests/Symfony/Storage/SessionBagTest.php b/tests/Symfony/Storage/SessionBagTest.php new file mode 100644 index 00000000..8928d97c --- /dev/null +++ b/tests/Symfony/Storage/SessionBagTest.php @@ -0,0 +1,84 @@ +requestStackMock = \Mockery::mock(RequestStack::class); + $this->fallbackSessionMock = \Mockery::mock(FallbackSessionInterface::class); + $this->sessionBag = new SessionBag($this->requestStackMock, $this->fallbackSessionMock); + } + + public function testGet(): void + { + $sessionMock = \Mockery::mock(SessionInterface::class); + $sessionMock->expects('get')->andReturns([new Envelope(new Notification(), new IdStamp('1111'))]); + + $parameterBagMock = \Mockery::mock(ParameterBag::class); + $parameterBagMock->expects()->get('_stateless', false)->andReturns(false); + + $requestMock = \Mockery::mock(SymfonyRequest::class); + $requestMock->attributes = $parameterBagMock; + + $this->requestStackMock->expects()->getCurrentRequest()->andReturns($requestMock); + $this->requestStackMock->expects()->getSession()->andReturns($sessionMock); + + $result = $this->sessionBag->get(); + + $this->assertIsArray($result); + $this->assertInstanceOf(Envelope::class, $result[0]); + } + + public function testSet(): void + { + $sessionMock = \Mockery::mock(SessionInterface::class); + $sessionMock->expects('set'); + + $parameterBagMock = \Mockery::mock(ParameterBag::class); + $parameterBagMock->expects()->get('_stateless', false)->andReturns(false); + + $requestMock = \Mockery::mock(SymfonyRequest::class); + $requestMock->attributes = $parameterBagMock; + + $this->requestStackMock->expects()->getCurrentRequest()->andReturns($requestMock); + $this->requestStackMock->expects()->getSession()->andReturns($sessionMock); + + $this->sessionBag->set([]); + } + + public function testFallbackSession(): void + { + $this->fallbackSessionMock->allows('get') + ->andReturns([new Envelope(new Notification(), new IdStamp('1111'))]); + + $this->requestStackMock->expects()->getCurrentRequest()->andReturns(null); + + $result = $this->sessionBag->get(); + + $this->assertIsArray($result); + $this->assertInstanceOf(Envelope::class, $result[0]); + } +} diff --git a/tests/Symfony/StorageTest.php b/tests/Symfony/StorageTest.php deleted file mode 100644 index 60132da1..00000000 --- a/tests/Symfony/StorageTest.php +++ /dev/null @@ -1,167 +0,0 @@ - - */ - -namespace Flasher\Tests\Symfony; - -use Flasher\Prime\Notification\Envelope; -use Flasher\Prime\Notification\Notification; -use Flasher\Prime\Stamp\PriorityStamp; -use Flasher\Prime\Stamp\UuidStamp; -use Flasher\Prime\Storage\StorageBag; -use Flasher\Symfony\Storage\SessionBag; -use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; -use Symfony\Component\HttpFoundation\SessionStorage\ArraySessionStorage; - -class StorageTest extends TestCase -{ - /** - * @return void - */ - public function testInitialState() - { - $storage = $this->getStorage(); - $this->assertEquals(array(), $storage->all()); - } - - /** - * @return void - */ - public function testAddEnvelope() - { - $uuid = new UuidStamp(); - $envelope = new Envelope(new Notification()); - $envelope->withStamp($uuid); - - $storage = $this->getStorage(); - $storage->add($envelope); - - $this->assertEquals(array($envelope), $storage->all()); - } - - /** - * @return void - */ - public function testAddMultipleEnvelopes() - { - $envelopes = array( - new Envelope(new Notification()), - new Envelope(new Notification()), - ); - - $storage = $this->getStorage(); - $storage->add($envelopes); - - $this->assertEquals($envelopes, $storage->all()); - } - - /** - * @return void - */ - public function testUpdateEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $envelopes[1]->withStamp(new PriorityStamp(1)); - $storage->update($envelopes[1]); - - $this->assertEquals($envelopes, $storage->all()); - $this->assertInstanceOf( - 'Flasher\Prime\Stamp\PriorityStamp', - $envelopes[1]->get('Flasher\Prime\Stamp\PriorityStamp') - ); - } - - /** - * @return void - */ - public function testRemoveEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $storage->remove($envelopes[1]); - $this->assertEquals(array($envelopes[0]), $storage->all()); - } - - /** - * @return void - */ - public function testRemoveMultipleEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $storage->remove($envelopes); - $this->assertEquals(array(), $storage->all()); - } - - /** - * @return void - */ - public function testClearAllEnvelopes() - { - $storage = $this->getStorage(); - $envelopes = array( - new Envelope(new Notification(), array( - new UuidStamp(), - )), - new Envelope(new Notification(), array( - new UuidStamp(), - )), - ); - - $storage->add($envelopes); - $this->assertEquals($envelopes, $storage->all()); - - $storage->clear(); - $this->assertEquals(array(), $storage->all()); - } - - /** - * @return StorageBag - */ - private function getStorage() - { - $session = class_exists('Symfony\Component\HttpFoundation\Session\Session') - ? new Session(new MockArraySessionStorage()) - : new \Symfony\Component\HttpFoundation\Session(new ArraySessionStorage()); // @phpstan-ignore-line - - return new StorageBag(new SessionBag($session)); // @phpstan-ignore-line - } -} diff --git a/tests/Symfony/Template/TwigTemplateEngineTest.php b/tests/Symfony/Template/TwigTemplateEngineTest.php new file mode 100644 index 00000000..d27c70cc --- /dev/null +++ b/tests/Symfony/Template/TwigTemplateEngineTest.php @@ -0,0 +1,43 @@ + 'Hello {{ name }}!']); + + $twig = new Environment($loader); + + $templateEngine = new TwigTemplateEngine($twig); + + $actual = $templateEngine->render('templateName', ['name' => 'John Doe']); + + $this->assertSame('Hello John Doe!', $actual); + } + + /** + * This test case covers the `render` method of the `TwigTemplateEngine` class. + * If Twig environment is null, a LogicException should be thrown. + */ + public function testRenderThrowsLogicExceptionWithNullTwigEnvironment(): void + { + $this->expectException(\LogicException::class); + + $templateEngineWithoutTwig = new TwigTemplateEngine(null); + + $templateEngineWithoutTwig->render('templateName', ['name' => 'John Doe']); + } +} diff --git a/tests/Symfony/TestCase.php b/tests/Symfony/TestCase.php deleted file mode 100644 index 8947f470..00000000 --- a/tests/Symfony/TestCase.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - -namespace Flasher\Tests\Symfony; - -use Flasher\Symfony\Bridge\Bridge; - -class TestCase extends \Flasher\Tests\Prime\TestCase -{ - protected function getContainer() - { - $kernel = new FlasherKernel(); - $kernel->boot(); - - if (Bridge::versionCompare('4.1', '>=')) { - return $kernel->getContainer()->get('test.service_container'); - } - - return $kernel->getContainer(); - } -} diff --git a/tests/Symfony/Translation/TranslatorTest.php b/tests/Symfony/Translation/TranslatorTest.php new file mode 100644 index 00000000..5135db12 --- /dev/null +++ b/tests/Symfony/Translation/TranslatorTest.php @@ -0,0 +1,76 @@ +symfonyTranslatorMock = \Mockery::mock(SymfonyTranslatorInterface::class); + if (interface_exists(TranslatorBagInterface::class)) { + $this->symfonyTranslatorMock->allows('getCatalogue')->andReturnUndefined(); + } + } + + public function testTranslateWithoutTranslatorBagInterface(): void + { + $this->symfonyTranslatorMock->expects('trans') + ->with('key', ['some_param' => 1], 'flasher', null) + ->andReturns('translation'); + + $translator = new Translator($this->symfonyTranslatorMock); + $this->assertSame('translation', $translator->translate('key', ['some_param' => 1])); + } + + public function testTranslateWithTranslatorBagInterfaceAndExistingTranslation(): void + { + $messageCatalogMock = \Mockery::mock(MessageCatalogueInterface::class); + $messageCatalogMock->allows('has')->with('key', 'flasher')->andReturnTrue(); + + $this->symfonyTranslatorMock->allows('getCatalogue')->andReturns($messageCatalogMock); + $this->symfonyTranslatorMock->allows('trans')->with('key', ['some_param' => 1], 'flasher', null)->andReturns('translation'); + + $translator = new Translator($this->symfonyTranslatorMock); + $this->assertSame('translation', $translator->translate('key', ['some_param' => 1])); + } + + public function testTranslateWithTranslatorBagInterfaceAndNonExistingTranslation(): void + { + $this->symfonyTranslatorMock->allows('getCatalogue') + ->andReturnUsing(function () { + $messageCatalogMock = \Mockery::mock(MessageCatalogueInterface::class); + $messageCatalogMock->allows('has')->andReturnFalse(); + + return $messageCatalogMock; + }); + + $this->symfonyTranslatorMock->allows('trans') + ->with('key', ['some_param' => 1], 'flasher', null) + ->andReturns('key'); + + $translator = new Translator($this->symfonyTranslatorMock); + $this->assertSame('key', $translator->translate('key', ['some_param' => 1])); + } + + public function testGetLocale(): void + { + $this->symfonyTranslatorMock->allows('getLocale')->andReturns('en_US'); + + $translator = new Translator($this->symfonyTranslatorMock); + $this->assertSame('en_US', str_replace('_POSIX', '', $translator->getLocale())); + } +} diff --git a/tests/Symfony/TranslatorTest.php b/tests/Symfony/TranslatorTest.php deleted file mode 100644 index cab6d470..00000000 --- a/tests/Symfony/TranslatorTest.php +++ /dev/null @@ -1,40 +0,0 @@ - - */ - -namespace Flasher\Tests\Symfony; - -use Flasher\Symfony\Translation\Translator; - -class TranslatorTest extends TestCase -{ - /** - * @return void - */ - public function testInitialState() - { - $translator = $this->getTranslator(); - - $this->assertEquals('en', $translator->getLocale()); - } - - /** - * @return Translator - */ - private function getTranslator() - { - $messageFormatter = null; - if (class_exists('Symfony\Component\Translation\Formatter\MessageFormatter')) { - $messageFormatter = new \Symfony\Component\Translation\Formatter\MessageFormatter(); - } elseif (class_exists('Symfony\Component\Translation\MessageSelector')) { - $messageFormatter = new \Symfony\Component\Translation\MessageSelector(); - } - - $symfonyTranslator = new \Symfony\Component\Translation\Translator('en', $messageFormatter); - - return new Translator($symfonyTranslator); - } -} diff --git a/tests/Symfony/Twig/FlasherTwigExtensionTest.php b/tests/Symfony/Twig/FlasherTwigExtensionTest.php new file mode 100644 index 00000000..84229848 --- /dev/null +++ b/tests/Symfony/Twig/FlasherTwigExtensionTest.php @@ -0,0 +1,80 @@ +flasher = \Mockery::mock(FlasherInterface::class); + $this->extension = new FlasherTwigExtension($this->flasher); + } + + protected function tearDown(): void + { + \Mockery::close(); + } + + /** + * Tests the getFunctions method. + * Ensures the method returns an array of TwigFunction instances. + */ + public function testGetFunctions(): void + { + $functions = $this->extension->getFunctions(); + + $this->assertIsArray($functions); + $this->assertCount(1, $functions); + $this->assertInstanceOf(TwigFunction::class, $functions[0]); + $this->assertSame('flasher_render', $functions[0]->getName()); + } + + /** + * Tests the render method when called without any criteria, presenter or context. + * Ensures the render method forwards the call to the FlasherInterface's render method with default arguments. + */ + public function testRenderWithoutArguments(): void + { + $this->flasher->expects() + ->render('html', [], []) + ->once() + ->andReturn('Rendered content'); + + $result = $this->extension->render(); + $this->assertSame('Rendered content', $result); + } + + /** + * Tests the render method when called with specific criteria, presenter and context. + * Ensures the render method forwards the call to the FlasherInterface's render method with the provided arguments. + */ + public function testRenderWithArguments(): void + { + $criteria = ['type' => 'info']; + $presenter = 'json'; + $context = ['option' => 'value']; + + $this->flasher->expects() + ->render($presenter, $criteria, $context) + ->once() + ->andReturn('Rendered content'); + + $result = $this->extension->render($criteria, $presenter, $context); + $this->assertSame('Rendered content', $result); + } +} diff --git a/tests/Toastr/Laravel/FlasherToastrServiceProviderTest.php b/tests/Toastr/Laravel/FlasherToastrServiceProviderTest.php new file mode 100644 index 00000000..e19193ba --- /dev/null +++ b/tests/Toastr/Laravel/FlasherToastrServiceProviderTest.php @@ -0,0 +1,78 @@ +app = \Mockery::mock(Application::class); + $this->serviceProvider = new FlasherToastrServiceProvider($this->app); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(ToastrPlugin::class, $this->serviceProvider->createPlugin()); + } + + public function testRegister(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('configurationIsCached')->never(); + + $this->serviceProvider->register(); + $this->addToAssertionCount(1); + } + + public function testBoot(): void + { + $this->app->expects()->make('config')->andReturns($configMock = \Mockery::mock(Repository::class)); + $configMock->expects('get')->andReturns([]); + $configMock->expects('set'); + + $this->app->expects('singleton'); + $this->app->expects('alias'); + $this->app->expects('extend'); + + $this->serviceProvider->register(); + $this->serviceProvider->boot(); + $this->addToAssertionCount(1); + } + + public function testGetConfigurationFile(): void + { + $expectedPath = $this->getResourcesPathFromServiceProvider(); + $this->assertStringEndsWith('/Resources/config.php', $this->serviceProvider->getConfigurationFile()); + $this->assertStringContainsString($expectedPath, $this->serviceProvider->getConfigurationFile()); + } + + private function getResourcesPathFromServiceProvider(): string + { + $reflection = new \ReflectionClass(FlasherToastrServiceProvider::class); + $method = $reflection->getMethod('getResourcesDir'); + $method->setAccessible(true); + + /** @var string $string */ + $string = $method->invoke($this->serviceProvider); + + return rtrim($string, '/').'/'; + } +} diff --git a/tests/Toastr/Prime/ToastrBuilderTest.php b/tests/Toastr/Prime/ToastrBuilderTest.php new file mode 100644 index 00000000..86e721c0 --- /dev/null +++ b/tests/Toastr/Prime/ToastrBuilderTest.php @@ -0,0 +1,350 @@ +toastrBuilder = new ToastrBuilder('toastr', $storageManagerMock); + } + + public function testCloseButton(): void + { + $this->toastrBuilder->closeButton(true); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeButton' => true], $options); + } + + public function testCloseClass(): void + { + $this->toastrBuilder->closeClass('.close'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeClass' => '.close'], $options); + } + + public function testCloseDuration(): void + { + $this->toastrBuilder->closeDuration(6000); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeDuration' => 6000], $options); + } + + public function testCloseEasing(): void + { + $this->toastrBuilder->closeEasing('closing'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeEasing' => 'closing'], $options); + } + + public function testCloseHtml(): void + { + $this->toastrBuilder->closeHtml(''); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeHtml' => ''], $options); + } + + public function testCloseMethod(): void + { + $this->toastrBuilder->closeMethod('fadeOut'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeMethod' => 'fadeOut'], $options); + } + + public function testCloseOnHover(): void + { + $this->toastrBuilder->closeOnHover(false); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['closeOnHover' => false], $options); + } + + public function testContainerId(): void + { + $this->toastrBuilder->containerId('myContainer'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['containerId' => 'myContainer'], $options); + } + + public function testDebug(): void + { + $this->toastrBuilder->debug(false); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['debug' => false], $options); + } + + public function testEscapeHtml(): void + { + $this->toastrBuilder->escapeHtml(false); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['escapeHtml' => false], $options); + } + + public function testExtendedTimeOut(): void + { + $this->toastrBuilder->extendedTimeOut(10000); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['extendedTimeOut' => 10000], $options); + } + + public function testHideDuration(): void + { + $this->toastrBuilder->hideDuration(3000); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['hideDuration' => 3000], $options); + } + + public function testHideEasing(): void + { + $this->toastrBuilder->hideEasing('linear'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['hideEasing' => 'linear'], $options); + } + + public function testHideMethod(): void + { + $this->toastrBuilder->hideMethod('slideUp'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['hideMethod' => 'slideUp'], $options); + } + + public function testIconClass(): void + { + $this->toastrBuilder->iconClass('icon-info'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['iconClass' => 'icon-info'], $options); + } + + public function testMessageClass(): void + { + $this->toastrBuilder->messageClass('message-info'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['messageClass' => 'message-info'], $options); + } + + public function testNewestOnTop(): void + { + $this->toastrBuilder->newestOnTop(false); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['newestOnTop' => false], $options); + } + + public function testOnHidden(): void + { + $this->toastrBuilder->onHidden('hiddenCallback'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['onHidden' => 'hiddenCallback'], $options); + } + + public function testOnShown(): void + { + $this->toastrBuilder->onShown('shownCallback'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['onShown' => 'shownCallback'], $options); + } + + public function testPositionClass(): void + { + $this->toastrBuilder->positionClass('toast-top-right'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['positionClass' => 'toast-top-right'], $options); + } + + public function testPreventDuplicates(): void + { + $this->toastrBuilder->preventDuplicates(); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['preventDuplicates' => true], $options); + } + + public function testProgressBar(): void + { + $this->toastrBuilder->progressBar(); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['progressBar' => true], $options); + } + + public function testProgressClass(): void + { + $this->toastrBuilder->progressClass('progress-info'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['progressClass' => 'progress-info'], $options); + } + + public function testRtl(): void + { + $this->toastrBuilder->rtl(true); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['rtl' => true], $options); + } + + public function testShowDuration(): void + { + $this->toastrBuilder->showDuration(500); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['showDuration' => 500], $options); + } + + public function testShowEasing(): void + { + $this->toastrBuilder->showEasing('easeIn'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['showEasing' => 'easeIn'], $options); + } + + public function testShowMethod(): void + { + $this->toastrBuilder->showMethod('slideDown'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['showMethod' => 'slideDown'], $options); + } + + public function testTapToDismiss(): void + { + $this->toastrBuilder->tapToDismiss(false); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['tapToDismiss' => false], $options); + } + + public function testTarget(): void + { + $this->toastrBuilder->target('#myTarget'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['target' => '#myTarget'], $options); + } + + public function testTimeOut(): void + { + $this->toastrBuilder->timeOut(3000, 1000); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['timeOut' => 3000, 'extendedTimeOut' => 1000], $options); + } + + public function testTitleClass(): void + { + $this->toastrBuilder->titleClass('title-info'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['titleClass' => 'title-info'], $options); + } + + public function testToastClass(): void + { + $this->toastrBuilder->toastClass('toast-info'); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['toastClass' => 'toast-info'], $options); + } + + public function testPersistent(): void + { + $this->toastrBuilder->persistent(); + + $envelope = $this->toastrBuilder->getEnvelope(); + $options = $envelope->getNotification()->getOptions(); + + $this->assertSame(['timeOut' => 0, 'extendedTimeOut' => 0], $options); + } +} diff --git a/tests/Toastr/Prime/ToastrPluginTest.php b/tests/Toastr/Prime/ToastrPluginTest.php new file mode 100644 index 00000000..c297e8b2 --- /dev/null +++ b/tests/Toastr/Prime/ToastrPluginTest.php @@ -0,0 +1,74 @@ +toastrPlugin = new ToastrPlugin(); + } + + public function testGetAlias(): void + { + $this->assertSame('toastr', $this->toastrPlugin->getAlias()); + } + + public function testGetFactory(): void + { + $this->assertSame(Toastr::class, $this->toastrPlugin->getFactory()); + } + + public function testGetServiceAliases(): void + { + $this->assertSame(ToastrInterface::class, $this->toastrPlugin->getServiceAliases()); + } + + public function testGetScripts(): void + { + $this->assertSame([ + '/vendor/flasher/jquery.min.js', + '/vendor/flasher/toastr.min.js', + '/vendor/flasher/flasher-toastr.min.js', + ], $this->toastrPlugin->getScripts()); + } + + public function testGetStyles(): void + { + $this->assertSame(['/vendor/flasher/toastr.min.css'], $this->toastrPlugin->getStyles()); + } + + public function testGetName(): void + { + $this->assertSame('flasher_toastr', $this->toastrPlugin->getName()); + } + + public function testGetServiceId(): void + { + $this->assertSame('flasher.toastr', $this->toastrPlugin->getServiceId()); + } + + public function testNormalizeConfig(): void + { + $expected = [ + 'scripts' => [ + '/vendor/flasher/jquery.min.js', + '/vendor/flasher/toastr.min.js', + '/vendor/flasher/flasher-toastr.min.js', + ], + 'styles' => ['/vendor/flasher/toastr.min.css'], + 'options' => [], + ]; + + $this->assertSame($expected, $this->toastrPlugin->normalizeConfig([])); + } +} diff --git a/tests/Toastr/Prime/ToastrTest.php b/tests/Toastr/Prime/ToastrTest.php new file mode 100644 index 00000000..0d52bc50 --- /dev/null +++ b/tests/Toastr/Prime/ToastrTest.php @@ -0,0 +1,39 @@ +createNotificationBuilder(); + + $this->assertInstanceOf(ToastrBuilder::class, $result); + } + + public function testToastrBuilderTextMethod(): void + { + $storageManager = \Mockery::mock(StorageManagerInterface::class); + + $toastr = new Toastr($storageManager); + + $builder = $toastr->createNotificationBuilder(); + $response = $toastr->closeButton(true); + + $this->assertInstanceOf(ToastrBuilder::class, $response); + $this->assertInstanceOf(ToastrBuilder::class, $builder); + } +} diff --git a/tests/Toastr/Symfony/FlasherToastrBundleTest.php b/tests/Toastr/Symfony/FlasherToastrBundleTest.php new file mode 100644 index 00000000..a1376e4d --- /dev/null +++ b/tests/Toastr/Symfony/FlasherToastrBundleTest.php @@ -0,0 +1,40 @@ +flasherToastrBundle = new FlasherToastrBundle(); + } + + public function testInstance(): void + { + $this->assertInstanceOf(PluginBundle::class, $this->flasherToastrBundle); + } + + public function testCreatePlugin(): void + { + $this->assertInstanceOf(ToastrPlugin::class, $this->flasherToastrBundle->createPlugin()); + } + + public function testGetConfigurationFileReturnsExpectedPath(): void + { + $expectedPath = $this->flasherToastrBundle->getPath().'/Resources/config/config.yaml'; + + $this->assertSame($expectedPath, $this->flasherToastrBundle->getConfigurationFile()); + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..430f0eea --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@flasher/flasher": ["src/Prime/Resources"], + "@flasher/flasher-noty": ["src/Noty/Prime/Resources"], + "@flasher/flasher-notyf": ["src/Notyf/Prime/Resources"], + "@flasher/flasher-sweetalert": ["src/SweetAlert/Prime/Resources"], + "@flasher/flasher-toastr": ["src/Toastr/Prime/Resources"], + }, + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationMap": false, + "downlevelIteration": true, + "esModuleInterop": true, + "lib": [ + "es6", + "dom" + ], + "module": "es6", + "moduleResolution": "node", + "noEmitOnError": true, + "removeComments": true, + "skipLibCheck": true, + "sourceMap": false, + "strict": true, + "target": "es6" + }, + "exclude": [ + "node_modules", + "dist", + "public" + ] +}
      Younes KHOUBZA
      Younes KHOUBZA

      💻 📖 🚧
      Younes ENNAJI
      Younes ENNAJI

      💻 📖 🚧
      Salma Mourad
      Salma Mourad

      💵
      Nashwan Abdullah
      Nashwan Abdullah

      💵
      Arvid de Jong
      Arvid de Jong

      💵