diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..249b4d4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,18 @@ +# Ignore everything except for the files necessary to build the codebase. +* +!assets +!config +!config_dev +!docker +!html/modules/custom +!html/themes/custom +!PATCHES +!scripts +!composer.json +!composer.lock +!composer.patches.json +!symfony.lock +!load.environment.php + +# Ignore the node modules in the common design subtheme. +html/themes/custom/common_design_subtheme/node_modules diff --git a/.docksal/commands/init b/.docksal/commands/init new file mode 100755 index 0000000..fbf6e0c --- /dev/null +++ b/.docksal/commands/init @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +fin project rm -f +fin project start diff --git a/.docksal/docksal.env b/.docksal/docksal.env new file mode 100644 index 0000000..9ec66a1 --- /dev/null +++ b/.docksal/docksal.env @@ -0,0 +1,5 @@ +DOCKSAL_STACK=default +DOCROOT=html +DB_IMAGE="docksal/db:1.1-mysql-5.7" +CLI_IMAGE='docksal/cli:php8.1-build' +XDEBUG_ENABLED=1 diff --git a/.docksal/docksal.yml b/.docksal/docksal.yml new file mode 100644 index 0000000..0368787 --- /dev/null +++ b/.docksal/docksal.yml @@ -0,0 +1,7 @@ +version: "2.1" +services: + # MailHog + mail: + extends: + file: ${HOME}/.docksal/stacks/services.yml + service: mail diff --git a/.docksal/etc/php/php.ini b/.docksal/etc/php/php.ini new file mode 100644 index 0000000..00d45cd --- /dev/null +++ b/.docksal/etc/php/php.ini @@ -0,0 +1,3 @@ +; Mail settings +sendmail_path = '/usr/bin/msmtp -t --host=mail --port=1025 --read-envelope-from' +xdebug.mode=coverage diff --git a/.docksal/settings.local.php b/.docksal/settings.local.php new file mode 100644 index 0000000..863f530 --- /dev/null +++ b/.docksal/settings.local.php @@ -0,0 +1,167 @@ + 'default', + 'username' => 'user', + 'password' => 'user', + 'host' => 'db', + 'driver' => 'mysql', +); + +// Workaround for permission issues with NFS shares +$settings['file_chmod_directory'] = 0777; +$settings['file_chmod_file'] = 0666; + +# File system settings. +$config['system.file']['path']['temporary'] = '/tmp'; + +// Reverse proxy configuration (Docksal vhost-proxy) +if (PHP_SAPI !== 'cli') { + $settings['reverse_proxy'] = TRUE; + $settings['reverse_proxy_addresses'] = array($_SERVER['REMOTE_ADDR']); + // HTTPS behind reverse-proxy + if ( + isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' && + !empty($settings['reverse_proxy']) && in_array($_SERVER['REMOTE_ADDR'], $settings['reverse_proxy_addresses']) + ) { + $_SERVER['HTTPS'] = 'on'; + // This is hardcoded because there is no header specifying the original port. + $_SERVER['SERVER_PORT'] = 443; + } +} + +$settings['config_sync_directory'] = dirname($app_root) . '/config'; +$settings['file_private_path'] = '../private_files'; diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..686c443 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# Drupal editor configuration normalization +# @see http://editorconfig.org/ + +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[composer.{json,lock}] +indent_size = 4 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..76ea8fe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,61 @@ +# Drupal git normalization +# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +# @see https://www.drupal.org/node/1542048 + +# Normally these settings would be done with macro attributes for improved +# readability and easier maintenance. However macros can only be defined at the +# repository root directory. Drupal avoids making any assumptions about where it +# is installed. + +# Define text file attributes. +# - Treat them as text. +# - Ensure no CRLF line-endings, neither on checkout nor on checkin. +# - Detect whitespace errors. +# - Exposed by default in `git diff --color` on the CLI. +# - Validate with `git diff --check`. +# - Deny applying with `git apply --whitespace=error-all`. +# - Fix automatically with `git apply --whitespace=fix`. + +*.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html +*.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php linguist-language=php +*.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 + +# Define binary file attributes. +# - Do not treat them as text. +# - Include binary diff in patches instead of "binary files differ." +*.eot -text diff +*.exe -text diff +*.gif -text diff +*.gz -text diff +*.ico -text diff +*.jpeg -text diff +*.jpg -text diff +*.otf -text diff +*.phar -text diff +*.png -text diff +*.svgz -text diff +*.ttf -text diff +*.woff -text diff +*.woff2 -text diff diff --git a/.github/workflows/composer-update.yml b/.github/workflows/composer-update.yml new file mode 100644 index 0000000..c47ffee --- /dev/null +++ b/.github/workflows/composer-update.yml @@ -0,0 +1,22 @@ +name: Run Composer Update + +on: + schedule: + - cron: '30 6 * * 4' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Update The Thing + id: update-action + uses: UN-OCHA/actions/composer-update@main + with: + github_access_token: ${{ secrets.PAT }} + patch_branch: 'develop' + patch_packages: 'drupal/*' + patch_maintainers: ${{ secrets.DRUPAL_MAINTAINERS }} + slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }} + slack_channel_name: ${{ secrets.SLACK_CHANNEL }} + flowdock_token: ${{ secrets.FLOWDOCK_TOKEN }} diff --git a/.github/workflows/docker-build-image.yml b/.github/workflows/docker-build-image.yml new file mode 100644 index 0000000..205391e --- /dev/null +++ b/.github/workflows/docker-build-image.yml @@ -0,0 +1,31 @@ +name: Build docker image + +on: + push: + branches: + - develop + - 'feature/**' + - main + release: + types: [published] + +jobs: + build: + runs-on: ubuntu-latest + steps: + + - name: Build + id: build-action + uses: UN-OCHA/actions/drupal-docker-build@main + with: + aws_access_key_id: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + aws_secret_access_key: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + docker_registry_url: public.ecr.aws + docker_registry_path: /unocha/ + docker_image: ai-summarize-site + docker_username: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + docker_password: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }} + ecr_github_token: ${{ secrets.ECR_GITHUB_TOKEN }} + ecr_jenkins_token: ${{ secrets.JENKINS_ECR_TOKEN }} + slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }} + slack_channel_name: ${{ secrets.SLACK_CHANNEL }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..3185369 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,269 @@ +name: Run tests + +on: [pull_request] + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + id: checkout + uses: actions/checkout@v3 + + - name: Extract PHP Version + id: php + uses: docker://ghcr.io/un-ocha/actions:extract-php-version-main + with: + docker_file: 'docker/Dockerfile' + docker_image: 'public.ecr.aws/unocha/php-k8s' + + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + if: ${{ !env.ACT }} + with: + php-version: ${{ steps.php.outputs.php_version }} + tools: composer + env: + fail-fast: true + + - name: Setup PHP with PECL extension locally + uses: shivammathur/setup-php@v2 + if: ${{ env.ACT }} + with: + php-version: ${{ steps.php.outputs.php_version }} + tools: composer + env: + fail-fast: true + runner: self-hosted + + - name: Software versions + id: versions + uses: cafuego/command-output@main + with: + run: | + php --version && composer --version + + - name: Composer Validate + id: validate + uses: cafuego/command-output@main + with: + run: | + composer validate + env: + fail-fast: true + + - name: Code Lint + id: lint + uses: cafuego/command-output@main + with: + run: | + test ! -d ./html/modules/custom || find -L ./html/modules/custom -iregex '.*\.\(php\|module\|inc\|install\)$' -print0 | xargs -0 -n 1 -P 4 php -l + test ! -d ./html/themes/custom || find -L ./html/themes/custom -iregex '.*\.\(php\|theme\)$' -print0 | xargs -0 -n 1 -P 4 php -l + env: + fail-fast: true + + - name: Configure AWS Credentials + id: aws + if: ${{ !env.ACT }} + uses: aws-actions/configure-aws-credentials@v3 + with: + aws-access-key-id: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Login to Public ECR + id: aws-login + if: ${{ !env.ACT }} + uses: docker/login-action@v2.1.0 + with: + registry: public.ecr.aws + username: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + password: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }} + env: + AWS_REGION: us-east-1 + + - name: Build Image + id: build + uses: cafuego/command-output@main + with: + run: | + make + env: + fail-fast: true + + - name: Setup Environment + id: docker + uses: cafuego/command-output@main + with: + run: | + docker-compose -f tests/docker-compose.yml up -d + sleep 10 + docker ps -a + docker-compose -f tests/docker-compose.yml exec -w /srv/www -T drupal composer install + env: + fail-fast: true + + - name: Install Subtheme + id: subtheme + uses: cafuego/command-output@main + with: + run: | + docker-compose -f tests/docker-compose.yml exec -w /srv/www -T drupal /usr/bin/composer run sub-theme + - name: PHPCS + id: phpcs + uses: cafuego/command-output@main + with: + run: | + docker-compose -f tests/docker-compose.yml exec -u appuser -w /srv/www -T drupal phpcs -p --report=full --standard=phpcs.xml ./html/modules/custom ./html/themes/custom + env: + fail-fast: true + + - name: Install Environment + id: install + uses: cafuego/command-output@main + with: + run: | + docker-compose -f tests/docker-compose.yml exec -T drupal drush -y si --existing-config minimal install_configure_form.enable_update_status_emails=NULL + env: + fail-fast: true + + - name: Run tests + id: tests + uses: cafuego/command-output@main + with: + run: | + docker-compose -f tests/docker-compose.yml exec -T drupal drush -y en dblog + docker-compose -f tests/docker-compose.yml exec -T drupal chmod -R 777 /srv/www/html/sites/default/files /srv/www/html/sites/default/private + docker-compose -f tests/docker-compose.yml exec -T drupal mkdir -p /srv/www/html/build/logs + docker-compose -f tests/docker-compose.yml exec -T drupal chmod -R 777 /srv/www/html/build/logs + docker-compose -f tests/docker-compose.yml exec -T drupal mkdir -p /srv/www/html/sites/default/files/browser_output + docker-compose -f tests/docker-compose.yml exec -T drupal chmod -R 777 /srv/www/html/sites/default/files/browser_output + docker-compose -f tests/docker-compose.yml exec -T -w /srv/www -e XDEBUG_MODE=coverage -e BROWSERTEST_OUTPUT_DIRECTORY=/srv/www/html/sites/default/files/browser_output -e DTT_BASE_URL=http://127.0.0.1 drupal ./vendor/bin/phpunit --coverage-clover /srv/www/html/build/logs/clover.xml --debug + env: + fail-fast: true + + - name: Copy Coveralls + id: copy_coveralls + if: success() + run: docker cp "$(docker-compose -f tests/docker-compose.yml ps -q drupal)":/srv/www/html/build/logs/clover.xml . || echo "skip=true" >> "$GITHUB_OUTPUT" + + - name: Monitor coverage + id: coveralls + if: ${{ steps.copy_coveralls.outputs.skip != 'true' }} + uses: slavcodev/coverage-monitor-action@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + coverage_path: "clover.xml" + threshold_alert: 0 + threshold_warning: 50 + threshold_metric: "lines" + comment_footer: false + + - name: DB Logs + id: dblog + if: failure() + uses: cafuego/command-output@main + with: + run: | + docker-compose -f tests/docker-compose.yml exec -T drupal drush watchdog:show + + - name: Find Comment + uses: peter-evans/find-comment@v2 + if: ${{ !env.ACT }} + id: fc + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: Build output + + - name: Create or update comment + uses: peter-evans/create-or-update-comment@v2 + if: ${{ !env.ACT }} + with: + token: ${{ secrets.GITHUB_TOKEN }} + comment-id: ${{ steps.fc.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ### Build output + #### Composer Validate `${{ steps.validate.outcome }}` + #### PHP Lint `${{ steps.lint.outcome }}` + #### Docker Build `${{ steps.build.outcome }}` + #### Environment Setup `${{ steps.docker.outcome }}` + #### Site Install `${{ steps.install.outcome }}` + #### PHP Code Sniffer `${{ steps.phpcs.outcome }}` + +
Software Versions + ${{ steps.versions.outputs.stdout }} +
+
Drupal Logs + ${{ steps.dblog.outputs.stdout }} +
+ + *Pusher: @${{ github.actor }}, Action: `${{ github.event_name }}`, Workflow: `${{ github.workflow }}`* + edit-mode: replace + + - name: Slack Success Notification + id: slack_success + if: ${{ !env.ACT && success() }} + uses: slackapi/slack-github-action@v1.23.0 + with: + channel-id: '${{ vars.SLACK_CHANNEL }}' + payload: | + { + "text": "Tests passed for a pull request on ${{ github.repository }}", + "attachments": [ + { + "color": "#00FF00", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Pull request by @${{ github.triggering_actor }} to merge _${{ github.head_ref }}_ into _${{ github.base_ref }}_ on <${{ github.repositoryUrl }}|${{ github.repository }}> passed tests (<${{ github.event.pull_request.html_url }}|Review>)" + } + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + + - name: Slack Failure Notification + id: slack_failure + if: ${{ !env.ACT && failure() }} + uses: slackapi/slack-github-action@v1.23.0 + with: + channel-id: '${{ vars.SLACK_CHANNEL }}' + payload: | + { + "text": "Tests failed for a pull request on ${{ github.repository }}", + "attachments": [ + { + "color": "#FF0000", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Pull request by @${{ github.triggering_actor }} to merge _${{ github.head_ref }}_ into _${{ github.base_ref }}_ on <${{ github.repositoryUrl }}|${{ github.repository }}> failed tests ()" + } + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + + - name: Clean up + id: docker-clean-up + if: ${{ env.ACT }} + uses: cafuego/command-output@main + with: + run: | + docker compose -f tests/docker-compose.yml down + env: + fail-fast: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f78a370 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# Ignore directories generated by Composer +/drush/contrib/ +/vendor/ +/bin/ +/.composer/ + +# Ignore drupal code except for the custom modules and themes. +/html/* + +!/html/modules/ +/html/modules/* +!/html/modules/custom/ + +!/html/themes/ +/html/themes/* +!/html/themes/custom/ + +# Ignore sensitive information +/html/sites/*/settings.php +/html/sites/*/settings.local.php +/html/sites/*/services.yml + +# Ignore .env files as they are personal +/.env + +# Ignore Drupal's file directory +/html/sites/*/files/ +/html/sites/*/private/ + +# Ignore SimpleTest multi-site environment. +/html/sites/simpletest + +# Ignore node modules. +/node_modules + +# Ignore docker image build log. +buildlog.txt + +# Ignore local dev directories. +/shared/ +/database/ +/private/ +/notes/ +/.idea/ +/.composer/ + +# Coverage +/phpcov.phar +/code-coverage-report-clover/ +/coverage/ +/html/sites/default/browser_output/ + +###> squizlabs/php_codesniffer ### +/.phpcs-cache +/tests/coverage/ +###< squizlabs/php_codesniffer ### + +###> phpunit/phpunit ### +.phpunit.result.cache +###< phpunit/phpunit ### + +###> symfony/phpunit-bridge ### +.phpunit +.phpunit.result.cache +###< symfony/phpunit-bridge ### diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b777c87 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +# Variables. Yes. +DOCKER=docker +DOCKER_BUILDKIT=0 + +# The main build recipe. +build: clean + DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) $(DOCKER) build \ + --build-arg BRANCH_ENVIRONMENT=$(NODE_ENV) \ + --build-arg VCS_REF=`git rev-parse --short HEAD` \ + --build-arg VCS_URL=`git config --get remote.origin.url | sed 's#git@github.com:#https://github.com/#'` \ + --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg GITHUB_ACTOR=`whoami` \ + --build-arg GITHUB_REPOSITORY=`git config --get remote.origin.url` \ + --build-arg GITHUB_SHA=`git rev-parse --short HEAD` \ + . --file docker/Dockerfile --tag public.ecr.aws/unocha/ai-summarize-site:local \ + 2>&1 | tee buildlog.txt + +clean: + rm -rf ./buildlog.txt + +# Always build, never claim cache. +.PHONY: build diff --git a/PATCHES/common_design-drupal-10-compatibility.patch b/PATCHES/common_design-drupal-10-compatibility.patch new file mode 100644 index 0000000..54fb69c --- /dev/null +++ b/PATCHES/common_design-drupal-10-compatibility.patch @@ -0,0 +1,69 @@ +diff --git a/common_design.info.yml b/common_design.info.yml +index ca86d3c..af2e0f9 100644 +--- a/common_design.info.yml ++++ b/common_design.info.yml +@@ -1,7 +1,7 @@ + name: OCHA Common Design + type: theme + description: OCHA Common Design drupal theme. Use as a base theme, and extend. +-core_version_requirement: ^8.8 || ^9 ++core_version_requirement: ^9 || ^10 + base theme: stable + logo: 'img/logos/ocha-lockup-blue.svg' + +diff --git a/common_design_subtheme/common_design_subtheme.info.yml.example b/common_design_subtheme/common_design_subtheme.info.yml.example +index 2dbde6a..8794cb6 100644 +--- a/common_design_subtheme/common_design_subtheme.info.yml.example ++++ b/common_design_subtheme/common_design_subtheme.info.yml.example +@@ -1,6 +1,6 @@ + name: OCHA Common Design sub-theme + description: OCHA Common Design sub-theme +-core_version_requirement: ^8.8 || ^9 ++core_version_requirement: ^9 || ^10 + type: theme + base theme: common_design + logo: 'img/logos/ocha-lockup-blue.svg' +diff --git a/templates/navigation/menu--account.html.twig b/templates/navigation/menu--account.html.twig +index d2acaec..a8ae929 100755 +--- a/templates/navigation/menu--account.html.twig ++++ b/templates/navigation/menu--account.html.twig +@@ -60,7 +60,7 @@ + If the menu item has children and javascript is enabled then this will + be replaced with a button to show the child menu. + #} +- {% spaceless %} ++ {% apply spaceless %} + + {# Add the user icon for the first menu item of the root element. #} + {% if menu_level == 0 and loop.index == 1 %} +@@ -70,7 +70,7 @@ + {% endif %} + {{ item.title }} + +- {% endspaceless %} ++ {% endapply %} + + {# + If the menu item has children then we mark the sub-menu as toggable +diff --git a/templates/navigation/menu--help.html.twig b/templates/navigation/menu--help.html.twig +index ed14b75..2ece6fe 100755 +--- a/templates/navigation/menu--help.html.twig ++++ b/templates/navigation/menu--help.html.twig +@@ -61,7 +61,7 @@ + If the menu item has children and javascript is enabled then this will + be replaced with a button to show the child menu. + #} +- {% spaceless %} ++ {% apply spaceless %} + + {# Add the user icon for the first menu item of the root element. #} + {% if menu_level == 0 and loop.index == 1 %} +@@ -71,7 +71,7 @@ + {% endif %} + {{ title }} + +- {% endspaceless %} ++ {% endapply %} + + {# If the menu item has children then we mark it as toggable and we'll + let the dropdown javascript handle the rest. #} diff --git a/PATCHES/csp-log-format.patch b/PATCHES/csp-log-format.patch new file mode 100644 index 0000000..470e2f4 --- /dev/null +++ b/PATCHES/csp-log-format.patch @@ -0,0 +1,18 @@ +diff --git a/src/Controller/ReportUri.php b/src/Controller/ReportUri.php +index d7229fa..744a40a 100644 +--- a/src/Controller/ReportUri.php ++++ b/src/Controller/ReportUri.php +@@ -87,9 +87,11 @@ public function log($type) { + } + + $this->logger +- ->info("@type
\n
@data
", [ ++ ->info("(@type) - Unmatched @directive: @blocked on page @page", [ + '@type' => $type, +- '@data' => json_encode($report, JSON_PRETTY_PRINT), ++ '@directive' => $report->{'csp-report'}->{'violated-directive'}, ++ '@blocked' => $report->{'csp-report'}->{'blocked-uri'}, ++ '@page' => $report->{'csp-report'}->{'document-uri'}, + ]); + + // 202: Accepted. diff --git a/PATCHES/maintenance200-drupal-10-compatibility.patch b/PATCHES/maintenance200-drupal-10-compatibility.patch new file mode 100644 index 0000000..f29fcc7 --- /dev/null +++ b/PATCHES/maintenance200-drupal-10-compatibility.patch @@ -0,0 +1,187 @@ +diff --git a/maintenance200.info.yml b/maintenance200.info.yml +index fa88b4e..9e81116 100755 +--- a/maintenance200.info.yml ++++ b/maintenance200.info.yml +@@ -1,6 +1,5 @@ + name: 'Maintenance 200' + type: module + description: 'Allows the maintenance page to return a configurable HTTP status code rather than the standard 503 code.' +-core: 8.x +-core_version_requirement: ^8 || ^9 ++core_version_requirement: ^9.1 || ^10 + configure: maintenance200_settings +diff --git a/src/EventSubscriber/MaintenanceModeSubscriber.php b/src/EventSubscriber/MaintenanceModeSubscriber.php +index 59c9691..21c58ab 100644 +--- a/src/EventSubscriber/MaintenanceModeSubscriber.php ++++ b/src/EventSubscriber/MaintenanceModeSubscriber.php +@@ -2,21 +2,40 @@ + + namespace Drupal\maintenance200\EventSubscriber; + ++use Symfony\Component\HttpKernel\Event\ResponseEvent; + use Symfony\Component\EventDispatcher\EventSubscriberInterface; +-use Symfony\Component\HttpKernel\Event\GetResponseEvent; + use Symfony\Component\HttpKernel\KernelEvents; +-use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpFoundation\RedirectResponse; +-use Symfony\Component\HttpKernel\Event\FilterResponseEvent; + + use Drupal\Core\Site\MaintenanceModeInterface; + use Drupal\Core\Session\AccountInterface; ++use Drupal\Core\Config\ImmutableConfig; + use Drupal\Core\Config\ConfigFactoryInterface; + use Drupal\Core\Routing\RouteMatch; + +- + class MaintenanceModeSubscriber implements EventSubscriberInterface { + ++ /** ++ * Configuration. ++ * ++ * @var \Drupal\Core\Config\ImmutableConfig ++ */ ++ private ImmutableConfig $config; ++ ++ /** ++ * Maintenance mode. ++ * ++ * @var \Drupal\Core\Site\MaintenanceModeInterface ++ */ ++ private MaintenanceModeInterface $maintenanceMode; ++ ++ /** ++ * User account. ++ * ++ * @var \Drupal\Core\Session\AccountInterface ++ */ ++ private AccountInterface $account; ++ + /** + * @inheritDoc + */ +@@ -30,7 +49,7 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface { + * Respond to RESPONSE Kernel event by setting status code if in maintenance. + * + */ +- public function onKernelResponse(FilterResponseEvent $event) { ++ public function onKernelResponse(ResponseEvent $event) { + if ($this->config->get('maintenance200_enabled')) { + $status_code = $this->config->get('maintenance200_status_code'); + $request = $event->getRequest(); +diff --git a/tests/src/Functional/Maintenance200SettingsTest.php b/tests/src/Functional/Maintenance200SettingsTest.php +index 044f2f9..1869431 100644 +--- a/tests/src/Functional/Maintenance200SettingsTest.php ++++ b/tests/src/Functional/Maintenance200SettingsTest.php +@@ -20,7 +20,7 @@ class Maintenance200SettingsTest extends BrowserTestBase { + * + * @var array + */ +- public static $modules = [ ++ protected static $modules = [ + 'block', + 'maintenance200', + ]; +@@ -40,7 +40,7 @@ class Maintenance200SettingsTest extends BrowserTestBase { + /** + * {@inheritdoc} + */ +- protected function setUp() { ++ protected function setUp(): void { + parent::setUp(); + + $this->sut = $this +@@ -57,8 +57,8 @@ class Maintenance200SettingsTest extends BrowserTestBase { + */ + public function testSettingsForm() { + $this->drupalGet(Url::fromRoute('maintenance200_settings')); +- $this->assertRaw('Change the status code during maintenance mode', 'Checkbox found.'); +- $this->assertFieldByName('maintenance200_enabled', TRUE); ++ $this->assertSession()->responseContains('Change the status code during maintenance mode'); ++ $this->assertSession()->fieldValueEquals('maintenance200_enabled', TRUE); + } + + /** +@@ -68,7 +68,7 @@ class Maintenance200SettingsTest extends BrowserTestBase { + $maintenance200FormUrl = Url::fromRoute('maintenance200_settings') + ->toString(); + $this->drupalGet(Url::fromRoute('system.site_maintenance_mode')); +- $this->assertLinkByHref($maintenance200FormUrl); ++ $this->assertSession()->linkByHrefExists($maintenance200FormUrl); + } + + /** +@@ -80,12 +80,13 @@ class Maintenance200SettingsTest extends BrowserTestBase { + $edit = [ + 'maintenance200_enabled' => 0, + ]; +- $this->drupalPostForm('admin/config/development/maintenance200', $edit, t('Save configuration')); ++ $this->drupalGet('admin/config/development/maintenance200'); ++ $this->submitForm($edit, t('Save configuration')); + +- $this->assertRaw('The configuration options have been saved.', 'Settings saved.'); ++ $this->assertSession()->responseContains('The configuration options have been saved.'); + + $this->drupalGet(Url::fromRoute('maintenance200_settings')); +- $this->assertFieldByName('maintenance200_enabled', FALSE); ++ $this->assertSession()->fieldValueEquals('maintenance200_enabled', FALSE); + } + + } +diff --git a/tests/src/Functional/Maintenance200Test.php b/tests/src/Functional/Maintenance200Test.php +index 8a3d39e..238ea14 100644 +--- a/tests/src/Functional/Maintenance200Test.php ++++ b/tests/src/Functional/Maintenance200Test.php +@@ -19,7 +19,7 @@ class Maintenance200Test extends BrowserTestBase { + * + * @var array + */ +- public static $modules = [ ++ protected static $modules = [ + 'maintenance200', + 'node', + ]; +@@ -32,7 +32,7 @@ class Maintenance200Test extends BrowserTestBase { + /** + * {@inheritdoc} + */ +- protected function setUp() { ++ protected function setUp(): void { + parent::setUp(); + + // Create Basic page node type. +@@ -63,7 +63,7 @@ class Maintenance200Test extends BrowserTestBase { + \Drupal::state()->set('system.maintenance_mode', FALSE); + + $this->drupalGet(''); +- $this->assertResponse(200); ++ $this->assertSession()->statusCodeEquals(200); + } + + /** +@@ -81,7 +81,7 @@ class Maintenance200Test extends BrowserTestBase { + ->save(); + + $this->drupalGet(''); +- $this->assertResponse(503); ++ $this->assertSession()->statusCodeEquals(503); + } + + /** +@@ -99,7 +99,7 @@ class Maintenance200Test extends BrowserTestBase { + ->save(); + + $this->drupalGet(''); +- $this->assertResponse(200); ++ $this->assertSession()->statusCodeEquals(200); + } + + /** +@@ -117,7 +117,7 @@ class Maintenance200Test extends BrowserTestBase { + ->save(); + + $this->drupalGet(''); +- $this->assertResponse(418); ++ $this->assertSession()->statusCodeEquals(418); + } + + } diff --git a/PATCHES/notes.md b/PATCHES/notes.md new file mode 100644 index 0000000..f2fe961 --- /dev/null +++ b/PATCHES/notes.md @@ -0,0 +1,23 @@ +# Patches + +Information about Drupal patches. + +## Drupal 10 compatibility patches + +In order to apply the compatibility patches generated by Drupal rector for +example, the https://github.com/orakili/composer-drupal-info-file-patch-helper +needs to be added to the composer.json. + +### Add a new incompatible module + +1. Add an entry for the module in `extra.drupal-lenient.allowed-list` in the + composer.json file +2. Add the compatibility patch in the `composer.patches.json` file. +3. Require the module via `composer require drupal/module` + +## Core patches to review + +Review the Drupal 10 compatibility of the following patches: + +- [XSS Filter](https://www.drupal.org/project/drupal/issues/2544110) +- [Pager query parameter](https://www.drupal.org/project/drupal/issues/3143617) diff --git a/PATCHES/user_expire-customize-notification-email.patch b/PATCHES/user_expire-customize-notification-email.patch new file mode 100644 index 0000000..db8c845 --- /dev/null +++ b/PATCHES/user_expire-customize-notification-email.patch @@ -0,0 +1,187 @@ +diff --git a/config/install/user_expire.settings.yml b/config/install/user_expire.settings.yml +index 62f9e8c7d5a064d87448b0faf5811a08709370c7..ea9fb144d2add8031bcafc516fb46cca209eb6c9 100644 +--- a/config/install/user_expire.settings.yml ++++ b/config/install/user_expire.settings.yml +@@ -1,3 +1,7 @@ + frequency: 172800 + offset: 604800 + user_expire_roles: {} ++send_mail: true ++mail: ++ subject: "[site:name]: Account expiration warning" ++ body: "Hello [user:display-name]\r\n\r\nBecause you have not logged in recently, your account at [site:name] will be blocked in the near future. If you still use this site, please log in [site:login-url] to prevent your account being blocked.\r\n\r\n-- [site:name] team" +diff --git a/config/schema/user_expire.schema.yml b/config/schema/user_expire.schema.yml +index a46bc68eeea8b41fa1e7bde72008daf77d54032d..f8e9e2e101f58d8f5a5cbfb87483bc9821a6a7a6 100644 +--- a/config/schema/user_expire.schema.yml ++++ b/config/schema/user_expire.schema.yml +@@ -7,9 +7,21 @@ user_expire.settings: + frequency: + type: integer + label: 'Frequency time in seconds' ++ mail: ++ type: mapping ++ mapping: ++ subject: ++ type: string ++ label: 'Subject line for the notification email' ++ body: ++ type: string ++ label: 'Body for the notification email' + offset: + type: integer + label: 'Warning offset time in seconds' ++ send_mail: ++ type: integer ++ label: 'Flag that enables or disables expiry emails' + user_expire_roles: + type: sequence + label: 'Roles and expire value' +diff --git a/src/Form/UserExpireSettingsForm.php b/src/Form/UserExpireSettingsForm.php +index 8d7e2d0d0f01265abce72f018b8b32facf76087a..d8d9cb6671b29364c0ba198e893e823261079412 100644 +--- a/src/Form/UserExpireSettingsForm.php ++++ b/src/Form/UserExpireSettingsForm.php +@@ -111,6 +111,50 @@ class UserExpireSettingsForm extends ConfigFormBase { + ]; + } + ++ // Enable or disable email notifications. ++ $form['send_mail'] = [ ++ '#type' => 'checkbox', ++ '#title' => $this->t('Send notifiation emails'), ++ '#default_value' => $config->get('send_mail') ?: true, ++ '#description' => $this->t('Send a notification email to the user, starting at the defined offset time before account expiry.'), ++ ]; ++ ++ // Notification email template. ++ $form['mail'] = [ ++ '#type' => 'fieldset', ++ '#title' => $this->t('Notification email'), ++ ]; ++ ++ $form['mail']['settings'] = [ ++ '#type' => 'container', ++ '#states' => [ ++ // Hide the additional settings when this email is disabled. ++ 'invisible' => [ ++ 'input[name="send_mail"]' => ['checked' => FALSE], ++ ], ++ ], ++ ]; ++ ++ $form['mail']['settings']['notification_subject'] = [ ++ '#type' => 'textfield', ++ '#title' => $this->t('Subject'), ++ '#default_value' => $config->get('mail.subject') ?: '', ++ '#description' => $this->t('Subject line for the notification email.'), ++ '#maxlength' => 180, ++ ]; ++ ++ $form['mail']['settings']['notification_body'] = [ ++ '#type' => 'textarea', ++ '#title' => $this->t('Body'), ++ '#default_value' => $config->get('mail.body') ?: '', ++ '#description' => $this->t('Body for the notifiction email.'), ++ '#rows' => 15, ++ ]; ++ ++ $form['mail']['settings']['help'] = [ ++ '#markup' => $this->t('Available token variables for use in the email are: [site:name], [site:url], [site:mail], [user:display-name], [user:account-name], [user:mail], [site:login-url], [site:url-brief], [user:edit-url], [user:one-time-login-url], [user:cancel-url]'), ++ ]; ++ + return parent::buildForm($form, $form_state); + } + +@@ -162,6 +206,13 @@ class UserExpireSettingsForm extends ConfigFormBase { + } + + $config->set('user_expire_roles', $rules); ++ ++ // The notification email. ++ $config->set('send_mail', $form_state->getValue('send_mail')); ++ ++ $config->set('mail.subject', $form_state->getValue('notification_subject')); ++ $config->set('mail.body', $form_state->getValue('notification_body')); ++ + $config->save(); + } + +diff --git a/user_expire.module b/user_expire.module +index 26beacd1c168d92962fae31090470698f753ff47..34f61dc939b476aa6a93323f6aff2801fab64891 100644 +--- a/user_expire.module ++++ b/user_expire.module +@@ -12,6 +12,7 @@ use Drupal\Core\Datetime\DrupalDateTime; + use Drupal\user\RoleInterface; + use Drupal\Core\Url; + use Drupal\Core\Routing\RouteMatchInterface; ++use Drupal\Component\Render\PlainTextOutput; + + /** + * Implements hook_help(). +@@ -332,18 +333,21 @@ function user_expire_expire_by_role_warning() { + if ($uids_to_warn) { + foreach ($uids_to_warn as $uid) { + $account = \Drupal::entityTypeManager()->getStorage('user')->load($uid->uid); +- if ($account) { ++ if (!$account) { + $logger->debug('Skipping warning @uid as it failed to load a valid user', [ + '@uid' => $uid->uid, + ]); + } + else { +- $logger->info('Warning about expiring account @name by role', ['@name' => $account->getAccountName()]); +- \Drupal::service('plugin.manager.mail')->mail('user_expire', 'expiration_warning', $account->getEmail(), $account->getPreferredLangcode(), +- [ +- 'account' => $account, +- ] +- ); ++ // Send a notification email if configured to do so. ++ if ($config->get('send_mail')) { ++ $logger->info('Sending warning about expiring account @name by role', ['@name' => $account->getAccountName()]); ++ \Drupal::service('plugin.manager.mail')->mail('user_expire', 'expiration_warning', $account->getEmail(), $account->getPreferredLangcode(), ++ [ ++ 'account' => $account, ++ ] ++ ); ++ } + } + } + } +@@ -445,20 +449,23 @@ function user_expire_get_role_rules() { + */ + function user_expire_mail($key, &$message, $params) { + if ($key == 'expiration_warning') { +- $site_name = \Drupal::config('system.site')->get('name'); +- // The subject. +- $message['subject'] = t('@site_name: Account expiration warning', ['@site_name' => $site_name]); +- // The body. +- $message['body'][] = t('Hello @user', ['@user' => $params['account']->getAccountName()]); +- // An empty string gives a newline. +- $message['body'][] = ''; +- $message['body'][] = t('Because you have not logged in recently, your account at @site_name will be blocked in the near future. If you still use this site, please log in @login_url to avoid having your account blocked.', +- [ +- '@site_name' => $site_name, +- '@login_url' => Url::fromRoute('entity.user.canonical', ['user' => \Drupal::currentUser()->id()], ['absolute' => TRUE]), +- ] +- ); +- $message['body'][] = ''; +- $message['body'][] = t('Thanks, @site_name', ['@site_name' => $site_name]); ++ ++ $token_service = \Drupal::token(); ++ $language_manager = \Drupal::languageManager(); ++ $langcode = $message['langcode']; ++ $variables = ['user' => $params['account']]; ++ ++ $language = $language_manager->getLanguage($params['account']->getPreferredLangcode()); ++ $original_language = $language_manager->getConfigOverrideLanguage(); ++ $language_manager->setConfigOverrideLanguage($language); ++ ++ $config_factory = \Drupal::configFactory(); ++ $config = $config_factory->get('user_expire.settings'); ++ ++ $token_options = ['langcode' => $langcode, 'callback' => 'user_mail_tokens', 'clear' => TRUE]; ++ $message['subject'] .= PlainTextOutput::renderFromHtml($token_service->replace($config->get('mail.subject'), $variables, $token_options)); ++ $message['body'][] = $token_service->replace($config->get('mail.body'), $variables, $token_options); ++ ++ $language_manager->setConfigOverrideLanguage($original_language); + } + } diff --git a/PATCHES/user_expire-reset-expiration-on-reactivation.patch b/PATCHES/user_expire-reset-expiration-on-reactivation.patch new file mode 100644 index 0000000..6f8bbc9 --- /dev/null +++ b/PATCHES/user_expire-reset-expiration-on-reactivation.patch @@ -0,0 +1,51 @@ +diff --git a/tests/src/Functional/UserExpireTest.php b/tests/src/Functional/UserExpireTest.php +index fb5180d8bc697603e46a4cf8debba8f07ef7552c..6bc1bb618ebfad3726fb0e0d5163f21aabbae3d1 100644 +--- a/tests/src/Functional/UserExpireTest.php ++++ b/tests/src/Functional/UserExpireTest.php +@@ -161,6 +161,18 @@ class UserExpireTest extends BrowserTestBase { + // Ensure they are disabled. + $this->drupalGet("user/" . $new_basic_account->id() . "/edit"); + $this->assertSession()->responseContains('type="radio" id="edit-status-0" name="status" value="0" checked="checked" class="form-radio"', $this->t('User account is currently disabled.')); ++ ++ // Manually unblock the user. ++ $edit = []; ++ $edit['status'] = 1; ++ $this->drupalPostForm("user/" . $new_basic_account->id() . "/edit", $edit, $this->t('Save')); ++ ++ // Process it. ++ user_expire_expire_by_role(); ++ ++ // Ensure they are still active. ++ $this->drupalGet("user/" . $new_basic_account->id() . "/edit"); ++ $this->assertSession()->responseContains('type="radio" id="edit-status-1" name="status" value="1" checked="checked" class="form-radio"', $this->t('User account is currently active.')); + } + + } +diff --git a/user_expire.module b/user_expire.module +index cb2958708e8063270d4765ec999009ea51f81ee9..9d7e157fbd908763521551237a7e2cc8d9a4abad 100644 +--- a/user_expire.module ++++ b/user_expire.module +@@ -9,6 +9,7 @@ use Drupal\Core\Form\FormStateInterface; + use Drupal\Core\Entity\EntityInterface; + use Drupal\Core\Database\Query\Condition; + use Drupal\Core\Datetime\DrupalDateTime; ++use Drupal\user\Entity\User; + use Drupal\user\RoleInterface; + use Drupal\Core\Url; + use Drupal\Core\Routing\RouteMatchInterface; +@@ -462,3 +463,15 @@ function user_expire_mail($key, &$message, $params) { + $message['body'][] = t('Thanks, @site_name', ['@site_name' => $site_name]); + } + } ++ ++/** ++ * Implements hook_ENTITY_TYPE_presave() for user entities. ++ * ++ * If the account was blocked but is now active, update the expiry so it is ++ * not re-blocked by the next cron run. ++ */ ++function user_expire_user_presave(User $account) { ++ if (!empty($account->original) && $account->original->isBlocked() && $account->isActive()) { ++ $account->setLastAccessTime(\Drupal::time()->getRequestTime()); ++ } ++} diff --git a/PATCHES/username_enumeration_prevention-user-login-block-form-3312288.patch b/PATCHES/username_enumeration_prevention-user-login-block-form-3312288.patch new file mode 100644 index 0000000..5fa6746 --- /dev/null +++ b/PATCHES/username_enumeration_prevention-user-login-block-form-3312288.patch @@ -0,0 +1,20 @@ +diff --git a/username_enumeration_prevention.module b/username_enumeration_prevention.module +index 1038f75b1d823887965f79df9d3b76fc396031a1..075abaa22c8392f810093e066990934328fdd01c 100644 +--- a/username_enumeration_prevention.module ++++ b/username_enumeration_prevention.module +@@ -86,3 +86,15 @@ function username_enumeration_prevention_pass_submit($form, FormStateInterface $ + \Drupal::messenger()->addMessage(t('If the username or email address exists and is active, further instructions have been sent to your email address.')); + $form_state->setRedirect('user.page'); + } ++ ++/** ++ * Implements hook_js_settings_alter(). ++ * ++ * Remove drupalSettings.path.currentPath on 404 responses. ++ */ ++function username_enumeration_prevention_js_settings_alter(&$settings) { ++ if (\Drupal::routeMatch()->getRouteName() === "system.404" ) { ++ $settings['path']['currentPath'] = ''; ++ } ++} ++ diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae626c4 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# OCHA AI Summarization + +## TL;DR + +Uses AI to summarize PDF files + diff --git a/assets/docker-build-image.yml b/assets/docker-build-image.yml new file mode 100644 index 0000000..205391e --- /dev/null +++ b/assets/docker-build-image.yml @@ -0,0 +1,31 @@ +name: Build docker image + +on: + push: + branches: + - develop + - 'feature/**' + - main + release: + types: [published] + +jobs: + build: + runs-on: ubuntu-latest + steps: + + - name: Build + id: build-action + uses: UN-OCHA/actions/drupal-docker-build@main + with: + aws_access_key_id: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + aws_secret_access_key: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + docker_registry_url: public.ecr.aws + docker_registry_path: /unocha/ + docker_image: ai-summarize-site + docker_username: ${{ secrets.ECR_AWS_ACCESS_KEY_ID }} + docker_password: ${{ secrets.ECR_AWS_SECRET_ACCESS_KEY }} + ecr_github_token: ${{ secrets.ECR_GITHUB_TOKEN }} + ecr_jenkins_token: ${{ secrets.JENKINS_ECR_TOKEN }} + slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }} + slack_channel_name: ${{ secrets.SLACK_CHANNEL }} diff --git a/assets/robots.txt.append b/assets/robots.txt.append new file mode 100644 index 0000000..e40cd97 --- /dev/null +++ b/assets/robots.txt.append @@ -0,0 +1 @@ +# Sitemap diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..d80f63c --- /dev/null +++ b/composer.json @@ -0,0 +1,233 @@ +{ + "name": "unocha/ai-summarize", + "description": "AI summarize", + "type": "project", + "license": "GPL-2.0-or-later", + "authors": [ + { + "name": "UNOCHA", + "role": "" + } + ], + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + }, + { + "type": "composer", + "url": "https://asset-packagist.org" + } + ], + "require": { + "php": ">=8.1", + "composer/installers": "^1.12", + "cweagans/composer-patches": "^1.7", + "drupal/admin_denied": "^2.0", + "drupal/allowed_formats": "^2.0", + "drupal/components": "^3.0@beta", + "drupal/config_split": "^2.0.0-rc4", + "drupal/core-composer-scaffold": "^10", + "drupal/core-dev": "^10", + "drupal/core-recommended": "^10", + "drupal/csp": "^1.17", + "drupal/environment_indicator": "^4.0", + "drupal/google_tag": "^1.6", + "drupal/imageapi_optimize_binaries": "^1.0@beta", + "drupal/imagemagick": "^3.4", + "drupal/layout_paragraphs": "^2.0", + "drupal/maintenance200": "^1.1", + "drupal/memcache": "^2.5", + "drupal/metatag": "^1.22", + "drupal/paragraphs": "^1.15", + "drupal/pathauto": "^1.8", + "drupal/queue_ui": "^3.1", + "drupal/redirect": "^1.8", + "drupal/social_auth_hid": "^3.2", + "drupal/stable": "^2.0", + "drupal/user_display_name": "^1.1", + "drupal/user_expire": "^1.1", + "drupal/username_enumeration_prevention": "^1.3", + "drupal/xmlsitemap": "^1.4", + "drush/drush": "^11.3", + "oomphinc/composer-installers-extender": "^2.0", + "orakili/composer-drupal-info-file-patch-helper": "^1", + "unocha/common_design": "^7.4", + "webflo/drupal-finder": "^1.2.2" + }, + "require-dev": { + "drupal/coder": "^8.3", + "drupal/config_filter": "^2.4", + "drupal/config_inspector": "^2.1", + "drupal/dev_mode": "^2.3", + "drupal/devel": "^5.0", + "drupal/devel_php": "^1.3", + "kint-php/kint": "^5.0", + "marcocesarato/php-conventional-changelog": "^1.16", + "mglaman/drupal-check": "^1.4", + "palantirnet/drupal-rector": "^0.13", + "phpcompatibility/php-compatibility": "^9.3", + "phpmd/phpmd": "^2.9", + "phpspec/prophecy-phpunit": "^2", + "phpunit/php-code-coverage": "^9.2", + "phpunit/phpunit": "^9.5", + "weitzman/drupal-test-traits": "^2" + }, + "conflict": { + "drupal/drupal": "*" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "bin-dir": "vendor/bin/", + "sort-packages": true, + "allow-plugins": { + "composer/installers": true, + "cweagans/composer-patches": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "drupal/console-extend-plugin": true, + "drupal/core-composer-scaffold": true, + "drupal/core-project-message": true, + "oomphinc/composer-installers-extender": true, + "orakili/composer-drupal-info-file-patch-helper": true, + "phpstan/extension-installer": true, + "symfony/flex": true + } + }, + "extra": { + "enable-patching": true, + "composer-exit-on-patch-failure": true, + "patches-file": "composer.patches.json", + "patchLevel": { + "drupal/core": "-p2" + }, + "installer-types": [ + "bower-asset", + "npm-asset" + ], + "installer-paths": { + "html/core": [ + "type:drupal-core" + ], + "html/libraries/ckeditor/plugins/{$name}": [ + "vendor:ckeditor-plugin" + ], + "html/libraries/{$name}": [ + "type:drupal-library", + "type:bower-asset", + "type:npm-asset" + ], + "html/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "html/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "html/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "html/modules/custom/{$name}": [ + "type:drupal-custom-module" + ], + "html/themes/custom/{$name}": [ + "type:drupal-custom-theme" + ], + "drush/Commands/{$name}": [ + "type:drupal-drush" + ] + }, + "drupal-scaffold": { + "file-mapping": { + "[web-root]/sites/default/services.yml": { + "mode": "replace", + "path": "html/core/assets/scaffold/files/default.services.yml", + "overwrite": false + }, + "[web-root]/sites/default/settings.php": { + "mode": "replace", + "path": "html/core/assets/scaffold/files/default.settings.php", + "overwrite": false + }, + "[web-root]/robots.txt": { + "append": "assets/robots.txt.append" + } + }, + "locations": { + "web-root": "html/" + } + }, + "merge-plugin": { + "include": [ + "html/core/composer.json" + ], + "recurse": true, + "replace": false, + "merge-extra": false + }, + "drupal-core-project-message": { + "include-keys": [ + "homepage", + "support" + ], + "post-create-project-cmd-message": [ + " ", + " Congratulations, you\u2019ve installed the Drupal codebase ", + " from the drupal/recommended-project template! ", + " ", + "", + "Next steps:", + " * Install the site: https://www.drupal.org/docs/8/install", + " * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html", + " * Get support: https://www.drupal.org/support", + " * Get involved with the Drupal community:", + " https://www.drupal.org/getting-involved", + " * Remove the plugin that prints this message:", + " composer remove drupal/core-project-message" + ] + }, + "drupal-lenient": { + "constraint": "^10", + "allowed-list": [ + "drupal/admin_denied", + "drupal/google_tag", + "drupal/imageapi_optimize", + "drupal/imageapi_optimize_binaries", + "drupal/maintenance200" + ] + } + }, + "autoload": { + "classmap": [ + "scripts/composer/DrupalLenientRequirement.php" + ] + }, + "scripts": { + "changelog": "conventional-changelog", + "release": "conventional-changelog", + "release:patch": "conventional-changelog --patch", + "release:minor": "conventional-changelog --minor", + "release:major": "conventional-changelog --major", + "git-hooks": "git config core.hooksPath git-hooks || exit 0", + "sass-prepare": "cd html/themes/custom/common_design_subtheme && npm install", + "sass-build": "cd html/themes/custom/common_design_subtheme && ./node_modules/.bin/sass sass:build", + "sass-cleanup": "cd html/themes/custom/common_design_subtheme && rm -rf ./node_modules", + "sub-theme": "test -d html/themes/custom/common_design_subtheme || (cp -r html/themes/contrib/common_design/common_design_subtheme html/themes/custom/ && mv html/themes/custom/common_design_subtheme/common_design_subtheme.info.yml.example html/themes/custom/common_design_subtheme/common_design_subtheme.info.yml)", + "sass": [ + "@sass-prepare", + "@sass-build", + "@sass-cleanup" + ], + "post-install-cmd": [ + "@git-hooks" + ], + "post-create-project-cmd": [ + "@sub-theme" + ], + "post-update-cmd": [ + "@git-hooks" + ], + "pre-pool-create": [ + "scripts\\composer\\DrupalLenientRequirement::changeVersionConstraint" + ] + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..5a9604f --- /dev/null +++ b/composer.lock @@ -0,0 +1,14231 @@ +{ + "_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": "8b0f34b5d0c05c4dd4f591c50038c532", + "packages": [ + { + "name": "asm89/stack-cors", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/asm89/stack-cors.git", + "reference": "73e5b88775c64ccc0b84fb60836b30dc9d92ac4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/73e5b88775c64ccc0b84fb60836b30dc9d92ac4a", + "reference": "73e5b88775c64ccc0b84fb60836b30dc9d92ac4a", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "symfony/http-foundation": "^4|^5|^6", + "symfony/http-kernel": "^4|^5|^6" + }, + "require-dev": { + "phpunit/phpunit": "^7|^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Asm89\\Stack\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander", + "email": "iam.asm89@gmail.com" + } + ], + "description": "Cross-origin resource sharing library and stack middleware", + "homepage": "https://github.com/asm89/stack-cors", + "keywords": [ + "cors", + "stack" + ], + "support": { + "issues": "https://github.com/asm89/stack-cors/issues", + "source": "https://github.com/asm89/stack-cors/tree/v2.1.1" + }, + "time": "2022-01-18T09:12:03+00:00" + }, + { + "name": "behat/mink", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/Mink.git", + "reference": "19e58905632e7cfdc5b2bafb9b950a3521af32c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/19e58905632e7cfdc5b2bafb9b950a3521af32c5", + "reference": "19e58905632e7cfdc5b2bafb9b950a3521af32c5", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/css-selector": "^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.22 || ^9.5.11", + "symfony/error-handler": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0" + }, + "suggest": { + "behat/mink-browserkit-driver": "fast headless driver for any app without JS emulation", + "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", + "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)", + "dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Browser controller/emulator abstraction for PHP", + "homepage": "https://mink.behat.org/", + "keywords": [ + "browser", + "testing", + "web" + ], + "support": { + "issues": "https://github.com/minkphp/Mink/issues", + "source": "https://github.com/minkphp/Mink/tree/v1.10.0" + }, + "time": "2022-03-28T14:22:43+00:00" + }, + { + "name": "behat/mink-browserkit-driver", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", + "reference": "d2768e6c17b293d86d8fcff54cbb9e6ad938fee1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/d2768e6c17b293d86d8fcff54cbb9e6ad938fee1", + "reference": "d2768e6c17b293d86d8fcff54cbb9e6ad938fee1", + "shasum": "" + }, + "require": { + "behat/mink": "^1.9.0@dev", + "php": ">=7.2", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "^8.5 || ^9.5", + "symfony/error-handler": "^4.4 || ^5.0 || ^6.0", + "symfony/http-client": "^4.4 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", + "symfony/mime": "^4.4 || ^5.0 || ^6.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Symfony2 BrowserKit driver for Mink framework", + "homepage": "https://mink.behat.org/", + "keywords": [ + "Mink", + "Symfony2", + "browser", + "testing" + ], + "support": { + "issues": "https://github.com/minkphp/MinkBrowserKitDriver/issues", + "source": "https://github.com/minkphp/MinkBrowserKitDriver/tree/v2.1.0" + }, + "time": "2022-03-28T14:33:51+00:00" + }, + { + "name": "behat/mink-selenium2-driver", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", + "reference": "e5f8421654930da725499fb92983e6948c6f973e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/e5f8421654930da725499fb92983e6948c6f973e", + "reference": "e5f8421654930da725499fb92983e6948c6f973e", + "shasum": "" + }, + "require": { + "behat/mink": "^1.9@dev", + "ext-json": "*", + "instaclick/php-webdriver": "^1.4", + "php": ">=7.2" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "^8.5.22 || ^9.5.11", + "symfony/error-handler": "^4.4 || ^5.0" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Pete Otaqui", + "email": "pete@otaqui.com", + "homepage": "https://github.com/pete-otaqui" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Selenium2 (WebDriver) driver for Mink framework", + "homepage": "https://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "javascript", + "selenium", + "testing", + "webdriver" + ], + "support": { + "issues": "https://github.com/minkphp/MinkSelenium2Driver/issues", + "source": "https://github.com/minkphp/MinkSelenium2Driver/tree/v1.6.0" + }, + "time": "2022-03-28T14:55:17+00:00" + }, + { + "name": "chi-teck/drupal-code-generator", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/Chi-teck/drupal-code-generator.git", + "reference": "22ed1cc02dc47814e8239de577da541e9b9bd980" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/22ed1cc02dc47814e8239de577da541e9b9bd980", + "reference": "22ed1cc02dc47814e8239de577da541e9b9bd980", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.4", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/console": "^4.4.15 || ^5.1 || ^6.0", + "symfony/filesystem": "^4.4 || ^5.1 || ^6", + "symfony/polyfill-php80": "^1.23", + "symfony/string": "^5.1 || ^6", + "twig/twig": "^2.14.11 || ^3.1" + }, + "conflict": { + "squizlabs/php_codesniffer": "<3.6" + }, + "require-dev": { + "chi-teck/drupal-coder-extension": "^1.2", + "drupal/coder": "^8.3.14", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.4", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^5.2 || ^6.0", + "symfony/yaml": "^5.2 || ^6.0" + }, + "bin": [ + "bin/dcg" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "DrupalCodeGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Drupal code generator", + "support": { + "issues": "https://github.com/Chi-teck/drupal-code-generator/issues", + "source": "https://github.com/Chi-teck/drupal-code-generator/tree/2.6.2" + }, + "time": "2022-11-11T15:34:04+00:00" + }, + { + "name": "colinodell/psr-testlogger", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/colinodell/psr-testlogger.git", + "reference": "9246155e688b310fb3d0f201ead2445686b5844e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinodell/psr-testlogger/zipball/9246155e688b310fb3d0f201ead2445686b5844e", + "reference": "9246155e688b310fb3d0f201ead2445686b5844e", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.9.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.30.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ColinODell\\PsrTestLogger\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "PSR-3 compliant test logger based on psr/log v1's, but compatible with v2 and v3 too!", + "homepage": "https://github.com/colinodell/psr-testlogger", + "keywords": [ + "log", + "logger", + "logging", + "mock", + "phpunit", + "psr", + "test", + "unit" + ], + "support": { + "issues": "https://github.com/colinodell/psr-testlogger/issues", + "rss": "https://github.com/colinodell/psr-testlogger/releases.atom", + "source": "https://github.com/colinodell/psr-testlogger" + }, + "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": "2023-03-14T19:12:55+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.3.7", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "76e46335014860eec1aa5a724799a00a2e47cc85" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/76e46335014860eec1aa5a724799a00a2e47cc85", + "reference": "76e46335014860eec1aa5a724799a00a2e47cc85", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "psr/log": "^1.0", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.3.7" + }, + "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": "2023-08-30T09:31:38+00:00" + }, + { + "name": "composer/class-map-generator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "953cc4ea32e0c31f2185549c7d216d7921f03da9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/953cc4ea32e0c31f2185549c7d216d7921f03da9", + "reference": "953cc4ea32e0c31f2185549c7d216d7921f03da9", + "shasum": "" + }, + "require": { + "composer/pcre": "^2.1 || ^3.1", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6 || ^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.1.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": "2023-06-30T13:58:57+00:00" + }, + { + "name": "composer/composer", + "version": "2.6.2", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "623e5e1de055e65bc6c3c61b8348dc4662d75e2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/623e5e1de055e65bc6c3c61b8348dc4662d75e2b", + "reference": "623e5e1de055e65bc6c3c61b8348dc4662d75e2b", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/class-map-generator": "^1.0", + "composer/metadata-minifier": "^1.0", + "composer/pcre": "^2.1 || ^3.1", + "composer/semver": "^3.2.5", + "composer/spdx-licenses": "^1.5.7", + "composer/xdebug-handler": "^2.0.2 || ^3.0.3", + "justinrainbow/json-schema": "^5.2.11", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "react/promise": "^2.8 || ^3", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.2", + "seld/signal-handler": "^2.0", + "symfony/console": "^5.4.11 || ^6.0.11 || ^7", + "symfony/filesystem": "^5.4 || ^6.0 || ^7", + "symfony/finder": "^5.4 || ^6.0 || ^7", + "symfony/polyfill-php73": "^1.24", + "symfony/polyfill-php80": "^1.24", + "symfony/polyfill-php81": "^1.24", + "symfony/process": "^5.4 || ^6.0 || ^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.9.3", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1", + "phpstan/phpstan-symfony": "^1.2.10", + "symfony/phpunit-bridge": "^6.0 || ^7" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.6-dev" + }, + "phpstan": { + "includes": [ + "phpstan/rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "https://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/composer/issues", + "security": "https://github.com/composer/composer/security/policy", + "source": "https://github.com/composer/composer/tree/2.6.2" + }, + "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": "2023-09-03T12:09:15+00:00" + }, + { + "name": "composer/installers", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Starbug", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "miaoxing", + "modulework", + "modx", + "moodle", + "osclass", + "pantheon", + "phpbb", + "piwik", + "ppi", + "processwire", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "tastyigniter", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.12.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": "2021-09-13T08:19:44+00:00" + }, + { + "name": "composer/metadata-minifier", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/metadata-minifier.git", + "reference": "c549d23829536f0d0e984aaabbf02af91f443207" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/metadata-minifier/zipball/c549d23829536f0d0e984aaabbf02af91f443207", + "reference": "c549d23829536f0d0e984aaabbf02af91f443207", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "composer/composer": "^2", + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\MetadataMinifier\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Small utility library that handles metadata minification and expansion.", + "keywords": [ + "composer", + "compression" + ], + "support": { + "issues": "https://github.com/composer/metadata-minifier/issues", + "source": "https://github.com/composer/metadata-minifier/tree/1.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": "2021-04-07T13:37:33+00:00" + }, + { + "name": "composer/pcre", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.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": "2022-11-17T09:50:14+00:00" + }, + { + "name": "composer/semver", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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.3.2" + }, + "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": "2022-04-01T19:23:25+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.7", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "c848241796da2abf65837d51dce1fae55a960149" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/c848241796da2abf65837d51dce1fae55a960149", + "reference": "c848241796da2abf65837d51dce1fae55a960149", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "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": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/spdx-licenses/issues", + "source": "https://github.com/composer/spdx-licenses/tree/1.5.7" + }, + "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": "2022-05-23T07:37:50+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "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": "2022-02-25T21:32:43+00:00" + }, + { + "name": "consolidation/annotated-command", + "version": "4.7.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "fd263e3e9341d29758025b1a9b2878e3247525be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/fd263e3e9341d29758025b1a9b2878e3247525be", + "reference": "fd263e3e9341d29758025b1a9b2878e3247525be", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "^4.1.1", + "php": ">=7.1.3", + "psr/log": "^1|^2|^3", + "symfony/console": "^4.4.8|^5|^6", + "symfony/event-dispatcher": "^4.4.8|^5|^6", + "symfony/finder": "^4.4.8|^5|^6" + }, + "require-dev": { + "composer-runtime-api": "^2.0", + "phpunit/phpunit": "^7.5.20 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "support": { + "issues": "https://github.com/consolidation/annotated-command/issues", + "source": "https://github.com/consolidation/annotated-command/tree/4.7.1" + }, + "time": "2022-12-06T22:57:25+00:00" + }, + { + "name": "consolidation/config", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/config.git", + "reference": "597f8d7fbeef801736250ec10c3e190569b1b0ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/config/zipball/597f8d7fbeef801736250ec10c3e190569b1b0ae", + "reference": "597f8d7fbeef801736250ec10c3e190569b1b0ae", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0 || ^2 || ^3", + "grasmash/expander": "^2.0.1 || ^3", + "php": ">=7.1.3", + "symfony/event-dispatcher": "^4 || ^5 || ^6" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": ">=7.5.20", + "squizlabs/php_codesniffer": "^3", + "symfony/console": "^4 || ^5 || ^6", + "symfony/yaml": "^4 || ^5 || ^6", + "yoast/phpunit-polyfills": "^1" + }, + "suggest": { + "symfony/event-dispatcher": "Required to inject configuration into Command options", + "symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provide configuration services for a commandline tool.", + "support": { + "issues": "https://github.com/consolidation/config/issues", + "source": "https://github.com/consolidation/config/tree/2.1.2" + }, + "time": "2022-10-06T17:48:03+00:00" + }, + { + "name": "consolidation/filter-via-dot-access-data", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/filter-via-dot-access-data.git", + "reference": "cb2eeba41f8e2e3c61698a5cf70ef048ff6c9d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/filter-via-dot-access-data/zipball/cb2eeba41f8e2e3c61698a5cf70ef048ff6c9d5b", + "reference": "cb2eeba41f8e2e3c61698a5cf70ef048ff6c9d5b", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0 || ^2.0.0 || ^3.0.0", + "php": ">=7.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.20 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Filter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "This project uses dflydev/dot-access-data to provide simple output filtering for applications built with annotated-command / Robo.", + "support": { + "source": "https://github.com/consolidation/filter-via-dot-access-data/tree/2.0.2" + }, + "time": "2021-12-30T03:56:08+00:00" + }, + { + "name": "consolidation/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "caaad9d70dae54eb49002666f000e3c607066878" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/caaad9d70dae54eb49002666f000e3c607066878", + "reference": "caaad9d70dae54eb49002666f000e3c607066878", + "shasum": "" + }, + "require": { + "php": ">=8.0.0", + "psr/log": "^3", + "symfony/console": "^5 || ^6" + }, + "require-dev": { + "phpunit/phpunit": ">=7.5.20", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "support": { + "issues": "https://github.com/consolidation/log/issues", + "source": "https://github.com/consolidation/log/tree/3.0.0" + }, + "time": "2022-04-05T16:53:32+00:00" + }, + { + "name": "consolidation/output-formatters", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "cbb50cc86775f14972003f797b61e232788bee1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/cbb50cc86775f14972003f797b61e232788bee1f", + "reference": "cbb50cc86775f14972003f797b61e232788bee1f", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0 || ^2 || ^3", + "php": ">=7.1.3", + "symfony/console": "^4|^5|^6", + "symfony/finder": "^4|^5|^6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4.2", + "phpunit/phpunit": ">=7", + "squizlabs/php_codesniffer": "^3", + "symfony/var-dumper": "^4|^5|^6", + "symfony/yaml": "^4|^5|^6", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "symfony/var-dumper": "For using the var_dump formatter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "support": { + "issues": "https://github.com/consolidation/output-formatters/issues", + "source": "https://github.com/consolidation/output-formatters/tree/4.2.3" + }, + "time": "2022-10-17T04:01:40+00:00" + }, + { + "name": "consolidation/robo", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/consolidation/robo.git", + "reference": "d655b79c8e916f9f9947df0ddc1040967ddc5a28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/robo/zipball/d655b79c8e916f9f9947df0ddc1040967ddc5a28", + "reference": "d655b79c8e916f9f9947df0ddc1040967ddc5a28", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^4.3", + "consolidation/config": "^2.0.1", + "consolidation/log": "^2.0.2 || ^3", + "consolidation/output-formatters": "^4.1.2", + "consolidation/self-update": "^2.0", + "league/container": "^3.3.1 || ^4.0", + "php": ">=8.0", + "phpowermove/docblock": "^4.0", + "symfony/console": "^6", + "symfony/event-dispatcher": "^6", + "symfony/filesystem": "^6", + "symfony/finder": "^6", + "symfony/process": "^6", + "symfony/yaml": "^6" + }, + "conflict": { + "codegyre/robo": "*" + }, + "require-dev": { + "natxet/cssmin": "3.0.4", + "patchwork/jsqueeze": "^2", + "pear/archive_tar": "^1.4.4", + "phpunit/phpunit": "^7.5.20 || ^8", + "squizlabs/php_codesniffer": "^3.6", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "natxet/cssmin": "For minifying CSS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.", + "totten/lurkerlite": "For monitoring filesystem changes in taskWatch" + }, + "bin": [ + "robo" + ], + "type": "library", + "autoload": { + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner", + "support": { + "issues": "https://github.com/consolidation/robo/issues", + "source": "https://github.com/consolidation/robo/tree/4.0.3" + }, + "time": "2022-12-07T14:13:05+00:00" + }, + { + "name": "consolidation/self-update", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/consolidation/self-update.git", + "reference": "8a64bdd8daf5faa8e85f56534dd99caf928164b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/8a64bdd8daf5faa8e85f56534dd99caf928164b3", + "reference": "8a64bdd8daf5faa8e85f56534dd99caf928164b3", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "php": ">=5.5.0", + "symfony/console": "^2.8 || ^3 || ^4 || ^5 || ^6", + "symfony/filesystem": "^2.5 || ^3 || ^4 || ^5 || ^6" + }, + "bin": [ + "scripts/release" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "SelfUpdate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander Menk", + "email": "menk@mestrona.net" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provides a self:update command for Symfony Console applications.", + "support": { + "issues": "https://github.com/consolidation/self-update/issues", + "source": "https://github.com/consolidation/self-update/tree/2.0.5" + }, + "time": "2022-02-09T22:44:24+00:00" + }, + { + "name": "consolidation/site-alias", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-alias.git", + "reference": "103fbc9bad6bbadb1f7533454a8f070ddce18e13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-alias/zipball/103fbc9bad6bbadb1f7533454a8f070ddce18e13", + "reference": "103fbc9bad6bbadb1f7533454a8f070ddce18e13", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1 || ^2", + "php": ">=7.4", + "symfony/filesystem": "^5.4 || ^6", + "symfony/finder": "^5 || ^6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4.2", + "phpunit/phpunit": ">=7", + "squizlabs/php_codesniffer": "^3", + "symfony/var-dumper": "^4", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteAlias\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "Manage alias records for local and remote sites.", + "support": { + "issues": "https://github.com/consolidation/site-alias/issues", + "source": "https://github.com/consolidation/site-alias/tree/4.0.0" + }, + "time": "2022-10-14T03:41:22+00:00" + }, + { + "name": "consolidation/site-process", + "version": "5.2.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-process.git", + "reference": "6c44638d7af8a8b4abe12c3180701243f480539d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-process/zipball/6c44638d7af8a8b4abe12c3180701243f480539d", + "reference": "6c44638d7af8a8b4abe12c3180701243f480539d", + "shasum": "" + }, + "require": { + "consolidation/config": "^2", + "consolidation/site-alias": "^3 || ^4", + "php": ">=8.0.14", + "symfony/console": "^5.4 || ^6", + "symfony/process": "^6" + }, + "require-dev": { + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "A thin wrapper around the Symfony Process Component that allows applications to use the Site Alias library to specify the target for a remote call.", + "support": { + "issues": "https://github.com/consolidation/site-process/issues", + "source": "https://github.com/consolidation/site-process/tree/5.2.0" + }, + "time": "2022-12-06T17:57:16+00:00" + }, + { + "name": "cweagans/composer-patches", + "version": "1.7.3", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "e190d4466fe2b103a55467dfa83fc2fecfcaf2db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/e190d4466fe2b103a55467dfa83fc2fecfcaf2db", + "reference": "e190d4466fe2b103a55467dfa83fc2fecfcaf2db", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0 || ~2.0", + "phpunit/phpunit": "~4.6" + }, + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages.", + "support": { + "issues": "https://github.com/cweagans/composer-patches/issues", + "source": "https://github.com/cweagans/composer-patches/tree/1.7.3" + }, + "time": "2022-12-20T22:53:13+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "time": "2023-01-05T11:28:13+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/annotations", + "version": "1.14.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", + "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1 || ^2", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "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": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.14.3" + }, + "time": "2023-02-01T09:20:38+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "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/v1.1.1" + }, + "time": "2023-06-03T09:27:29+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + }, + "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%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" + }, + { + "name": "doctrine/lexer", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" + }, + "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/2.1.0" + }, + "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": "2022-12-14T08:49:07+00:00" + }, + { + "name": "drupal/admin_denied", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/admin_denied.git", + "reference": "2.0.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/admin_denied-2.0.0.zip", + "reference": "2.0.0", + "shasum": "6a66e40a4249351a89afba529910e1e5e2f667aa" + }, + "require": { + "drupal/core": "^10" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.0.0", + "datestamp": "1674008376", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "cafuego", + "homepage": "https://www.drupal.org/user/218525" + } + ], + "description": "Prevents password based logins by uid 1.", + "homepage": "https://www.drupal.org/project/admin_denied", + "support": { + "source": "https://git.drupalcode.org/project/admin_denied" + } + }, + { + "name": "drupal/allowed_formats", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/allowed_formats.git", + "reference": "2.0.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/allowed_formats-2.0.0.zip", + "reference": "2.0.0", + "shasum": "ac6c6d398f303608ced7e9cd9d4556a728dc41f0" + }, + "require": { + "drupal/core": "^9.2 || ^10" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.0.0", + "datestamp": "1669170410", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Northern Commerce (formerly Digital Echidna)", + "homepage": "https://www.drupal.org/northern-commerce-formerly-digital-echidna", + "role": "Supporting organization" + }, + { + "name": "Jordan Thompson (nord102)", + "homepage": "https://www.drupal.org/u/nord102", + "role": "Maintainer" + }, + { + "name": "Wunder", + "homepage": "https://www.drupal.org/wunder", + "role": "Supporting organization" + }, + { + "name": "Florian Loretan (floretan)", + "homepage": "https://www.drupal.org/u/floretan", + "role": "Maintainer" + } + ], + "description": "Limit which text formats are available for each field instance.", + "homepage": "https://www.drupal.org/project/allowed_formats", + "support": { + "source": "http://cgit.drupalcode.org/allowed_formats", + "issues": "https://www.drupal.org/project/issues/allowed_formats" + } + }, + { + "name": "drupal/coder", + "version": "8.3.21", + "source": { + "type": "git", + "url": "https://github.com/pfrenssen/coder.git", + "reference": "a0b76c6c8ea277b07d58fa75dcacf102a203ad51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pfrenssen/coder/zipball/a0b76c6c8ea277b07d58fa75dcacf102a203ad51", + "reference": "a0b76c6c8ea277b07d58fa75dcacf102a203ad51", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1 || ^1.0.0", + "ext-mbstring": "*", + "php": ">=7.2", + "sirbrillig/phpcs-variable-analysis": "^2.11.7", + "slevomat/coding-standard": "^8.11", + "squizlabs/php_codesniffer": "^3.7.1", + "symfony/yaml": ">=3.4.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.7.12", + "phpunit/phpunit": "^8.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "Drupal\\": "coder_sniffer/Drupal/", + "DrupalPractice\\": "coder_sniffer/DrupalPractice/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Coder is a library to review Drupal code.", + "homepage": "https://www.drupal.org/project/coder", + "keywords": [ + "code review", + "phpcs", + "standards" + ], + "support": { + "issues": "https://www.drupal.org/project/issues/coder", + "source": "https://www.drupal.org/project/coder" + }, + "time": "2023-07-17T15:36:49+00:00" + }, + { + "name": "drupal/components", + "version": "3.0.0-beta3", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/components.git", + "reference": "3.0.0-beta3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/components-3.0.0-beta3.zip", + "reference": "3.0.0-beta3", + "shasum": "47ced4332f0a655ca38ae1b54e97a8e78d59f0bc" + }, + "require": { + "drupal/core": "^9 || ^10" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "3.0.0-beta3", + "datestamp": "1651759488", + "security-coverage": { + "status": "not-covered", + "message": "Beta releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "JohnAlbin", + "homepage": "https://www.drupal.org/user/32095", + "email": "virtually.johnalbin@gmail.com" + }, + { + "name": "RobLoach", + "homepage": "https://www.drupal.org/user/61114" + } + ], + "description": "Registers folders of components defined by your theme or module as Twig namespaces", + "homepage": "https://drupal.org/project/components", + "support": { + "source": "https://git.drupalcode.org/project/components" + } + }, + { + "name": "drupal/config_split", + "version": "2.0.0-rc4", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/config_split.git", + "reference": "2.0.0-rc4" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/config_split-2.0.0-rc4.zip", + "reference": "2.0.0-rc4", + "shasum": "d4c06efbadd34793b0c9b71772162057afa58111" + }, + "require": { + "drupal/core": "^8.8 || ^9 || ^10" + }, + "conflict": { + "drush/drush": "<10" + }, + "require-dev": { + "drupal/config_filter": "^1||^2" + }, + "suggest": { + "drupal/chosen": "Chosen uses the Chosen jQuery plugin to make the