From e26a93f7cc7ab58115870c71672276a21e187b03 Mon Sep 17 00:00:00 2001 From: Yoan Bernabeu Date: Fri, 20 Dec 2024 21:51:15 +0100 Subject: [PATCH] Initial commit --- .dockerignore | 65 + .env | 23 +- .env.test | 6 + .github/workflows/docker.yml | 45 + .github/workflows/quality.yml | 48 + .gitignore | 20 +- Dockerfile | 40 + LICENSE | 21 + Makefile | 246 + README.md | 96 + assets/app.js | 19 + assets/app_obs.js | 39 + assets/styles/app.css | 4 + assets/styles/obs.css | 117 + bin/phpunit | 23 + compose.yaml | 17 + composer.json | 49 +- composer.lock | 9928 +++++++++++++++++++--- config/bundles.php | 10 + config/packages/asset_mapper.yaml | 11 + config/packages/csrf.yaml | 11 + config/packages/debug.yaml | 5 + config/packages/doctrine.yaml | 54 + config/packages/doctrine_migrations.yaml | 6 + config/packages/mailer.yaml | 3 + config/packages/messenger.yaml | 29 + config/packages/monolog.yaml | 62 + config/packages/notifier.yaml | 12 + config/packages/security.yaml | 52 + config/packages/translation.yaml | 7 + config/packages/twig.yaml | 6 + config/packages/validator.yaml | 11 + config/packages/web_profiler.yaml | 17 + config/routes/security.yaml | 3 + config/routes/web_profiler.yaml | 8 + importmap.php | 66 + migrations/.gitignore | 0 migrations/Version20241218152147.php | 49 + migrations/Version20241219142150.php | 37 + migrations/Version20241219193957.php | 37 + package-lock.json | 171 + package.json | 5 + phpunit.xml.dist | 38 + public/img/screen1.webp | Bin 0 -> 67808 bytes src/Command/CreateUserCommand.php | 48 + src/Controller/AdminController.php | 102 + src/Controller/HomeController.php | 18 + src/Controller/ObsController.php | 36 + src/Controller/PollController.php | 64 + src/Controller/SecurityController.php | 32 + src/Entity/.gitignore | 0 src/Entity/Poll.php | 226 + src/Entity/User.php | 112 + src/Entity/Vote.php | 81 + src/Enum/FlashTypeEnum.php | 21 + src/Form/PollType.php | 65 + src/Form/VoteType.php | 43 + src/Repository/.gitignore | 0 src/Repository/PollRepository.php | 67 + src/Repository/UserRepository.php | 60 + src/Repository/VoteRepository.php | 43 + src/Service/Poll/PollService.php | 79 + src/Service/User/UserService.php | 43 + src/Service/Visitor/VisitorService.php | 54 + symfony.lock | 222 + tailwind.config.js | 11 + templates/admin/_results.html.twig | 31 + templates/admin/create.html.twig | 174 + templates/admin/index.html.twig | 261 + templates/admin/show.html.twig | 160 + templates/base.html.twig | 19 + templates/base_obs.html.twig | 15 + templates/components/_toast.html.twig | 57 + templates/home/index.html.twig | 345 + templates/obs/_results.html.twig | 41 + templates/obs/index.html.twig | 6 + templates/poll/error.html.twig | 23 + templates/poll/show.html.twig | 112 + templates/poll/success.html.twig | 40 + templates/security/login.html.twig | 51 + tests/bootstrap.php | 11 + translations/.gitignore | 0 82 files changed, 13032 insertions(+), 1257 deletions(-) create mode 100644 .dockerignore create mode 100644 .env.test create mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/quality.yml create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 assets/app.js create mode 100644 assets/app_obs.js create mode 100644 assets/styles/app.css create mode 100644 assets/styles/obs.css create mode 100755 bin/phpunit create mode 100644 compose.yaml create mode 100644 config/packages/asset_mapper.yaml create mode 100644 config/packages/csrf.yaml create mode 100644 config/packages/debug.yaml create mode 100644 config/packages/doctrine.yaml create mode 100644 config/packages/doctrine_migrations.yaml create mode 100644 config/packages/mailer.yaml create mode 100644 config/packages/messenger.yaml create mode 100644 config/packages/monolog.yaml create mode 100644 config/packages/notifier.yaml create mode 100644 config/packages/security.yaml create mode 100644 config/packages/translation.yaml create mode 100644 config/packages/twig.yaml create mode 100644 config/packages/validator.yaml create mode 100644 config/packages/web_profiler.yaml create mode 100644 config/routes/security.yaml create mode 100644 config/routes/web_profiler.yaml create mode 100644 importmap.php create mode 100644 migrations/.gitignore create mode 100644 migrations/Version20241218152147.php create mode 100644 migrations/Version20241219142150.php create mode 100644 migrations/Version20241219193957.php create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 phpunit.xml.dist create mode 100644 public/img/screen1.webp create mode 100644 src/Command/CreateUserCommand.php create mode 100644 src/Controller/AdminController.php create mode 100644 src/Controller/HomeController.php create mode 100644 src/Controller/ObsController.php create mode 100644 src/Controller/PollController.php create mode 100644 src/Controller/SecurityController.php create mode 100644 src/Entity/.gitignore create mode 100644 src/Entity/Poll.php create mode 100644 src/Entity/User.php create mode 100644 src/Entity/Vote.php create mode 100644 src/Enum/FlashTypeEnum.php create mode 100644 src/Form/PollType.php create mode 100644 src/Form/VoteType.php create mode 100644 src/Repository/.gitignore create mode 100644 src/Repository/PollRepository.php create mode 100644 src/Repository/UserRepository.php create mode 100644 src/Repository/VoteRepository.php create mode 100644 src/Service/Poll/PollService.php create mode 100644 src/Service/User/UserService.php create mode 100644 src/Service/Visitor/VisitorService.php create mode 100644 tailwind.config.js create mode 100644 templates/admin/_results.html.twig create mode 100644 templates/admin/create.html.twig create mode 100644 templates/admin/index.html.twig create mode 100644 templates/admin/show.html.twig create mode 100644 templates/base.html.twig create mode 100644 templates/base_obs.html.twig create mode 100644 templates/components/_toast.html.twig create mode 100644 templates/home/index.html.twig create mode 100644 templates/obs/_results.html.twig create mode 100644 templates/obs/index.html.twig create mode 100644 templates/poll/error.html.twig create mode 100644 templates/poll/show.html.twig create mode 100644 templates/poll/success.html.twig create mode 100644 templates/security/login.html.twig create mode 100644 tests/bootstrap.php create mode 100644 translations/.gitignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6098e57 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,65 @@ +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/config/secrets/prod/prod.decrypt.private.php +/public/bundles/ +/var/ +/vendor/ +/assets/vendor/ +###< symfony/framework-bundle ### + +###> development files ### +.git +.gitignore +.github +docker-compose*.yml +compose.yaml +Dockerfile* +.dockerignore +.env.test +phpunit.xml.dist +README.md +CHANGELOG.md +LICENSE +###< development files ### + +###> IDE files ### +.idea/ +.vscode/ +*.sublime-workspace +*.sublime-project +###< IDE files ### + +###> testing ### +/tests/ +/phpunit.xml +.phpunit.result.cache +/coverage/ +###< testing ### + +###> node ### +node_modules/ +npm-debug.log +yarn-debug.log +yarn-error.log +###< node ### + +###> misc ### +*.log +*.cache +.DS_Store +Thumbs.db +###< misc ### + +###> symfony/phpunit-bridge ### +.phpunit.result.cache +/phpunit.xml +###< symfony/phpunit-bridge ### + +###> symfony/webpack-encore-bundle ### +/node_modules/ +/public/build/ +npm-debug.log +yarn-error.log +###< symfony/webpack-encore-bundle ### diff --git a/.env b/.env index e6cabe4..687ae32 100644 --- a/.env +++ b/.env @@ -16,5 +16,26 @@ ###> symfony/framework-bundle ### APP_ENV=dev -APP_SECRET= +APP_SECRET=3ab646fbee5901930d1a63635406e1b9e2a014b405710f5bf3ca459e6da7d8e0 ###< symfony/framework-bundle ### + +###> doctrine/doctrine-bundle ### +# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml +# +DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" +# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" +# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" +#DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8" +###< doctrine/doctrine-bundle ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 +###< symfony/messenger ### + +###> symfony/mailer ### +MAILER_DSN=null://null +###< symfony/mailer ### diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..9e7162f --- /dev/null +++ b/.env.test @@ -0,0 +1,6 @@ +# define your env variables for the test env here +KERNEL_CLASS='App\Kernel' +APP_SECRET='$ecretf0rt3st' +SYMFONY_DEPRECATIONS_HELPER=999999 +PANTHER_APP_ENV=panther +PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..5ea34f8 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,45 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - "main" + tags: + - "*.*.*" + pull_request: + branches: + - "main" + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set Docker tags + id: meta + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + echo "tags=yoanbernabeu/openstreampoll:${VERSION},yoanbernabeu/openstreampoll:latest" >> $GITHUB_OUTPUT + else + echo "tags=yoanbernabeu/openstreampoll:dev" >> $GITHUB_OUTPUT + fi + + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/build-push-action@v6 + with: + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} \ No newline at end of file diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..6ca6308 --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,48 @@ +name: Quality Assurance + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + static-code-analysis: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + + - name: PHP CS Fixer + uses: docker://jakzal/phpqa:php8.3 + with: + args: php-cs-fixer fix ./src --rules=@Symfony --verbose --dry-run + + - name: PHPStan + uses: docker://jakzal/phpqa:php8.3 + with: + args: phpstan analyse ./src --level=8 + + - name: Security Check + uses: docker://jakzal/phpqa:php8.3 + with: + args: local-php-security-checker + + - name: Lint Twig + uses: docker://jakzal/phpqa:php8.3 + with: + args: bin/console lint:twig ./templates + + - name: Lint YAML + uses: docker://jakzal/phpqa:php8.3 + with: + args: bin/console lint:yaml ./config + + - name: Lint Container + uses: docker://jakzal/phpqa:php8.3 + with: + args: bin/console lint:container + + - name: Run Tests + uses: docker://jakzal/phpqa:php8.3 + with: + args: bin/phpunit --testdox \ No newline at end of file diff --git a/.gitignore b/.gitignore index a67f91e..d07f3c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - ###> symfony/framework-bundle ### /.env.local /.env.local.php @@ -7,4 +6,23 @@ /public/bundles/ /var/ /vendor/ +/node_modules/ ###< symfony/framework-bundle ### + +###> phpunit/phpunit ### +/phpunit.xml +.phpunit.result.cache +###< phpunit/phpunit ### + +###> symfony/phpunit-bridge ### +.phpunit.result.cache +/phpunit.xml +###< symfony/phpunit-bridge ### + +###> symfony/asset-mapper ### +/public/assets/ +/assets/vendor/ +###< symfony/asset-mapper ### +.php-cs-fixer.cache +compose.prod.yaml +*.bak diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..14bb10f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +# install PHP dependencies for development +FROM composer:2 AS composer_dev +WORKDIR /app +COPY composer.json composer.lock ./ +RUN composer install --no-scripts --no-progress --prefer-dist + +# install PHP dependencies for production +FROM composer:2 AS composer_prod +WORKDIR /app +COPY composer.json composer.lock ./ +RUN composer install --no-scripts --no-progress --prefer-dist --no-dev + +# install Node dependencies +FROM node:20 AS node +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm install + +# build assets +FROM dunglas/frankenphp AS build +WORKDIR /app +COPY --from=composer_dev /app/vendor /app/vendor +COPY --from=node /app/node_modules /app/node_modules +COPY . /app/ +RUN APP_ENV=prod php bin/console tailwind:build --minify +RUN APP_ENV=prod php bin/console importmap:install +RUN APP_ENV=prod php bin/console asset-map:compile + +# build the final image +FROM dunglas/frankenphp + +ENV SERVER_NAME=your-app.com +ENV APP_RUNTIME=Runtime\\FrankenPhpSymfony\\Runtime +ENV APP_ENV=prod +ENV FRANKENPHP_CONFIG="worker ./public/index.php" + +COPY . /app/ +COPY --from=composer_prod /app/vendor /app/vendor +COPY --from=node /app/node_modules /app/node_modules +COPY --from=build /app/public/assets /app/public/assets diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6b23344 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Yoan Bernabeu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..67e8864 --- /dev/null +++ b/Makefile @@ -0,0 +1,246 @@ +#---Symfony-And-Docker-Makefile---------------# +# Author: https://github.com/yoanbernabeu +# License: MIT +#---------------------------------------------# + +#---VARIABLES---------------------------------# +#---DOCKER---# +DOCKER = docker +DOCKER_RUN = $(DOCKER) run +DOCKER_COMPOSE = docker compose +DOCKER_COMPOSE_UP = $(DOCKER_COMPOSE) up -d +DOCKER_COMPOSE_STOP = $(DOCKER_COMPOSE) stop +#------------# + +#---SYMFONY--# +SYMFONY = symfony +SYMFONY_SERVER_START = $(SYMFONY) serve -d +SYMFONY_SERVER_STOP = $(SYMFONY) server:stop +SYMFONY_CONSOLE = $(SYMFONY) console +SYMFONY_LINT = $(SYMFONY_CONSOLE) lint: +#------------# + +#---COMPOSER-# +COMPOSER = composer +COMPOSER_INSTALL = $(COMPOSER) install +COMPOSER_UPDATE = $(COMPOSER) update +#------------# + +#---PHPQA---# +PHPQA = jakzal/phpqa:php8.3 +PHPQA_RUN = $(DOCKER_RUN) --init --rm -v $(PWD):/project -w /project $(PHPQA) +#------------# + +#---PHPUNIT-# +PHPUNIT = APP_ENV=test $(SYMFONY) php bin/phpunit +#------------# +#---------------------------------------------# s + +## === 🆘 HELP ================================================== +help: ## Show this help. + @echo "Symfony-And-Docker-Makefile" + @echo "---------------------------" + @echo "Usage: make [target]" + @echo "" + @echo "Targets:" + @grep -E '(^[a-zA-Z0-9_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/' +#---------------------------------------------# + +## === 🎛️ SYMFONY =============================================== +sf-start: ## Start symfony server. + $(SYMFONY_SERVER_START) +.PHONY: sf-start + +sf-stop: ## Stop symfony server. + $(SYMFONY_SERVER_STOP) +.PHONY: sf-stop + +sf-cc: ## Clear symfony cache. + $(SYMFONY_CONSOLE) cache:clear +.PHONY: sf-cc + +sf-log: ## Show symfony logs. + $(SYMFONY) server:log +.PHONY: sf-log + +sf-dc: ## Create symfony database. + $(SYMFONY_CONSOLE) doctrine:database:create +.PHONY: sf-dc + +sf-dd-test: ## Drop symfony database in test environment. + $(SYMFONY_CONSOLE) doctrine:database:drop --force --env=test +.PHONY: sf-dd-test + +sf-dc-test: ## Create symfony database in test environment. + $(SYMFONY_CONSOLE) doctrine:database:create --env=test +.PHONY: sf-dc-test + +sf-dd: ## Drop symfony database. + $(SYMFONY_CONSOLE) doctrine:database:drop --force +.PHONY: sf-dd + +sf-mm: ## Make migrations. + $(SYMFONY_CONSOLE) make:migration +.PHONY: sf-mm + +sf-dmm: ## Migrate. + $(SYMFONY_CONSOLE) doctrine:migrations:migrate --no-interaction +.PHONY: sf-dmm + +sf-dmm-test: ## Migrate in test environment. + $(SYMFONY_CONSOLE) doctrine:migrations:migrate --env=test --no-interaction +.PHONY: sf-dmm-test + +sf-dump-env: ## Dump env. + $(SYMFONY_CONSOLE) debug:dotenv +.PHONY: sf-dump-env + +sf-dump-env-container: ## Dump Env container. + $(SYMFONY_CONSOLE) debug:container --env-vars +.PHONY: sf-dump-env-container + +sf-dump-routes: ## Dump routes. + $(SYMFONY_CONSOLE) debug:router +.PHONY: sf-dump-routes + +sf-open: ## Open symfony server. + $(SYMFONY) open:local +.PHONY: sf-open + +sf-check-requirements: ## Check requirements. + $(SYMFONY) check:requirements +.PHONY: sf-check-requirements +#---------------------------------------------# + +## === 📦 COMPOSER ============================================== +composer-install: ## Install composer dependencies. + $(COMPOSER_INSTALL) +.PHONY: composer-install + +composer-update: ## Update composer dependencies. + $(COMPOSER_UPDATE) +.PHONY: composer-update +#---------------------------------------------# + +## === 📦 NPM ================================================= +npm-install: ## Install npm dependencies. + $(DOCKER_RUN) --init --rm -v $(PWD):/app -w /app node:22 npm install +.PHONY: npm-install +#---------------------------------------------# + +## === 🐛 PHPQA ================================================= +qa-cs-fixer-dry-run: ## Run php-cs-fixer in dry-run mode. + $(PHPQA_RUN) php-cs-fixer fix ./src --rules=@Symfony --verbose --dry-run +.PHONY: qa-cs-fixer-dry-run + +qa-cs-fixer: ## Run php-cs-fixer. + $(PHPQA_RUN) php-cs-fixer fix ./src --rules=@Symfony --verbose +.PHONY: qa-cs-fixer + +qa-phpstan: ## Run phpstan. + $(PHPQA_RUN) phpstan analyse ./src --level=8 +.PHONY: qa-phpstan + +qa-security-checker: ## Run security-checker. + $(SYMFONY) security:check +.PHONY: qa-security-checker + +qa-phpcpd: ## Run phpcpd (copy/paste detector). + $(PHPQA_RUN) phpcpd ./src +.PHONY: qa-phpcpd + +qa-php-metrics: ## Run php-metrics. + $(PHPQA_RUN) phpmetrics --report-html=var/phpmetrics ./src +.PHONY: qa-php-metrics + +qa-lint-twigs: ## Lint twig files. + $(SYMFONY_LINT)twig ./templates +.PHONY: qa-lint-twigs + +qa-lint-yaml: ## Lint yaml files. + $(SYMFONY_LINT)yaml ./config +.PHONY: qa-lint-yaml + +qa-lint-container: ## Lint container. + $(SYMFONY_LINT)container +.PHONY: qa-lint-container + +qa-lint-schema: ## Lint Doctrine schema. + $(SYMFONY_CONSOLE) doctrine:schema:validate --skip-sync -vvv --no-interaction +.PHONY: qa-lint-schema +#---------------------------------------------# + +## === 🔎 TESTS ================================================= +tests: ## Run tests. + $(MAKE) sf-dd-test + $(MAKE) sf-dc-test + $(MAKE) sf-dmm-test + $(PHPUNIT) --testdox +.PHONY: tests + +tests-coverage: ## Run tests with coverage. + $(MAKE) sf-dc-test + $(MAKE) sf-dmm-test + XDEBUG_MODE=coverage $(PHPUNIT) --coverage-html ./var/coverage +.PHONY: tests-coverage +#---------------------------------------------# + +## === 🚀 PROJECT =============================================== + +deploy: ## Deploy project. + @cp compose.yaml compose.prod.yaml + @read -p "Enter SERVER_NAME (e.g. example.com or :80 for no SSL): " SERVER_NAME; \ + if [ "$$SERVER_NAME" = ":80" ]; then \ + sed -i'.bak' 's/ - SERVER_NAME=.*$$/ - SERVER_NAME=:80 # without ssl\/letsencrypt/' compose.prod.yaml; \ + else \ + sed -i'.bak' 's/ - SERVER_NAME=.*$$/ - SERVER_NAME='"$$SERVER_NAME"' # for prod with ssl\/letsencrypt/' compose.prod.yaml; \ + fi; \ + rm -f compose.prod.yaml.bak + $(DOCKER_COMPOSE) -f compose.prod.yaml up -d + $(DOCKER_COMPOSE) -f compose.prod.yaml exec openstreampoll php bin/console doctrine:database:create + $(DOCKER_COMPOSE) -f compose.prod.yaml exec openstreampoll php bin/console doctrine:migrations:migrate --no-interaction + @read -p "Enter username: " USER; \ + read -p "Enter password: " PASSWORD; \ + $(DOCKER_COMPOSE) -f compose.prod.yaml exec openstreampoll php bin/console app:create-user $$USER $$PASSWORD +.PHONY: deploy + +start: ## Start project for local development. + $(MAKE) sf-dmm + $(MAKE) sf-start + $(MAKE) sf-open + $(SYMFONY_CONSOLE) tailwind:build --watch +.PHONY: start +#---------------------------------------------# + +## === ⭐ OTHER ================================================= +before-commit: ## Run before commit. + $(MAKE) qa-cs-fixer + $(MAKE) qa-phpstan + $(MAKE) qa-security-checker + $(MAKE) qa-lint-twigs + $(MAKE) qa-lint-yaml + $(MAKE) qa-lint-container + $(MAKE) qa-lint-schema + $(MAKE) tests +.PHONY: before-commit + +first-install: ## First install. + $(MAKE) composer-install + $(MAKE) npm-install + $(MAKE) sf-dc + $(MAKE) start +.PHONY: first-install + +stop: ## Stop project. + $(MAKE) sf-stop +.PHONY: stop + +reset-db: ## Reset database. + $(eval CONFIRM := $(shell read -p "Are you sure you want to reset the database? [y/N] " CONFIRM && echo $${CONFIRM:-N})) + @if [ "$(CONFIRM)" = "y" ]; then \ + $(MAKE) sf-dd; \ + $(MAKE) sf-dc; \ + $(MAKE) sf-dmm; \ + fi +.PHONY: reset-db +#---------------------------------------------# \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d823003 --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +# OpenStreamPoll + +OpenStreamPoll is an open-source live polling platform designed specifically for streamers. It empowers creators to engage their audience with instant polls, real-time results, and seamless integration with popular streaming tools. + +--- + +## Features + +- **Instant Poll Creation:** Set up live polls effortlessly with multiple customizable options. +- **Real-Time Results:** Display dynamic updates to keep your audience engaged. +- **OBS Integration:** Designed to work flawlessly with OBS for professional streams. +- **Anti-Cheat Protection:** Ensures fair and authentic voting. +- **Mobile-Friendly Interface:** Optimized for all devices, making participation easy. +- **Docker-Ready Deployment:** Simplifies setup and scalability. + +--- + +## Prerequisites for Local Development + +To get started locally, ensure you have the following installed: + +- PHP 8.3 or higher +- Composer +- Symfony CLI +- SQLite +- Make +- Docker + +--- + +## Local Development Setup + +Follow these steps to run the project locally: + +1. **Clone the Repository:** + ```bash + git clone https://github.com/yoanbernabeu/OpenStreamPoll.git + cd OpenStreamPoll + ``` + +2. **Initial Installation:** + ```bash + make first-install + ``` + +3. **Launch the Development Server:** + ```bash + make start + ``` + The application will be accessible at: `http://localhost:8000` (or an alternative port if 8000 is unavailable). + +4. **Create an Admin User:** + ```bash + symfony console app:create-user + ``` + +5. **Access the Admin Interface:** + Navigate to: `http://localhost:8000/admin` + +--- + +## Production Deployment + +> **Note:** Secure your server before deploying this application to production. If you are not familiar with server security best practices, consider using a managed hosting provider. + +1. **Clone the Repository:** + ```bash + git clone https://github.com/yoanbernabeu/OpenStreamPoll.git + cd OpenStreamPoll + ``` + +2. **Start the Application:** + ```bash + make deploy + ``` + +--- + +## Usage Guide + +1. **Create a Poll:** Use the admin interface to set up a new poll. +2. **Share the Link:** Distribute the poll's public URL to your audience. +3. **Monitor Results:** View live updates to track audience responses. +4. **Stream Results:** Seamlessly display live results during your stream. + +--- + +## Contributing + +Currently, contributions are not being accepted as this is a personal project shared for public use. While PRs are welcome, they may not be actively managed at this time. + +--- + +## License + +OpenStreamPoll is open-source and distributed under the [MIT License](LICENSE). \ No newline at end of file diff --git a/assets/app.js b/assets/app.js new file mode 100644 index 0000000..d33ca46 --- /dev/null +++ b/assets/app.js @@ -0,0 +1,19 @@ +/* + * Welcome to your app's main JavaScript file! + * + * This file will be included onto the page via the importmap() Twig function, + * which should already be in your base.html.twig. + */ +import './styles/app.css'; + +import Alpine from 'alpinejs' +window.Alpine = Alpine +Alpine.start() + +import 'htmx.org'; +import htmx from 'htmx.org'; +window.htmx = htmx; + +// Export Fireworks pour l'utiliser dans les templates +import { Fireworks } from 'fireworks-js' +window.Fireworks = Fireworks; \ No newline at end of file diff --git a/assets/app_obs.js b/assets/app_obs.js new file mode 100644 index 0000000..df06627 --- /dev/null +++ b/assets/app_obs.js @@ -0,0 +1,39 @@ +import './styles/obs.css'; +import 'htmx.org'; +import Alpine from 'alpinejs'; + +window.Alpine = Alpine; + +document.addEventListener('alpine:init', () => { + Alpine.data('timer', (endDate) => ({ + minutes: '00', + seconds: '00', + isExpired: false, + + init() { + this.updateTimer() + setInterval(() => this.updateTimer(), 1000) + }, + + updateTimer() { + const end = new Date(endDate) + const now = new Date() + const diff = end - now + + if (diff <= 0) { + this.isExpired = true + this.minutes = '00' + this.seconds = '00' + return + } + + const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)) + const seconds = Math.floor((diff % (1000 * 60)) / 1000) + + this.minutes = minutes.toString().padStart(2, '0') + this.seconds = seconds.toString().padStart(2, '0') + } + })) +}); + +Alpine.start(); diff --git a/assets/styles/app.css b/assets/styles/app.css new file mode 100644 index 0000000..a90f074 --- /dev/null +++ b/assets/styles/app.css @@ -0,0 +1,4 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + diff --git a/assets/styles/obs.css b/assets/styles/obs.css new file mode 100644 index 0000000..1397ddc --- /dev/null +++ b/assets/styles/obs.css @@ -0,0 +1,117 @@ +body { + margin: 0; + padding: 0; + background: transparent !important; +} + +.results-container { + background-color: rgba(0, 0, 0, 0.96); /* Augmenté de 0.92 à 0.96 pour plus d'opacité */ + padding: 30px; + border-radius: 12px; + color: white; + font-family: system-ui, sans-serif; + width: 100%; /* Remplace la largeur fixe */ + max-width: 1200px; /* Largeur maximum */ + border: 2px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); + margin: 0 auto; /* Centre le conteneur */ +} + +/* Suppression de .choices-grid qui utilisait grid */ + +.title { + font-size: clamp(24px, 4vw, 32px); /* Responsive font-size */ + font-weight: bold; + margin-bottom: 20px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); +} + +.timer { + font-family: 'Courier New', monospace; + font-size: clamp(28px, 3.5vw, 36px); /* Responsive font-size */ + font-weight: bold; + color: #4f46e5; + text-shadow: 0 0 10px rgba(79, 70, 229, 0.3); + background: rgba(0, 0, 0, 0.2); + padding: 5px 15px; + border-radius: 6px; +} + +.choice { + font-size: clamp(20px, 3vw, 28px); /* Responsive font-size */ + margin-bottom: 28px; /* Augmenté pour plus d'espacement */ +} + +.badge { + background: #4f46e5; + color: white; + padding: 2px 8px; + border-radius: 4px; + font-size: 0.875rem; +} + +.progress { + width: 100%; + height: clamp(24px, 3vw, 36px); /* Responsive height */ + margin: 10px 0; + border-radius: 6px; +} + +progress { + background: rgba(255, 255, 255, 0.1); +} + +progress::-webkit-progress-bar { + background: rgba(255, 255, 255, 0.1); + border-radius: 6px; +} + +progress::-webkit-progress-value { + background: linear-gradient(90deg, #4f46e5, #6366f1); + border-radius: 6px; + transition: width 0.3s ease; +} + +progress::-moz-progress-bar { + background: linear-gradient(90deg, #4f46e5, #6366f1); + border-radius: 6px; +} + +.percentage { + font-size: clamp(18px, 2.5vw, 26px); /* Responsive font-size */ + color: rgba(255, 255, 255, 0.9); + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); +} + +.vote-count { + font-size: clamp(20px, 3vw, 28px); /* Responsive font-size */ + color: #4f46e5; + font-weight: bold; + background: rgba(79, 70, 229, 0.1); + padding: 5px 15px; /* Padding augmenté pour mieux encadrer le nombre */ + border-radius: 4px; + border: 1px solid rgba(79, 70, 229, 0.2); +} + +.total-votes { + font-size: clamp(16px, 2vw, 20px); /* Responsive font-size */ + color: rgba(255, 255, 255, 0.7); + margin-top: 20px; +} + +/* Media queries pour ajuster les espacements */ +@media (max-width: 768px) { + .results-container { + padding: 20px; + } + + .choice { + margin-bottom: 20px; + } +} + +@media (max-width: 480px) { + .results-container { + padding: 15px; + } +} diff --git a/bin/phpunit b/bin/phpunit new file mode 100755 index 0000000..692bacc --- /dev/null +++ b/bin/phpunit @@ -0,0 +1,23 @@ +#!/usr/bin/env php += 80000) { + require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit'; + } else { + define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php'); + require PHPUNIT_COMPOSER_INSTALL; + PHPUnit\TextUI\Command::main(); + } +} else { + if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) { + echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n"; + exit(1); + } + + require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php'; +} diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..2b53bea --- /dev/null +++ b/compose.yaml @@ -0,0 +1,17 @@ +services: + openstreampoll: + image: yoanbernabeu/openstreampoll:latest + restart: unless-stopped + ports: + - "80:80" + - "443:443" + environment: + - APP_ENV=prod + - SERVER_NAME=yourdomain.com # for prod with ssl/letsencrypt + volumes: + - database_data:/var/www/openstreampoll/var/sqlite + +volumes: +###> doctrine/doctrine-bundle ### + database_data: +###< doctrine/doctrine-bundle ### diff --git a/composer.json b/composer.json index d51a94e..ebe425c 100644 --- a/composer.json +++ b/composer.json @@ -7,14 +7,44 @@ "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", + "doctrine/dbal": "^3", + "doctrine/doctrine-bundle": "^2.13", + "doctrine/doctrine-migrations-bundle": "^3.3", + "doctrine/orm": "^3.3", + "phpdocumentor/reflection-docblock": "^5.6", + "phpstan/phpdoc-parser": "^2.0", + "runtime/frankenphp-symfony": "^0.2.0", + "symfony/asset": "7.2.*", + "symfony/asset-mapper": "7.2.*", "symfony/console": "7.2.*", + "symfony/doctrine-messenger": "7.2.*", "symfony/dotenv": "7.2.*", + "symfony/expression-language": "7.2.*", "symfony/flex": "^2", + "symfony/form": "7.2.*", "symfony/framework-bundle": "7.2.*", + "symfony/http-client": "7.2.*", + "symfony/intl": "7.2.*", + "symfony/mailer": "7.2.*", + "symfony/mime": "7.2.*", + "symfony/monolog-bundle": "^3.0", + "symfony/notifier": "7.2.*", + "symfony/process": "7.2.*", + "symfony/property-access": "7.2.*", + "symfony/property-info": "7.2.*", "symfony/runtime": "7.2.*", - "symfony/yaml": "7.2.*" - }, - "require-dev": { + "symfony/security-bundle": "7.2.*", + "symfony/serializer": "7.2.*", + "symfony/string": "7.2.*", + "symfony/translation": "7.2.*", + "symfony/twig-bundle": "7.2.*", + "symfony/validator": "7.2.*", + "symfony/web-link": "7.2.*", + "symfony/yaml": "7.2.*", + "symfonycasts/tailwind-bundle": "^0.6.1", + "twig/extra-bundle": "^2.12|^3.0", + "twig/string-extra": "^3.17", + "twig/twig": "^2.12|^3.0" }, "config": { "allow-plugins": { @@ -48,7 +78,8 @@ "scripts": { "auto-scripts": { "cache:clear": "symfony-cmd", - "assets:install %PUBLIC_DIR%": "symfony-cmd" + "assets:install %PUBLIC_DIR%": "symfony-cmd", + "importmap:install": "symfony-cmd" }, "post-install-cmd": [ "@auto-scripts" @@ -65,5 +96,15 @@ "allow-contrib": false, "require": "7.2.*" } + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "symfony/browser-kit": "7.2.*", + "symfony/css-selector": "7.2.*", + "symfony/debug-bundle": "7.2.*", + "symfony/maker-bundle": "^1.0", + "symfony/phpunit-bridge": "^7.2", + "symfony/stopwatch": "7.2.*", + "symfony/web-profiler-bundle": "7.2.*" } } diff --git a/composer.lock b/composer.lock index ca6b45d..9a1afc3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,34 +4,38 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7fa7ba6bb5f8b40063b77f1ecd789779", + "content-hash": "40823ac0a24a9f1dc85cbd2c8075caed", "packages": [ { - "name": "psr/cache", - "version": "3.0.0", + "name": "composer/semver", + "version": "3.4.3", "source": { "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { - "php": ">=8.0.0" + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Cache\\": "src/" + "Composer\\Semver\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -40,47 +44,81 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "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": "Common interface for caching libraries", + "description": "Semver library that offers utilities, version constraint parsing and validation.", "keywords": [ - "cache", - "psr", - "psr-6" + "semantic", + "semver", + "validation", + "versioning" ], "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" }, - "time": "2021-02-03T23:26:27+00:00" + "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": "2024-09-19T14:15:21+00:00" }, { - "name": "psr/container", - "version": "2.0.2", + "name": "doctrine/cache", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { - "php": ">=7.4.0" + "php": "~7.1 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } }, "notification-url": "https://packagist.org/downloads/", @@ -89,51 +127,89 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "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": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" ], "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, - "time": "2021-11-05T16:47:00+00:00" + "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%2Fcache", + "type": "tidelift" + } + ], + "time": "2022-05-20T20:07:39+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "doctrine/collections", + "version": "2.2.2", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/doctrine/collections.git", + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/doctrine/collections/zipball/d8af7f248c74f195f7347424600fd9e17b57af59", + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59", "shasum": "" }, "require": { - "php": ">=7.2.0" + "doctrine/deprecations": "^1", + "php": "^8.1" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "doctrine/coding-standard": "^12", + "ext-json": "*", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.11" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\EventDispatcher\\": "src/" + "Doctrine\\Common\\Collections\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -142,48 +218,101 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "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": "Standard interfaces for event handling.", + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", "keywords": [ - "events", - "psr", - "psr-14" + "array", + "collections", + "iterators", + "php" ], "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/2.2.2" }, - "time": "2019-01-08T18:20:26+00:00" + "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%2Fcollections", + "type": "tidelift" + } + ], + "time": "2024-04-18T06:56:21+00:00" }, { - "name": "psr/log", - "version": "3.0.2", + "name": "doctrine/dbal", + "version": "3.9.3", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + "url": "https://github.com/doctrine/dbal.git", + "reference": "61446f07fcb522414d6cfd8b1c3e5f9e18c579ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/61446f07fcb522414d6cfd8b1c3e5f9e18c579ba", + "reference": "61446f07fcb522414d6cfd8b1c3e5f9e18c579ba", "shasum": "" }, "require": { - "php": ">=8.0.0" + "composer-runtime-api": "^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1|^2", + "php": "^7.4 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } + "require-dev": { + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.1", + "phpstan/phpstan": "1.12.6", + "phpstan/phpstan-strict-rules": "^1.6", + "phpunit/phpunit": "9.6.20", + "psalm/plugin-phpunit": "0.18.4", + "slevomat/coding-standard": "8.13.1", + "squizlabs/php_codesniffer": "3.10.2", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/console": "^4.4|^5.4|^6.0|^7.0", + "vimeo/psalm": "4.30.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", "autoload": { "psr-4": { - "Psr\\Log\\": "src" + "Doctrine\\DBAL\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -192,80 +321,178 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "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" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", "keywords": [ - "log", - "psr", - "psr-3" + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.9.3" }, - "time": "2024-09-11T13:17:53+00:00" + "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%2Fdbal", + "type": "tidelift" + } + ], + "time": "2024-10-10T17:56:43+00:00" }, { - "name": "symfony/cache", - "version": "v7.2.1", + "name": "doctrine/deprecations", + "version": "1.1.4", "source": { "type": "git", - "url": "https://github.com/symfony/cache.git", - "reference": "e7e983596b744c4539f31e79b0350a6cf5878a20" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/e7e983596b744c4539f31e79b0350a6cf5878a20", - "reference": "e7e983596b744c4539f31e79b0350a6cf5878a20", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/cache": "^2.0|^3.0", - "psr/log": "^1.1|^2|^3", - "symfony/cache-contracts": "^2.5|^3", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/var-exporter": "^6.4|^7.0" + "php": "^7.1 || ^8.0" }, - "conflict": { - "doctrine/dbal": "<3.6", - "symfony/dependency-injection": "<6.4", - "symfony/http-kernel": "<6.4", - "symfony/var-dumper": "<6.4" + "require-dev": { + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/log": "^1 || ^2 || ^3" }, - "provide": { - "psr/cache-implementation": "2.0|3.0", - "psr/simple-cache-implementation": "1.0|2.0|3.0", - "symfony/cache-implementation": "1.1|2.0|3.0" + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" + }, + "time": "2024-12-07T21:18:45+00:00" + }, + { + "name": "doctrine/doctrine-bundle", + "version": "2.13.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "2740ad8b8739b39ab37d409c972b092f632b025a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/2740ad8b8739b39ab37d409c972b092f632b025a", + "reference": "2740ad8b8739b39ab37d409c972b092f632b025a", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/dbal": "^3.7.0 || ^4.0", + "doctrine/persistence": "^2.2 || ^3", + "doctrine/sql-formatter": "^1.0.1", + "php": "^7.4 || ^8.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/doctrine-bridge": "^5.4.46 || ^6.4.3 || ^7.0.3", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" + }, + "conflict": { + "doctrine/annotations": ">=3.0", + "doctrine/orm": "<2.17 || >=4.0", + "twig/twig": "<1.34 || >=2.0 <2.4" }, "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/dbal": "^3.6|^4", - "predis/predis": "^1.1|^2.0", - "psr/simple-cache": "^1.0|^2.0|^3.0", - "symfony/clock": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/filesystem": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "doctrine/annotations": "^1 || ^2", + "doctrine/coding-standard": "^12", + "doctrine/deprecations": "^1.0", + "doctrine/orm": "^2.17 || ^3.0", + "friendsofphp/proxy-manager-lts": "^1.0", + "phpunit/phpunit": "^9.5.26", + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^5", + "psr/log": "^1.1.4 || ^2.0 || ^3.0", + "symfony/phpunit-bridge": "^6.1 || ^7.0", + "symfony/property-info": "^5.4 || ^6.0 || ^7.0", + "symfony/proxy-manager-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/security-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^5.4 || ^6.2 || ^7.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0", + "twig/twig": "^1.34 || ^2.12 || ^3.0", + "vimeo/psalm": "^5.15" }, - "type": "library", + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", + "ext-pdo": "*", + "symfony/web-profiler-bundle": "To use the data collector." + }, + "type": "symfony-bundle", "autoload": { "psr-4": { - "Symfony\\Component\\Cache\\": "" - }, - "classmap": [ - "Traits/ValueWrapper.php" - ], - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Bundle\\DoctrineBundle\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -273,71 +500,96 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" + }, + { + "name": "Doctrine Project", + "homepage": "https://www.doctrine-project.org/" } ], - "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", - "homepage": "https://symfony.com", + "description": "Symfony DoctrineBundle", + "homepage": "https://www.doctrine-project.org", "keywords": [ - "caching", - "psr6" + "database", + "dbal", + "orm", + "persistence" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.2.1" + "issues": "https://github.com/doctrine/DoctrineBundle/issues", + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.13.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-bundle", "type": "tidelift" } ], - "time": "2024-12-07T08:08:50+00:00" + "time": "2024-11-08T23:27:54+00:00" }, { - "name": "symfony/cache-contracts", - "version": "v3.5.1", + "name": "doctrine/doctrine-migrations-bundle", + "version": "3.3.1", "source": { "type": "git", - "url": "https://github.com/symfony/cache-contracts.git", - "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b" + "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", + "reference": "715b62c31a5894afcb2b2cdbbc6607d7dd0580c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", - "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/715b62c31a5894afcb2b2cdbbc6607d7dd0580c0", + "reference": "715b62c31a5894afcb2b2cdbbc6607d7dd0580c0", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/cache": "^3.0" + "doctrine/doctrine-bundle": "^2.4", + "doctrine/migrations": "^3.2", + "php": "^7.2|^8.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "composer/semver": "^3.0", + "doctrine/coding-standard": "^12", + "doctrine/orm": "^2.6 || ^3", + "doctrine/persistence": "^2.0 || ^3 ", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^8.5|^9.5", + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^3 || ^5", + "symfony/phpunit-bridge": "^6.3 || ^7", + "symfony/var-exporter": "^5.4 || ^6 || ^7", + "vimeo/psalm": "^4.30 || ^5.15" }, + "type": "symfony-bundle", "autoload": { "psr-4": { - "Symfony\\Contracts\\Cache\\": "" - } + "Doctrine\\Bundle\\MigrationsBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -345,82 +597,76 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Doctrine Project", + "homepage": "https://www.doctrine-project.org" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to caching", - "homepage": "https://symfony.com", + "description": "Symfony DoctrineMigrationsBundle", + "homepage": "https://www.doctrine-project.org", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "dbal", + "migrations", + "schema" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.5.1" + "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues", + "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.3.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-migrations-bundle", "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-05-14T20:32:18+00:00" }, { - "name": "symfony/config", - "version": "v7.2.0", + "name": "doctrine/event-manager", + "version": "2.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" + "url": "https://github.com/doctrine/event-manager.git", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", - "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^7.1", - "symfony/polyfill-ctype": "~1.8" + "php": "^8.1" }, "conflict": { - "symfony/finder": "<6.4", - "symfony/service-contracts": "<2.5" + "doctrine/common": "<2.9" }, "require-dev": { - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Common\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -428,86 +674,89 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" } ], - "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", - "homepage": "https://symfony.com", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], "support": { - "source": "https://github.com/symfony/config/tree/v7.2.0" + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", "type": "tidelift" } ], - "time": "2024-11-04T11:36:24+00:00" + "time": "2024-05-22T20:47:39+00:00" }, { - "name": "symfony/console", - "version": "v7.2.1", + "name": "doctrine/inflector", + "version": "2.0.10", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" - }, - "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -515,85 +764,92 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "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": "Eases the creation of beautiful and testable command line interfaces", - "homepage": "https://symfony.com", + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", "keywords": [ - "cli", - "command-line", - "console", - "terminal" + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.1" + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", "type": "tidelift" } ], - "time": "2024-12-11T03:49:26+00:00" + "time": "2024-02-18T20:23:39+00:00" }, { - "name": "symfony/dependency-injection", - "version": "v7.2.0", + "name": "doctrine/instantiator", + "version": "2.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a475747af1a1c98272a5471abc35f3da81197c5d" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a475747af1a1c98272a5471abc35f3da81197c5d", - "reference": "a475747af1a1c98272a5471abc35f3da81197c5d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/service-contracts": "^3.5", - "symfony/var-exporter": "^6.4|^7.0" - }, - "conflict": { - "ext-psr": "<1.1|>=2", - "symfony/config": "<6.4", - "symfony/finder": "<6.4", - "symfony/yaml": "<6.4" - }, - "provide": { - "psr/container-implementation": "1.1|2.0", - "symfony/service-implementation": "1.1|2.0|3.0" + "php": "^8.1" }, "require-dev": { - "symfony/config": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0" + "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": { - "Symfony\\Component\\DependencyInjection\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -601,66 +857,66 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" } ], - "description": "Allows you to standardize and centralize the way objects are constructed in your application", - "homepage": "https://symfony.com", + "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": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0" + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", "type": "tidelift" } ], - "time": "2024-11-25T15:45:00+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "name": "doctrine/lexer", + "version": "3.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", "shasum": "" }, "require": { - "php": ">=8.1" + "php": "^8.1" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" }, + "type": "library", "autoload": { - "files": [ - "function.php" - ] + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -668,68 +924,104 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.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": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-02-05T11:56:58+00:00" }, { - "name": "symfony/dotenv", - "version": "v7.2.0", + "name": "doctrine/migrations", + "version": "3.8.2", "source": { "type": "git", - "url": "https://github.com/symfony/dotenv.git", - "reference": "28347a897771d0c28e99b75166dd2689099f3045" + "url": "https://github.com/doctrine/migrations.git", + "reference": "5007eb1168691225ac305fe16856755c20860842" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/28347a897771d0c28e99b75166dd2689099f3045", - "reference": "28347a897771d0c28e99b75166dd2689099f3045", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/5007eb1168691225ac305fe16856755c20860842", + "reference": "5007eb1168691225ac305fe16856755c20860842", "shasum": "" }, "require": { - "php": ">=8.2" + "composer-runtime-api": "^2", + "doctrine/dbal": "^3.6 || ^4", + "doctrine/deprecations": "^0.5.3 || ^1", + "doctrine/event-manager": "^1.2 || ^2.0", + "php": "^8.1", + "psr/log": "^1.1.3 || ^2 || ^3", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.2 || ^7.0" }, "conflict": { - "symfony/console": "<6.4", - "symfony/process": "<6.4" + "doctrine/orm": "<2.12 || >=4" }, "require-dev": { - "symfony/console": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0" + "doctrine/coding-standard": "^12", + "doctrine/orm": "^2.13 || ^3", + "doctrine/persistence": "^2 || ^3", + "doctrine/sql-formatter": "^1.0", + "ext-pdo_sqlite": "*", + "fig/log-test": "^1", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.4", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^10.3", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "doctrine/sql-formatter": "Allows to generate formatted SQL with the diff command.", + "symfony/yaml": "Allows the use of yaml for migration configuration files." }, + "bin": [ + "bin/doctrine-migrations" + ], "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Dotenv\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Migrations\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -737,79 +1029,97 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Michael Simonson", + "email": "contact@mikesimonson.com" } ], - "description": "Registers environment variables from a .env file", - "homepage": "https://symfony.com", + "description": "PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying changes to it. It is a very easy to use and a powerful tool.", + "homepage": "https://www.doctrine-project.org/projects/migrations.html", "keywords": [ - "dotenv", - "env", - "environment" + "database", + "dbal", + "migrations" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.2.0" + "issues": "https://github.com/doctrine/migrations/issues", + "source": "https://github.com/doctrine/migrations/tree/3.8.2" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fmigrations", "type": "tidelift" } ], - "time": "2024-11-27T11:18:42+00:00" + "time": "2024-10-10T21:35:27+00:00" }, { - "name": "symfony/error-handler", - "version": "v7.2.1", + "name": "doctrine/orm", + "version": "3.3.0", "source": { "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "6150b89186573046167796fa5f3f76601d5145f8" + "url": "https://github.com/doctrine/orm.git", + "reference": "69958152e661aa9c14e80d1ee4962863485aa60b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/6150b89186573046167796fa5f3f76601d5145f8", - "reference": "6150b89186573046167796fa5f3f76601d5145f8", + "url": "https://api.github.com/repos/doctrine/orm/zipball/69958152e661aa9c14e80d1ee4962863485aa60b", + "reference": "69958152e661aa9c14e80d1ee4962863485aa60b", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^6.4|^7.0" - }, - "conflict": { - "symfony/deprecation-contracts": "<2.5", - "symfony/http-kernel": "<6.4" + "composer-runtime-api": "^2", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.8.2 || ^4", + "doctrine/deprecations": "^0.5.3 || ^1", + "doctrine/event-manager": "^1.2 || ^2", + "doctrine/inflector": "^1.4 || ^2.0", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^3", + "doctrine/persistence": "^3.3.1", + "ext-ctype": "*", + "php": "^8.1", + "psr/cache": "^1 || ^2 || ^3", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.3.9 || ^7.0" }, "require-dev": { - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0" + "doctrine/coding-standard": "^12.0", + "phpbench/phpbench": "^1.0", + "phpdocumentor/guides-cli": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "1.12.6", + "phpstan/phpstan-deprecation-rules": "^1.2", + "phpunit/phpunit": "^10.4.0", + "psr/log": "^1 || ^2 || ^3", + "squizlabs/php_codesniffer": "3.7.2", + "symfony/cache": "^5.4 || ^6.2 || ^7.0", + "vimeo/psalm": "5.24.0" + }, + "suggest": { + "ext-dom": "Provides support for XSD validation for XML mapping files", + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, - "bin": [ - "Resources/bin/patch-type-declarations" - ], "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\ErrorHandler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\ORM\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -817,79 +1127,74 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools to manage errors and ease debugging PHP code", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.2.1" - }, - "funding": [ + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, { - "url": "https://symfony.com/sponsor", - "type": "custom" + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" }, { - "url": "https://github.com/fabpot", - "type": "github" + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" } ], - "time": "2024-12-07T08:50:44+00:00" + "description": "Object-Relational-Mapper for PHP", + "homepage": "https://www.doctrine-project.org/projects/orm.html", + "keywords": [ + "database", + "orm" + ], + "support": { + "issues": "https://github.com/doctrine/orm/issues", + "source": "https://github.com/doctrine/orm/tree/3.3.0" + }, + "time": "2024-10-12T20:07:18+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v7.2.0", + "name": "doctrine/persistence", + "version": "3.4.0", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + "url": "https://github.com/doctrine/persistence.git", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/event-dispatcher-contracts": "^2.5|^3" + "doctrine/event-manager": "^1 || ^2", + "php": "^7.2 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0" }, "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" + "doctrine/common": "<2.10" }, "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/error-handler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" + "doctrine/coding-standard": "^12", + "doctrine/common": "^3.0", + "phpstan/phpstan": "1.12.7", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5.38 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Doctrine\\Persistence\\": "src/Persistence" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -897,66 +1202,90 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" } ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "homepage": "https://www.doctrine-project.org/projects/persistence.html", + "keywords": [ + "mapper", + "object", + "odm", + "orm", + "persistence" + ], "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/3.4.0" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.doctrine-project.org/sponsorship.html", "type": "custom" }, { - "url": "https://github.com/fabpot", - "type": "github" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2024-10-30T19:48:12+00:00" }, { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.1", + "name": "doctrine/sql-formatter", + "version": "1.5.1", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + "url": "https://github.com/doctrine/sql-formatter.git", + "reference": "b784cbde727cf806721451dde40eff4fec3bbe86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/b784cbde727cf806721451dde40eff4fec3bbe86", + "reference": "b784cbde727cf806721451dde40eff4fec3bbe86", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" + "php": "^8.1" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "require-dev": { + "doctrine/coding-standard": "^12", + "ergebnis/phpunit-slow-test-detector": "^2.14", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, + "bin": [ + "bin/sql-formatter" + ], + "type": "library", "autoload": { "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" + "Doctrine\\SqlFormatter\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -965,73 +1294,59 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "https://jeremydorn.com/" } ], - "description": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", + "description": "a PHP SQL highlighting library", + "homepage": "https://github.com/doctrine/sql-formatter/", "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" + "highlight", + "sql" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + "issues": "https://github.com/doctrine/sql-formatter/issues", + "source": "https://github.com/doctrine/sql-formatter/tree/1.5.1" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-10-21T18:21:57+00:00" }, { - "name": "symfony/filesystem", - "version": "v7.2.0", + "name": "egulias/email-validator", + "version": "4.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8" + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Egulias\\EmailValidator\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1039,63 +1354,98 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Eduardo Gulias Davis" } ], - "description": "Provides basic utilities for the filesystem", - "homepage": "https://symfony.com", + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.2" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/egulias", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-10-25T15:15:23+00:00" + "time": "2023-10-06T06:47:41+00:00" }, { - "name": "symfony/finder", - "version": "v7.2.0", + "name": "monolog/monolog", + "version": "3.8.1", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" + "url": "https://github.com/Seldaek/monolog.git", + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", - "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0" + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Monolog\\": "src/Monolog" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1103,70 +1453,60 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" } ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], "support": { - "source": "https://github.com/symfony/finder/tree/v7.2.0" + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.8.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" + "url": "https://github.com/Seldaek", + "type": "github" }, { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", "type": "tidelift" } ], - "time": "2024-10-23T06:56:12+00:00" + "time": "2024-12-05T17:15:07+00:00" }, { - "name": "symfony/flex", - "version": "v2.4.7", + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/flex.git", - "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402" + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/92f4fba342161ff36072bd3b8e0b3c6c23160402", - "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "composer-plugin-api": "^2.1", - "php": ">=8.0" - }, - "conflict": { - "composer/semver": "<1.7.2" - }, - "require-dev": { - "composer/composer": "^2.1", - "symfony/dotenv": "^5.4|^6.0", - "symfony/filesystem": "^5.4|^6.0", - "symfony/phpunit-bridge": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0" + "php": "^7.2 || ^8.0" }, - "type": "composer-plugin", + "type": "library", "extra": { - "class": "Symfony\\Flex\\Flex" + "branch-alias": { + "dev-2.x": "2.x-dev" + } }, "autoload": { "psr-4": { - "Symfony\\Flex\\": "src" + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1175,145 +1515,67 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien.potencier@gmail.com" + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" } ], - "description": "Composer plugin for Symfony", + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], "support": { - "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v2.4.7" + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-10-07T08:51:54+00:00" + "time": "2020-06-27T09:03:43+00:00" }, { - "name": "symfony/framework-bundle", - "version": "v7.2.1", + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.1", "source": { "type": "git", - "url": "https://github.com/symfony/framework-bundle.git", - "reference": "1c630f4697c9bd87b342e8090cc9022071af4d77" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/1c630f4697c9bd87b342e8090cc9022071af4d77", - "reference": "1c630f4697c9bd87b342e8090cc9022071af4d77", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", "shasum": "" }, "require": { - "composer-runtime-api": ">=2.1", - "ext-xml": "*", - "php": ">=8.2", - "symfony/cache": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^7.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/filesystem": "^7.1", - "symfony/finder": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^7.2", - "symfony/polyfill-mbstring": "~1.0", - "symfony/routing": "^6.4|^7.0" - }, - "conflict": { - "doctrine/persistence": "<1.3", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/asset": "<6.4", - "symfony/asset-mapper": "<6.4", - "symfony/clock": "<6.4", - "symfony/console": "<6.4", - "symfony/dom-crawler": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/form": "<6.4", - "symfony/http-client": "<6.4", - "symfony/lock": "<6.4", - "symfony/mailer": "<6.4", - "symfony/messenger": "<6.4", - "symfony/mime": "<6.4", - "symfony/property-access": "<6.4", - "symfony/property-info": "<6.4", - "symfony/runtime": "<6.4.13|>=7.0,<7.1.6", - "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", - "symfony/security-core": "<6.4", - "symfony/security-csrf": "<7.2", - "symfony/serializer": "<7.1", - "symfony/stopwatch": "<6.4", - "symfony/translation": "<6.4", - "symfony/twig-bridge": "<6.4", - "symfony/twig-bundle": "<6.4", - "symfony/validator": "<6.4", - "symfony/web-profiler-bundle": "<6.4", - "symfony/webhook": "<7.2", - "symfony/workflow": "<6.4" + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1" }, "require-dev": { - "doctrine/persistence": "^1.3|^2|^3", - "dragonmantank/cron-expression": "^3.1", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "seld/jsonlint": "^1.10", - "symfony/asset": "^6.4|^7.0", - "symfony/asset-mapper": "^6.4|^7.0", - "symfony/browser-kit": "^6.4|^7.0", - "symfony/clock": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/dom-crawler": "^6.4|^7.0", - "symfony/dotenv": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/form": "^6.4|^7.0", - "symfony/html-sanitizer": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/mailer": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", - "symfony/notifier": "^6.4|^7.0", - "symfony/polyfill-intl-icu": "~1.0", - "symfony/process": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0", - "symfony/scheduler": "^6.4.4|^7.0.4", - "symfony/security-bundle": "^6.4|^7.0", - "symfony/semaphore": "^6.4|^7.0", - "symfony/serializer": "^7.1", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/string": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", - "symfony/twig-bundle": "^6.4|^7.0", - "symfony/type-info": "^7.1", - "symfony/uid": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0", - "symfony/web-link": "^6.4|^7.0", - "symfony/webhook": "^7.2", - "symfony/workflow": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0", - "twig/twig": "^3.12" + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } }, - "type": "symfony-bundle", "autoload": { "psr-4": { - "Symfony\\Bundle\\FrameworkBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "phpDocumentor\\Reflection\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1321,77 +1583,61 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Mike van Riel", + "email": "me@mikevanriel.com" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" } ], - "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", - "homepage": "https://symfony.com", + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.2.1" + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-12-07T13:24:01+00:00" + "time": "2024-12-07T09:39:29+00:00" }, { - "name": "symfony/http-foundation", - "version": "v7.2.0", + "name": "phpdocumentor/type-resolver", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", - "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php83": "^1.27" - }, - "conflict": { - "doctrine/dbal": "<3.6", - "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { - "doctrine/dbal": "^3.6|^4", - "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4.12|^7.1.5", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0" + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "phpDocumentor\\Reflection\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1399,421 +1645,7657 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Mike van Riel", + "email": "me@mikevanriel.com" } ], - "description": "Defines an object-oriented layer for the HTTP specification", - "homepage": "https://symfony.com", + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.2.0" + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-11-13T18:58:46+00:00" + "time": "2024-11-09T15:12:26+00:00" }, { - "name": "symfony/http-kernel", - "version": "v7.2.1", + "name": "phpstan/phpdoc-parser", + "version": "2.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97" + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d8ae58eecae44c8e66833e76cc50a4ad3c002d97", - "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/polyfill-ctype": "^1.8" + "php": "^7.4 || ^8.0" }, - "conflict": { - "symfony/browser-kit": "<6.4", - "symfony/cache": "<6.4", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<6.4", + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0" + }, + "time": "2024-10-13T11:29:49+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/link", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/link.git", + "reference": "84b159194ecfd7eaa472280213976e96415433f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/link/zipball/84b159194ecfd7eaa472280213976e96415433f7", + "reference": "84b159194ecfd7eaa472280213976e96415433f7", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "suggest": { + "fig/link-util": "Provides some useful PSR-13 utilities" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Link\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for HTTP links", + "homepage": "https://github.com/php-fig/link", + "keywords": [ + "http", + "http-link", + "link", + "psr", + "psr-13", + "rest" + ], + "support": { + "source": "https://github.com/php-fig/link/tree/2.0.1" + }, + "time": "2021-03-11T23:00:27+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "runtime/frankenphp-symfony", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-runtime/frankenphp-symfony.git", + "reference": "56822c3631d9522a3136a4c33082d006bdfe4bad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-runtime/frankenphp-symfony/zipball/56822c3631d9522a3136a4c33082d006bdfe4bad", + "reference": "56822c3631d9522a3136a4c33082d006bdfe4bad", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/runtime": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Runtime\\FrankenPhpSymfony\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "kevin@dunglas.dev" + } + ], + "description": "FrankenPHP runtime for Symfony", + "support": { + "issues": "https://github.com/php-runtime/frankenphp-symfony/issues", + "source": "https://github.com/php-runtime/frankenphp-symfony/tree/0.2.0" + }, + "funding": [ + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-12-12T12:06:11+00:00" + }, + { + "name": "symfony/asset", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset.git", + "reference": "cb926cd59fefa1f9b4900b3695f0f846797ba5c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset/zipball/cb926cd59fefa1f9b4900b3695f0f846797ba5c0", + "reference": "cb926cd59fefa1f9b4900b3695f0f846797ba5c0", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "conflict": { + "symfony/http-foundation": "<6.4" + }, + "require-dev": { + "symfony/http-client": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Asset\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/asset/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:15:23+00:00" + }, + { + "name": "symfony/asset-mapper", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset-mapper.git", + "reference": "ffb733232bb6bb85ef6a994f47c817e7c2ecab9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/ffb733232bb6bb85ef6a994f47c817e7c2ecab9c", + "reference": "ffb733232bb6bb85ef6a994f47c817e7c2ecab9c", + "shasum": "" + }, + "require": { + "composer/semver": "^3.0", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/filesystem": "^7.1", + "symfony/http-client": "^6.4|^7.0" + }, + "conflict": { + "symfony/framework-bundle": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/event-dispatcher-contracts": "^3.0", + "symfony/finder": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\AssetMapper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps directories of assets & makes them available in a public directory with versioned filenames.", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/asset-mapper/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T11:17:29+00:00" + }, + { + "name": "symfony/cache", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "e7e983596b744c4539f31e79b0350a6cf5878a20" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/e7e983596b744c4539f31e79b0350a6cf5878a20", + "reference": "e7e983596b744c4539f31e79b0350a6cf5878a20", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/dependency-injection": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/var-dumper": "<6.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:08:50+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/config", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^7.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-04T11:36:24+00:00" + }, + { + "name": "symfony/console", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-11T03:49:26+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a475747af1a1c98272a5471abc35f3da81197c5d", + "reference": "a475747af1a1c98272a5471abc35f3da81197c5d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^3.5", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T15:45:00+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/doctrine-bridge", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-bridge.git", + "reference": "b492be51eb703723d682851a0c9fb39b9d1a7bfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/b492be51eb703723d682851a0c9fb39b9d1a7bfb", + "reference": "b492be51eb703723d682851a0c9fb39b9d1a7bfb", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^2", + "doctrine/persistence": "^3.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/collections": "<1.8", + "doctrine/dbal": "<3.6", + "doctrine/lexer": "<1.1", + "doctrine/orm": "<2.15", + "symfony/cache": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/form": "<6.4.6|>=7,<7.0.6", + "symfony/http-foundation": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/lock": "<6.4", + "symfony/messenger": "<6.4", + "symfony/property-info": "<6.4", + "symfony/security-bundle": "<6.4", + "symfony/security-core": "<6.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "doctrine/collections": "^1.8|^2.0", + "doctrine/data-fixtures": "^1.1|^2", + "doctrine/dbal": "^3.6|^4", + "doctrine/orm": "^2.15|^3", + "psr/log": "^1|^2|^3", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/doctrine-messenger": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4.6|^7.0.6", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Doctrine with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/doctrine-messenger", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-messenger.git", + "reference": "533e664a37b4208c5a26f1f7894f212690e806f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/533e664a37b4208c5a26f1f7894f212690e806f5", + "reference": "533e664a37b4208c5a26f1f7894f212690e806f5", + "shasum": "" + }, + "require": { + "doctrine/dbal": "^3.6|^4", + "php": ">=8.2", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/persistence": "<1.3" + }, + "require-dev": { + "doctrine/persistence": "^1.3|^2|^3", + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "symfony-messenger-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Doctrine Messenger Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-messenger/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-18T09:50:33+00:00" + }, + { + "name": "symfony/dotenv", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dotenv.git", + "reference": "28347a897771d0c28e99b75166dd2689099f3045" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/28347a897771d0c28e99b75166dd2689099f3045", + "reference": "28347a897771d0c28e99b75166dd2689099f3045", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "conflict": { + "symfony/console": "<6.4", + "symfony/process": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Dotenv\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Registers environment variables from a .env file", + "homepage": "https://symfony.com", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "source": "https://github.com/symfony/dotenv/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-27T11:18:42+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "6150b89186573046167796fa5f3f76601d5145f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6150b89186573046167796fa5f3f76601d5145f8", + "reference": "6150b89186573046167796fa5f3f76601d5145f8", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/expression-language", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "26f4884a455e755e630a5fc372df124a3578da2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/26f4884a455e755e630a5fc372df124a3578da2e", + "reference": "26f4884a455e755e630a5fc372df124a3578da2e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/cache": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an engine that can compile and evaluate expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/expression-language/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-15T11:52:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:15:23+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49", + "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T06:56:12+00:00" + }, + { + "name": "symfony/flex", + "version": "v2.4.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/flex.git", + "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/flex/zipball/92f4fba342161ff36072bd3b8e0b3c6c23160402", + "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.1", + "php": ">=8.0" + }, + "conflict": { + "composer/semver": "<1.7.2" + }, + "require-dev": { + "composer/composer": "^2.1", + "symfony/dotenv": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/phpunit-bridge": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Flex\\Flex" + }, + "autoload": { + "psr-4": { + "Symfony\\Flex\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien.potencier@gmail.com" + } + ], + "description": "Composer plugin for Symfony", + "support": { + "issues": "https://github.com/symfony/flex/issues", + "source": "https://github.com/symfony/flex/tree/v2.4.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-07T08:51:54+00:00" + }, + { + "name": "symfony/form", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/form.git", + "reference": "264cff30f52f12149aff92bbc23e78160a45c2f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/form/zipball/264cff30f52f12149aff92bbc23e78160a45c2f3", + "reference": "264cff30f52f12149aff92bbc23e78160a45c2f3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/options-resolver": "^6.4|^7.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/polyfill-mbstring": "~1.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/error-handler": "<6.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "doctrine/collections": "^1.0|^2.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Form\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows to easily create, process and reuse HTML forms", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/form/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-27T11:55:00+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "1c630f4697c9bd87b342e8090cc9022071af4d77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/1c630f4697c9bd87b342e8090cc9022071af4d77", + "reference": "1c630f4697c9bd87b342e8090cc9022071af4d77", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.2", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/filesystem": "^7.1", + "symfony/finder": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^7.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^6.4|^7.0" + }, + "conflict": { + "doctrine/persistence": "<1.3", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/asset": "<6.4", + "symfony/asset-mapper": "<6.4", + "symfony/clock": "<6.4", + "symfony/console": "<6.4", + "symfony/dom-crawler": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/lock": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/runtime": "<6.4.13|>=7.0,<7.1.6", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", + "symfony/security-core": "<6.4", + "symfony/security-csrf": "<7.2", + "symfony/serializer": "<7.1", + "symfony/stopwatch": "<6.4", + "symfony/translation": "<6.4", + "symfony/twig-bridge": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4", + "symfony/web-profiler-bundle": "<6.4", + "symfony/webhook": "<7.2", + "symfony/workflow": "<6.4" + }, + "require-dev": { + "doctrine/persistence": "^1.3|^2|^3", + "dragonmantank/cron-expression": "^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "seld/jsonlint": "^1.10", + "symfony/asset": "^6.4|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/mailer": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/notifier": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", + "symfony/security-bundle": "^6.4|^7.0", + "symfony/semaphore": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/webhook": "^7.2", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/framework-bundle/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T13:24:01+00:00" + }, + { + "name": "symfony/http-client", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "ff4df2b68d1c67abb9fef146e6540ea16b58d99e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/ff4df2b68d1c67abb9fef146e6540ea16b58d99e", + "reference": "ff4df2b68d1c67abb9fef146e6540ea16b58d99e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:49:48+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e88a66c3997859532bc2ddd6dd8f35aba2711744", + "reference": "e88a66c3997859532bc2ddd6dd8f35aba2711744", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-13T18:58:46+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d8ae58eecae44c8e66833e76cc50a4ad3c002d97", + "reference": "d8ae58eecae44c8e66833e76cc50a4ad3c002d97", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-11T12:09:10+00:00" + }, + { + "name": "symfony/intl", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/intl.git", + "reference": "76bb3462c6c308f8bd97d3c178c2626ae44d4dea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/intl/zipball/76bb3462c6c308f8bd97d3c178c2626ae44d4dea", + "reference": "76bb3462c6c308f8bd97d3c178c2626ae44d4dea", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/string": "<7.1" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Intl\\": "" + }, + "exclude-from-classmap": [ + "/Tests/", + "/Resources/data/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Eriksen Costa", + "email": "eriksen.costa@infranology.com.br" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides access to the localization data of the ICU library", + "homepage": "https://symfony.com", + "keywords": [ + "i18n", + "icu", + "internationalization", + "intl", + "l10n", + "localization" + ], + "support": { + "source": "https://github.com/symfony/intl/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T14:26:33+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/e4d358702fb66e4c8a2af08e90e7271a62de39cc", + "reference": "e4d358702fb66e4c8a2af08e90e7271a62de39cc", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T15:21:05+00:00" + }, + { + "name": "symfony/messenger", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/messenger.git", + "reference": "cc0e820c02a0a887a88ddb52b7c4de4634677ce6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/messenger/zipball/cc0e820c02a0a887a88ddb52b7c4de4634677ce6", + "reference": "cc0e820c02a0a887a88ddb52b7c4de4634677ce6", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/clock": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<7.2", + "symfony/event-dispatcher": "<6.4", + "symfony/event-dispatcher-contracts": "<2.5", + "symfony/framework-bundle": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/serializer": "<6.4" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/console": "^7.2", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Samuel Roze", + "email": "samuel.roze@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps applications send and receive messages to/from other applications or via message queues", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/messenger/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:08:50+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/7f9617fcf15cb61be30f8b252695ed5e2bfac283", + "reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/monolog-bridge", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bridge.git", + "reference": "bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d", + "reference": "bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d", + "shasum": "" + }, + "require": { + "monolog/monolog": "^3", + "php": ">=8.2", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/security-core": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/mailer": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Monolog\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Monolog with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/monolog-bridge/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-14T18:16:08+00:00" + }, + { + "name": "symfony/monolog-bundle", + "version": "v3.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bundle.git", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "shasum": "" + }, + "require": { + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "php": ">=7.2.5", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony MonologBundle", + "homepage": "https://symfony.com", + "keywords": [ + "log", + "logging" + ], + "support": { + "issues": "https://github.com/symfony/monolog-bundle/issues", + "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-11-06T17:08:13+00:00" + }, + { + "name": "symfony/notifier", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/notifier.git", + "reference": "b5104341c0b0d78fe2cfc8a7a0a185d544ee5c1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/notifier/zipball/b5104341c0b0d78fe2cfc8a7a0a185d544ee5c1c", + "reference": "b5104341c0b0d78fe2cfc8a7a0a185d544ee5c1c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3" + }, + "conflict": { + "symfony/event-dispatcher": "<6.4", + "symfony/event-dispatcher-contracts": "<2.5", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/event-dispatcher-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Notifier\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Sends notifications via one or more channels (email, SMS, ...)", + "homepage": "https://symfony.com", + "keywords": [ + "notification", + "notifier" + ], + "support": { + "source": "https://github.com/symfony/notifier/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-15T13:52:25+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T11:17:29+00:00" + }, + { + "name": "symfony/password-hasher", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/password-hasher.git", + "reference": "d8bd3d66d074c0acba1214a0d42f5941a8e1e94d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/d8bd3d66d074c0acba1214a0d42f5941a8e1e94d", + "reference": "d8bd3d66d074c0acba1214a0d42f5941a8e1e94d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "conflict": { + "symfony/security-core": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PasswordHasher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Chalas", + "email": "robin.chalas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides password hashing utilities", + "homepage": "https://symfony.com", + "keywords": [ + "hashing", + "password" + ], + "support": { + "source": "https://github.com/symfony/password-hasher/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-icu", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-icu.git", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance and support of other locales than \"en\"" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Icu\\": "" + }, + "classmap": [ + "Resources/stubs" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's ICU-related data and classes", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "icu", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-06T14:24:19+00:00" + }, + { + "name": "symfony/property-access", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "3ae42efba01e45aaedecf5c93c8d6a3ab3a82276" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/3ae42efba01e45aaedecf5c93c8d6a3ab3a82276", + "reference": "3ae42efba01e45aaedecf5c93c8d6a3ab3a82276", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/property-info": "^6.4|^7.0" + }, + "require-dev": { + "symfony/cache": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-26T12:28:35+00:00" + }, + { + "name": "symfony/property-info", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "65fb9be15380f949d72ff405473cce733364b8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/65fb9be15380f949d72ff405473cce733364b8b4", + "reference": "65fb9be15380f949d72ff405473cce733364b8b4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/string": "^6.4|^7.0", + "symfony/type-info": "^7.1" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/dependency-injection": "<6.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T11:08:51+00:00" + }, + { + "name": "symfony/runtime", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/runtime.git", + "reference": "2c350568f3eaccb25fbbbf962bd67cde273121a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/runtime/zipball/2c350568f3eaccb25fbbbf962bd67cde273121a7", + "reference": "2c350568f3eaccb25fbbbf962bd67cde273121a7", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": ">=8.2" + }, + "conflict": { + "symfony/dotenv": "<6.4" + }, + "require-dev": { + "composer/composer": "^2.6", + "symfony/console": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Component\\Runtime\\Internal\\ComposerPlugin" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Runtime\\": "", + "Symfony\\Runtime\\Symfony\\Component\\": "Internal/" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Enables decoupling PHP applications from global state", + "homepage": "https://symfony.com", + "keywords": [ + "runtime" + ], + "support": { + "source": "https://github.com/symfony/runtime/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-06T11:43:25+00:00" + }, + { + "name": "symfony/security-bundle", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-bundle.git", + "reference": "4bed2029576bf02a6915c5a58bc8a174af338e6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/4bed2029576bf02a6915c5a58bc8a174af338e6f", + "reference": "4bed2029576bf02a6915c5a58bc8a174af338e6f", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.2", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.11|^7.1.4", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/password-hasher": "^6.4|^7.0", + "symfony/security-core": "^7.2", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/security-http": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/console": "<6.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-client": "<6.4", + "symfony/ldap": "<6.4", + "symfony/serializer": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/ldap": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.12", + "web-token/jwt-library": "^3.3.2|^4.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\SecurityBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-bundle/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T08:31:32+00:00" + }, + { + "name": "symfony/security-core", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-core.git", + "reference": "fdbf318b939a86f89b0c071f60b9d551261d3cc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-core/zipball/fdbf318b939a86f89b0c071f60b9d551261d3cc1", + "reference": "fdbf318b939a86f89b0c071f60b9d551261d3cc1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher-contracts": "^2.5|^3", + "symfony/password-hasher": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/ldap": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/validator": "<6.4" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "psr/container": "^1.1|^2.0", + "psr/log": "^1|^2|^3", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/ldap": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/validator": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Core\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - Core Library", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-core/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-27T09:50:52+00:00" + }, + { + "name": "symfony/security-csrf", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-csrf.git", + "reference": "5d884aff316bd4f24c4c2ab4d5f02a00df4b08cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/5d884aff316bd4f24c4c2ab4d5f02a00df4b08cf", + "reference": "5d884aff316bd4f24c4c2ab4d5f02a00df4b08cf", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/security-core": "^6.4|^7.0" + }, + "conflict": { + "symfony/http-foundation": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Csrf\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - CSRF Library", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-csrf/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-08T13:08:31+00:00" + }, + { + "name": "symfony/security-http", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-http.git", + "reference": "125844598d9cef4fe72a9f6c4a78ac7c59c3f532" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-http/zipball/125844598d9cef4fe72a9f6c4a78ac7c59c3f532", + "reference": "125844598d9cef4fe72a9f6c4a78ac7c59c3f532", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/security-core": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/clock": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/http-client-contracts": "<3.0", + "symfony/security-bundle": "<6.4", + "symfony/security-csrf": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/cache": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-client-contracts": "^3.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "web-token/jwt-library": "^3.3.2|^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Http\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - HTTP Integration", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-http/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:50:44+00:00" + }, + { + "name": "symfony/serializer", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0", + "reference": "3f5ed9f5e6c02e3853109190ba38408f5e1d2dd0", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/dependency-injection": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/uid": "<6.4", + "symfony/validator": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "seld/jsonlint": "^1.10", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", + "symfony/error-handler": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/serializer/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-25T15:21:05+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/696f418b0d722a4225e1c3d95489d262971ca924", + "reference": "696f418b0d722a4225e1c3d95489d262971ca924", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/string", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-13T13:31:26+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/dc89e16b44048ceecc879054e5b7f38326ab6cc5", + "reference": "dc89e16b44048ceecc879054e5b7f38326ab6cc5", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-12T20:47:56+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/twig-bridge", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/twig-bridge.git", + "reference": "d5cdf4d59da5ab44ebd7503480c22d8235887de0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/d5cdf4d59da5ab44ebd7503480c22d8235887de0", + "reference": "d5cdf4d59da5ab44ebd7503480c22d8235887de0", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/translation-contracts": "^2.5|^3", + "twig/twig": "^3.12" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/console": "<6.4", "symfony/form": "<6.4", - "symfony/http-client": "<6.4", - "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<6.4", - "symfony/messenger": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/mime": "<6.4", + "symfony/serializer": "<6.4", "symfony/translation": "<6.4", - "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<6.4", - "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.4", - "twig/twig": "<3.12" + "symfony/workflow": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^6.4|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/emoji": "^7.1", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/security-acl": "^2.8|^3.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/security-http": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/cssinliner-extra": "^2.12|^3", + "twig/inky-extra": "^2.12|^3", + "twig/markdown-extra": "^2.12|^3" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Twig\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Twig with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/twig-bridge/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T09:50:32+00:00" + }, + { + "name": "symfony/twig-bundle", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/twig-bundle.git", + "reference": "cd2be4563afaef5285bb6e0a06c5445e644a5c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/cd2be4563afaef5285bb6e0a06c5445e644a5c01", + "reference": "cd2be4563afaef5285bb6e0a06c5445e644a5c01", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "conflict": { + "symfony/framework-bundle": "<6.4", + "symfony/translation": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\TwigBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration of Twig into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/twig-bundle/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T08:11:15+00:00" + }, + { + "name": "symfony/type-info", + "version": "v7.2.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "4f402070b08ad0b87e9cadbb07b87fb36061e6e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/4f402070b08ad0b87e9cadbb07b87fb36061e6e4", + "reference": "4f402070b08ad0b87e9cadbb07b87fb36061e6e4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.0|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v7.2.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-11T07:49:41+00:00" + }, + { + "name": "symfony/validator", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/validator.git", + "reference": "ddad20aa8cf7a45a9d6300e5776b8d252dc3524b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/validator/zipball/ddad20aa8cf7a45a9d6300e5776b8d252dc3524b", + "reference": "ddad20aa8cf7a45a9d6300e5776b8d252dc3524b", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php83": "^1.27", + "symfony/translation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/lexer": "<1.1", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<7.0", + "symfony/expression-language": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/intl": "<6.4", + "symfony/property-info": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/type-info": "^7.1", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "exclude-from-classmap": [ + "/Tests/", + "/Resources/bin/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to validate values", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/validator/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-27T09:50:52+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", + "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-08T15:48:14+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-18T07:58:17+00:00" + }, + { + "name": "symfony/web-link", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/web-link.git", + "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/web-link/zipball/f537556a885e14a1d28f6c759d41e57e93d0a532", + "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/link": "^1.1|^2.0" + }, + "conflict": { + "symfony/http-kernel": "<6.4" + }, + "provide": { + "psr/link-implementation": "1.0|2.0" + }, + "require-dev": { + "symfony/http-kernel": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\WebLink\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Manages links between resources", + "homepage": "https://symfony.com", + "keywords": [ + "dns-prefetch", + "http", + "http2", + "link", + "performance", + "prefetch", + "preload", + "prerender", + "psr13", + "push" + ], + "support": { + "source": "https://github.com/symfony/web-link/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T06:56:12+00:00" + }, + { + "name": "symfonycasts/tailwind-bundle", + "version": "v0.6.1", + "source": { + "type": "git", + "url": "https://github.com/SymfonyCasts/tailwind-bundle.git", + "reference": "28db7cfe23758cffc79f25a7c75cdb2fca52e9d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SymfonyCasts/tailwind-bundle/zipball/28db7cfe23758cffc79f25a7c75cdb2fca52e9d9", + "reference": "28db7cfe23758cffc79f25a7c75cdb2fca52e9d9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/asset-mapper": "^6.3|^7.0", + "symfony/cache": "^6.3|^7.0", + "symfony/console": "^5.4|^6.3|^7.0", + "symfony/http-client": "^5.4|^6.3|^7.0", + "symfony/process": "^5.4|^6.3|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "symfony/filesystem": "^6.3|^7.0", + "symfony/framework-bundle": "^6.3|^7.0", + "symfony/phpunit-bridge": "^6.3.9|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfonycasts\\TailwindBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ryan Weaver", + "homepage": "https://symfonycasts.com" + } + ], + "description": "Delightful Tailwind Support for Symfony + AssetMapper", + "keywords": [ + "asset-mapper", + "tailwind" + ], + "support": { + "issues": "https://github.com/SymfonyCasts/tailwind-bundle/issues", + "source": "https://github.com/SymfonyCasts/tailwind-bundle/tree/v0.6.1" + }, + "time": "2024-11-06T18:41:22+00:00" + }, + { + "name": "twig/extra-bundle", + "version": "v3.17.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/twig-extra-bundle.git", + "reference": "9746573ca4bc1cd03a767a183faadaf84e0c31fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/9746573ca4bc1cd03a767a183faadaf84e0c31fa", + "reference": "9746573ca4bc1cd03a767a183faadaf84e0c31fa", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.4|^7.0", + "twig/twig": "^3.2|^4.0" + }, + "require-dev": { + "league/commonmark": "^1.0|^2.0", + "symfony/phpunit-bridge": "^6.4|^7.0", + "twig/cache-extra": "^3.0", + "twig/cssinliner-extra": "^3.0", + "twig/html-extra": "^3.0", + "twig/inky-extra": "^3.0", + "twig/intl-extra": "^3.0", + "twig/markdown-extra": "^3.0", + "twig/string-extra": "^3.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Twig\\Extra\\TwigExtraBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Symfony bundle for extra Twig extensions", + "homepage": "https://twig.symfony.com", + "keywords": [ + "bundle", + "extra", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.17.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2024-09-26T19:22:23+00:00" + }, + { + "name": "twig/string-extra", + "version": "v3.17.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/string-extra.git", + "reference": "cb4eec11de02f63ad8ea9d065a1f27752d0bf752" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/string-extra/zipball/cb4eec11de02f63ad8ea9d065a1f27752d0bf752", + "reference": "cb4eec11de02f63ad8ea9d065a1f27752d0bf752", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/string": "^5.4|^6.4|^7.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^3.13|^4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Twig\\Extra\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Twig extension for Symfony String", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "string", + "twig", + "unicode" + ], + "support": { + "source": "https://github.com/twigphp/string-extra/tree/v3.17.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2024-11-30T08:42:13+00:00" + }, + { + "name": "twig/twig", + "version": "v3.17.1", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "677ef8da6497a03048192aeeb5aa3018e379ac71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/677ef8da6497a03048192aeeb5aa3018e379ac71", + "reference": "677ef8da6497a03048192aeeb5aa3018e379ac71", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php81": "^1.29" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.17.1" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2024-12-12T09:58:10+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "masterminds/html5", + "version": "2.9.0", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" + }, + "time": "2024-03-31T07:05:07+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-11-08T17:47:46+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.3.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + }, + "time": "2024-10-08T18:51:32+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.32", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:23:01+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.22", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f80235cb4d3caa59ae09be3adf1ded27521d1a9c", + "reference": "f80235cb4d3caa59ae09be3adf1ded27521d1a9c", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.5.0 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.32", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", + "sebastian/comparator": "^4.0.8", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.6", + "sebastian/global-state": "^5.0.7", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.22" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-12-05T13:48:26+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:27:43+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-09-14T12:41:17+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:19:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^6.4|^7.0", - "symfony/clock": "^6.4|^7.0", - "symfony/config": "^6.4|^7.0", - "symfony/console": "^6.4|^7.0", - "symfony/css-selector": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/dom-crawler": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/finder": "^6.4|^7.0", - "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^7.1", - "symfony/routing": "^6.4|^7.0", - "symfony/serializer": "^7.1", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^6.4|^7.0", - "symfony/validator": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0", - "symfony/var-exporter": "^6.4|^7.0", - "twig/twig": "^3.12" + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:33:00+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:35:11+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:20:34+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } }, - "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Provides a structured process for converting a Request into a Response", - "homepage": "https://symfony.com", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.2.1" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-12-11T12:09:10+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "name": "sebastian/resource-operations", + "version": "3.0.4", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=7.3" }, - "suggest": { - "ext-intl": "For best performance" + "require-dev": { + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-main": "3.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "grapheme", - "intl", - "polyfill", - "portable", - "shim" - ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-03-14T16:00:52+00:00" }, { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "name": "sebastian/type", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=7.3" }, - "suggest": { - "ext-intl": "For best performance" + "require-dev": { + "phpunit/phpunit": "^9.5" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-master": "3.2-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, "classmap": [ - "Resources/stubs" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "name": "sebastian/version", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" + "php": ">=7.3" }, "type": "library", "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" + "branch-alias": { + "dev-master": "3.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2020-09-28T06:39:44+00:00" }, { - "name": "symfony/polyfill-php83", - "version": "v1.31.0", + "name": "symfony/browser-kit", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + "url": "https://github.com/symfony/browser-kit.git", + "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/8d64d17e198082f8f198d023a6b634e7b5fdda94", + "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.2", + "symfony/dom-crawler": "^6.4|^7.0" }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } + "require-dev": { + "symfony/css-selector": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" }, + "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" + "Symfony\\Component\\BrowserKit\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1822,24 +9304,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" + "source": "https://github.com/symfony/browser-kit/tree/v7.2.0" }, "funding": [ { @@ -1855,43 +9331,29 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { - "name": "symfony/routing", + "name": "symfony/css-selector", "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e" + "url": "https://github.com/symfony/css-selector.git", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/e10a2450fa957af6c448b9b93c9010a4e4c0725e", - "reference": "e10a2450fa957af6c448b9b93c9010a4e4c0725e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/config": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/yaml": "<6.4" - }, - "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/expression-language": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/yaml": "^6.4|^7.0" + "php": ">=8.2" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Routing\\": "" + "Symfony\\Component\\CssSelector\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -1906,21 +9368,19 @@ "name": "Fabien Potencier", "email": "fabien@symfony.com" }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Maps an HTTP request to a set of configuration variables", + "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.2.0" + "source": "https://github.com/symfony/css-selector/tree/v7.2.0" }, "funding": [ { @@ -1936,44 +9396,42 @@ "type": "tidelift" } ], - "time": "2024-11-25T11:08:51+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "symfony/runtime", + "name": "symfony/debug-bundle", "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/runtime.git", - "reference": "2c350568f3eaccb25fbbbf962bd67cde273121a7" + "url": "https://github.com/symfony/debug-bundle.git", + "reference": "2dade0d1415c08b627379b5ec214ec8424cb2e32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/2c350568f3eaccb25fbbbf962bd67cde273121a7", - "reference": "2c350568f3eaccb25fbbbf962bd67cde273121a7", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/2dade0d1415c08b627379b5ec214ec8424cb2e32", + "reference": "2dade0d1415c08b627379b5ec214ec8424cb2e32", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0|^2.0", - "php": ">=8.2" + "ext-xml": "*", + "php": ">=8.2", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "conflict": { - "symfony/dotenv": "<6.4" + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4" }, "require-dev": { - "composer/composer": "^2.6", - "symfony/console": "^6.4|^7.0", - "symfony/dotenv": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Symfony\\Component\\Runtime\\Internal\\ComposerPlugin" + "symfony/config": "^6.4|^7.0", + "symfony/web-profiler-bundle": "^6.4|^7.0" }, + "type": "symfony-bundle", "autoload": { "psr-4": { - "Symfony\\Component\\Runtime\\": "", - "Symfony\\Runtime\\Symfony\\Component\\": "Internal/" + "Symfony\\Bundle\\DebugBundle\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -1985,21 +9443,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Enables decoupling PHP applications from global state", + "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", - "keywords": [ - "runtime" - ], "support": { - "source": "https://github.com/symfony/runtime/tree/v7.2.0" + "source": "https://github.com/symfony/debug-bundle/tree/v7.2.0" }, "funding": [ { @@ -2015,46 +9470,38 @@ "type": "tidelift" } ], - "time": "2024-11-06T11:43:25+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { - "name": "symfony/service-contracts", - "version": "v3.5.1", + "name": "symfony/dom-crawler", + "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "b176e1f1f550ef44c94eb971bf92488de08f7c6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b176e1f1f550ef44c94eb971bf92488de08f7c6b", + "reference": "b176e1f1f550ef44c94eb971bf92488de08f7c6b", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" + "masterminds/html5": "^2.6", + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" }, - "conflict": { - "ext-psr": "<1.1|>=2" + "require-dev": { + "symfony/css-selector": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, "autoload": { "psr-4": { - "Symfony\\Contracts\\Service\\": "" + "Symfony\\Component\\DomCrawler\\": "" }, "exclude-from-classmap": [ - "/Test/" + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2063,26 +9510,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to writing services", + "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/dom-crawler/tree/v7.2.0" }, "funding": [ { @@ -2098,78 +9537,83 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-11-13T16:15:23+00:00" }, { - "name": "symfony/string", - "version": "v7.2.0", + "name": "symfony/maker-bundle", + "version": "v1.61.0", "source": { "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "url": "https://github.com/symfony/maker-bundle.git", + "reference": "a3b7f14d349f8f44ed752d4dde2263f77510cc18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/a3b7f14d349f8f44ed752d4dde2263f77510cc18", + "reference": "a3b7f14d349f8f44ed752d4dde2263f77510cc18", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.0", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "doctrine/inflector": "^2.0", + "nikic/php-parser": "^4.18|^5.0", + "php": ">=8.1", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.2|^3", + "symfony/filesystem": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" }, "conflict": { - "symfony/translation-contracts": "<2.5" + "doctrine/doctrine-bundle": "<2.10", + "doctrine/orm": "<2.15" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", + "composer/semver": "^3.0", + "doctrine/doctrine-bundle": "^2.5.0", + "doctrine/orm": "^2.15|^3", "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/phpunit-bridge": "^6.4.1|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.0|^4.x-dev" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } }, - "type": "library", "autoload": { - "files": [ - "Resources/functions.php" - ], "psr-4": { - "Symfony\\Component\\String\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Bundle\\MakerBundle\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", - "homepage": "https://symfony.com", + "description": "Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.", + "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", "keywords": [ - "grapheme", - "i18n", - "string", - "unicode", - "utf-8", - "utf8" + "code generator", + "dev", + "generator", + "scaffold", + "scaffolding" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "issues": "https://github.com/symfony/maker-bundle/issues", + "source": "https://github.com/symfony/maker-bundle/tree/v1.61.0" }, "funding": [ { @@ -2185,50 +9629,53 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2024-08-29T22:50:23+00:00" }, { - "name": "symfony/var-dumper", + "name": "symfony/phpunit-bridge", "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c" + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "2bbde92ab25a0e2c88160857af7be9db5da0d145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6a22929407dec8765d6e2b6ff85b800b245879c", - "reference": "c6a22929407dec8765d6e2b6ff85b800b245879c", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/2bbde92ab25a0e2c88160857af7be9db5da0d145", + "reference": "2bbde92ab25a0e2c88160857af7be9db5da0d145", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=7.2.5" }, "conflict": { - "symfony/console": "<6.4" + "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { - "ext-iconv": "*", - "symfony/console": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", - "twig/twig": "^3.12" + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/error-handler": "^5.4|^6.4|^7.0", + "symfony/polyfill-php81": "^1.27" }, "bin": [ - "Resources/bin/var-dump-server" + "bin/simple-phpunit" ], - "type": "library", + "type": "symfony-bridge", + "extra": { + "thanks": { + "url": "https://github.com/sebastianbergmann/phpunit", + "name": "phpunit/phpunit" + } + }, "autoload": { "files": [ - "Resources/functions/dump.php" + "bootstrap.php" ], "psr-4": { - "Symfony\\Component\\VarDumper\\": "" + "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2245,14 +9692,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.2.0" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.2.0" }, "funding": [ { @@ -2268,34 +9711,47 @@ "type": "tidelift" } ], - "time": "2024-11-08T15:48:14+00:00" + "time": "2024-11-13T16:15:23+00:00" }, { - "name": "symfony/var-exporter", + "name": "symfony/web-profiler-bundle", "version": "v7.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/var-exporter.git", - "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" + "url": "https://github.com/symfony/web-profiler-bundle.git", + "reference": "8843019fa7140a4aa079f1a8d71fd010f61de5f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", - "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/8843019fa7140a4aa079f1a8d71fd010f61de5f2", + "reference": "8843019fa7140a4aa079f1a8d71fd010f61de5f2", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "conflict": { + "symfony/form": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/serializer": "<7.2" }, "require-dev": { - "symfony/property-access": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" }, - "type": "library", + "type": "symfony-bundle", "autoload": { "psr-4": { - "Symfony\\Component\\VarExporter\\": "" + "Symfony\\Bundle\\WebProfilerBundle\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -2307,28 +9763,21 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "description": "Provides a development tool that gives detailed information about the execution of any request", "homepage": "https://symfony.com", "keywords": [ - "clone", - "construct", - "export", - "hydrate", - "instantiate", - "lazy-loading", - "proxy", - "serialize" + "dev" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.2.0" }, "funding": [ { @@ -2344,82 +9793,59 @@ "type": "tidelift" } ], - "time": "2024-10-18T07:58:17+00:00" + "time": "2024-11-19T10:12:55+00:00" }, { - "name": "symfony/yaml", - "version": "v7.2.0", + "name": "theseer/tokenizer", + "version": "1.2.3", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22" + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", - "reference": "099581e99f557e9f16b43c5916c26380b54abb22", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.2.0" + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/theseer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2024-10-23T06:56:12+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], - "packages-dev": [], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/config/bundles.php b/config/bundles.php index 49d3fb6..165f54d 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -2,4 +2,14 @@ return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], + Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], + Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], + Symfonycasts\TailwindBundle\SymfonycastsTailwindBundle::class => ['all' => true], ]; diff --git a/config/packages/asset_mapper.yaml b/config/packages/asset_mapper.yaml new file mode 100644 index 0000000..f7653e9 --- /dev/null +++ b/config/packages/asset_mapper.yaml @@ -0,0 +1,11 @@ +framework: + asset_mapper: + # The paths to make available to the asset mapper. + paths: + - assets/ + missing_import_mode: strict + +when@prod: + framework: + asset_mapper: + missing_import_mode: warn diff --git a/config/packages/csrf.yaml b/config/packages/csrf.yaml new file mode 100644 index 0000000..40d4040 --- /dev/null +++ b/config/packages/csrf.yaml @@ -0,0 +1,11 @@ +# Enable stateless CSRF protection for forms and logins/logouts +framework: + form: + csrf_protection: + token_id: submit + + csrf_protection: + stateless_token_ids: + - submit + - authenticate + - logout diff --git a/config/packages/debug.yaml b/config/packages/debug.yaml new file mode 100644 index 0000000..ad874af --- /dev/null +++ b/config/packages/debug.yaml @@ -0,0 +1,5 @@ +when@dev: + debug: + # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser. + # See the "server:dump" command to start a new server. + dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%" diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml new file mode 100644 index 0000000..25138b9 --- /dev/null +++ b/config/packages/doctrine.yaml @@ -0,0 +1,54 @@ +doctrine: + dbal: + url: '%env(resolve:DATABASE_URL)%' + + # IMPORTANT: You MUST configure your server version, + # either here or in the DATABASE_URL env var (see .env file) + #server_version: '16' + + profiling_collect_backtrace: '%kernel.debug%' + use_savepoints: true + orm: + auto_generate_proxy_classes: true + enable_lazy_ghost_objects: true + report_fields_where_declared: true + validate_xml_mapping: true + naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware + identity_generation_preferences: + Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity + auto_mapping: true + mappings: + App: + type: attribute + is_bundle: false + dir: '%kernel.project_dir%/src/Entity' + prefix: 'App\Entity' + alias: App + controller_resolver: + auto_mapping: false + +when@test: + doctrine: + dbal: + # "TEST_TOKEN" is typically set by ParaTest + dbname_suffix: '_test%env(default::TEST_TOKEN)%' + +when@prod: + doctrine: + orm: + auto_generate_proxy_classes: false + proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies' + query_cache_driver: + type: pool + pool: doctrine.system_cache_pool + result_cache_driver: + type: pool + pool: doctrine.result_cache_pool + + framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/config/packages/doctrine_migrations.yaml b/config/packages/doctrine_migrations.yaml new file mode 100644 index 0000000..29231d9 --- /dev/null +++ b/config/packages/doctrine_migrations.yaml @@ -0,0 +1,6 @@ +doctrine_migrations: + migrations_paths: + # namespace is arbitrary but should be different from App\Migrations + # as migrations classes should NOT be autoloaded + 'DoctrineMigrations': '%kernel.project_dir%/migrations' + enable_profiler: false diff --git a/config/packages/mailer.yaml b/config/packages/mailer.yaml new file mode 100644 index 0000000..56a650d --- /dev/null +++ b/config/packages/mailer.yaml @@ -0,0 +1,3 @@ +framework: + mailer: + dsn: '%env(MAILER_DSN)%' diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml new file mode 100644 index 0000000..270f3c7 --- /dev/null +++ b/config/packages/messenger.yaml @@ -0,0 +1,29 @@ +framework: + messenger: + failure_transport: failed + + transports: + # https://symfony.com/doc/current/messenger.html#transport-configuration + async: + dsn: '%env(MESSENGER_TRANSPORT_DSN)%' + options: + use_notify: true + check_delayed_interval: 60000 + retry_strategy: + max_retries: 3 + multiplier: 2 + failed: 'doctrine://default?queue_name=failed' + # sync: 'sync://' + + default_bus: messenger.bus.default + + buses: + messenger.bus.default: [] + + routing: + Symfony\Component\Mailer\Messenger\SendEmailMessage: async + Symfony\Component\Notifier\Message\ChatMessage: async + Symfony\Component\Notifier\Message\SmsMessage: async + + # Route your messages to the transports + # 'App\Message\YourMessage': async diff --git a/config/packages/monolog.yaml b/config/packages/monolog.yaml new file mode 100644 index 0000000..9db7d8a --- /dev/null +++ b/config/packages/monolog.yaml @@ -0,0 +1,62 @@ +monolog: + channels: + - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists + +when@dev: + monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + channels: ["!event"] + # uncomment to get logging in your browser + # you may have to allow bigger header sizes in your Web server configuration + #firephp: + # type: firephp + # level: info + #chromephp: + # type: chromephp + # level: info + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine", "!console"] + +when@test: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + channels: ["!event"] + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + +when@prod: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + buffer_size: 50 # How many messages should be saved? Prevent memory leaks + nested: + type: stream + path: php://stderr + level: debug + formatter: monolog.formatter.json + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine"] + deprecation: + type: stream + channels: [deprecation] + path: php://stderr + formatter: monolog.formatter.json diff --git a/config/packages/notifier.yaml b/config/packages/notifier.yaml new file mode 100644 index 0000000..d02f986 --- /dev/null +++ b/config/packages/notifier.yaml @@ -0,0 +1,12 @@ +framework: + notifier: + chatter_transports: + texter_transports: + channel_policy: + # use chat/slack, chat/telegram, sms/twilio or sms/nexmo + urgent: ['email'] + high: ['email'] + medium: ['email'] + low: ['email'] + admin_recipients: + - { email: admin@example.com } diff --git a/config/packages/security.yaml b/config/packages/security.yaml new file mode 100644 index 0000000..b69f6b5 --- /dev/null +++ b/config/packages/security.yaml @@ -0,0 +1,52 @@ +security: + # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords + password_hashers: + Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' + # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider + providers: + # used to reload user from session & other features (e.g. switch_user) + app_user_provider: + entity: + class: App\Entity\User + property: username + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + main: + lazy: true + provider: app_user_provider + form_login: + login_path: app_login + check_path: app_login + enable_csrf: true + default_target_path: app_admin_index + logout: + path: app_logout + # where to redirect after logout + # target: app_any_route + + # activate different ways to authenticate + # https://symfony.com/doc/current/security.html#the-firewall + + # https://symfony.com/doc/current/security/impersonating_user.html + # switch_user: true + + # Easy way to control access for large sections of your site + # Note: Only the *first* access control that matches will be used + access_control: + - { path: ^/admin, roles: ROLE_USER } + # - { path: ^/profile, roles: ROLE_USER } + +when@test: + security: + password_hashers: + # By default, password hashers are resource intensive and take time. This is + # important to generate secure password hashes. In tests however, secure hashes + # are not important, waste resources and increase test times. The following + # reduces the work factor to the lowest possible values. + Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: + algorithm: auto + cost: 4 # Lowest possible value for bcrypt + time_cost: 3 # Lowest possible value for argon + memory_cost: 10 # Lowest possible value for argon diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml new file mode 100644 index 0000000..b3f8f9c --- /dev/null +++ b/config/packages/translation.yaml @@ -0,0 +1,7 @@ +framework: + default_locale: en + translator: + default_path: '%kernel.project_dir%/translations' + fallbacks: + - en + providers: diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml new file mode 100644 index 0000000..3f795d9 --- /dev/null +++ b/config/packages/twig.yaml @@ -0,0 +1,6 @@ +twig: + file_name_pattern: '*.twig' + +when@test: + twig: + strict_variables: true diff --git a/config/packages/validator.yaml b/config/packages/validator.yaml new file mode 100644 index 0000000..dd47a6a --- /dev/null +++ b/config/packages/validator.yaml @@ -0,0 +1,11 @@ +framework: + validation: + # Enables validator auto-mapping support. + # For instance, basic validation constraints will be inferred from Doctrine's metadata. + #auto_mapping: + # App\Entity\: [] + +when@test: + framework: + validation: + not_compromised_password: false diff --git a/config/packages/web_profiler.yaml b/config/packages/web_profiler.yaml new file mode 100644 index 0000000..b946111 --- /dev/null +++ b/config/packages/web_profiler.yaml @@ -0,0 +1,17 @@ +when@dev: + web_profiler: + toolbar: true + intercept_redirects: false + + framework: + profiler: + only_exceptions: false + collect_serializer_data: true + +when@test: + web_profiler: + toolbar: false + intercept_redirects: false + + framework: + profiler: { collect: false } diff --git a/config/routes/security.yaml b/config/routes/security.yaml new file mode 100644 index 0000000..f853be1 --- /dev/null +++ b/config/routes/security.yaml @@ -0,0 +1,3 @@ +_security_logout: + resource: security.route_loader.logout + type: service diff --git a/config/routes/web_profiler.yaml b/config/routes/web_profiler.yaml new file mode 100644 index 0000000..8d85319 --- /dev/null +++ b/config/routes/web_profiler.yaml @@ -0,0 +1,8 @@ +when@dev: + web_profiler_wdt: + resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml' + prefix: /_wdt + + web_profiler_profiler: + resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml' + prefix: /_profiler diff --git a/importmap.php b/importmap.php new file mode 100644 index 0000000..10042e5 --- /dev/null +++ b/importmap.php @@ -0,0 +1,66 @@ + [ + 'path' => './assets/app.js', + 'entrypoint' => true, + ], + 'daisyui' => [ + 'version' => '4.12.22', + ], + 'postcss-js' => [ + 'version' => '4.0.1', + ], + 'picocolors' => [ + 'version' => '1.1.1', + ], + 'css-selector-tokenizer' => [ + 'version' => '0.8.0', + ], + 'culori/require' => [ + 'version' => '3.3.0', + ], + 'daisyui/dist/full.min.css' => [ + 'version' => '4.12.22', + 'type' => 'css', + ], + 'camelcase-css' => [ + 'version' => '2.0.1', + ], + 'postcss' => [ + 'version' => '8.4.33', + ], + 'fastparse' => [ + 'version' => '1.1.2', + ], + 'cssesc' => [ + 'version' => '3.0.0', + ], + 'nanoid/non-secure' => [ + 'version' => '3.3.7', + ], + 'alpinejs' => [ + 'version' => '3.14.7', + ], + 'htmx.org' => [ + 'version' => '2.0.4', + ], + 'fireworks-js' => [ + 'version' => '2.10.8', + ], + 'app_obs' => [ + 'path' => './assets/app_obs.js', + 'entrypoint' => true, + ], +]; diff --git a/migrations/.gitignore b/migrations/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/migrations/Version20241218152147.php b/migrations/Version20241218152147.php new file mode 100644 index 0000000..bfd6aa1 --- /dev/null +++ b/migrations/Version20241218152147.php @@ -0,0 +1,49 @@ +addSql('CREATE TABLE poll (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title VARCHAR(255) NOT NULL, description CLOB DEFAULT NULL, short_code VARCHAR(255) NOT NULL, start_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , end_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , is_active BOOLEAN NOT NULL, question1 CLOB DEFAULT NULL, question2 CLOB DEFAULT NULL, question3 CLOB DEFAULT NULL, question4 CLOB DEFAULT NULL, question5 CLOB DEFAULT NULL)'); + $this->addSql('CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username VARCHAR(180) NOT NULL, roles CLOB NOT NULL --(DC2Type:json) + , password VARCHAR(255) NOT NULL)'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_USERNAME ON user (username)'); + $this->addSql('CREATE TABLE vote (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, poll_id INTEGER NOT NULL, voter_id VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , CONSTRAINT FK_5A1085643C947C0F FOREIGN KEY (poll_id) REFERENCES poll (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('CREATE INDEX IDX_5A1085643C947C0F ON vote (poll_id)'); + $this->addSql('CREATE TABLE messenger_messages (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , available_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , delivered_at DATETIME DEFAULT NULL --(DC2Type:datetime_immutable) + )'); + $this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)'); + $this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)'); + $this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE poll'); + $this->addSql('DROP TABLE user'); + $this->addSql('DROP TABLE vote'); + $this->addSql('DROP TABLE messenger_messages'); + } +} diff --git a/migrations/Version20241219142150.php b/migrations/Version20241219142150.php new file mode 100644 index 0000000..dab908b --- /dev/null +++ b/migrations/Version20241219142150.php @@ -0,0 +1,37 @@ +addSql('ALTER TABLE vote ADD COLUMN choice INTEGER NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TEMPORARY TABLE __temp__vote AS SELECT id, poll_id, voter_id, created_at FROM vote'); + $this->addSql('DROP TABLE vote'); + $this->addSql('CREATE TABLE vote (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, poll_id INTEGER NOT NULL, voter_id VARCHAR(255) NOT NULL, created_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , CONSTRAINT FK_5A1085643C947C0F FOREIGN KEY (poll_id) REFERENCES poll (id) NOT DEFERRABLE INITIALLY IMMEDIATE)'); + $this->addSql('INSERT INTO vote (id, poll_id, voter_id, created_at) SELECT id, poll_id, voter_id, created_at FROM __temp__vote'); + $this->addSql('DROP TABLE __temp__vote'); + $this->addSql('CREATE INDEX IDX_5A1085643C947C0F ON vote (poll_id)'); + } +} diff --git a/migrations/Version20241219193957.php b/migrations/Version20241219193957.php new file mode 100644 index 0000000..1c6dbfa --- /dev/null +++ b/migrations/Version20241219193957.php @@ -0,0 +1,37 @@ +addSql('CREATE TEMPORARY TABLE __temp__poll AS SELECT id, title, description, short_code, start_at, end_at, question1, question2, question3, question4, question5 FROM poll'); + $this->addSql('DROP TABLE poll'); + $this->addSql('CREATE TABLE poll (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title VARCHAR(255) NOT NULL, description CLOB DEFAULT NULL, short_code VARCHAR(255) NOT NULL, start_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , end_at DATETIME NOT NULL --(DC2Type:datetime_immutable) + , question1 CLOB DEFAULT NULL, question2 CLOB DEFAULT NULL, question3 CLOB DEFAULT NULL, question4 CLOB DEFAULT NULL, question5 CLOB DEFAULT NULL)'); + $this->addSql('INSERT INTO poll (id, title, description, short_code, start_at, end_at, question1, question2, question3, question4, question5) SELECT id, title, description, short_code, start_at, end_at, question1, question2, question3, question4, question5 FROM __temp__poll'); + $this->addSql('DROP TABLE __temp__poll'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE poll ADD COLUMN is_active BOOLEAN NOT NULL'); + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..28935cf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,171 @@ +{ + "name": "app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "daisyui": "^4.12.22" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/css-selector-tokenizer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz", + "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/culori": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz", + "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/daisyui": { + "version": "4.12.22", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.12.22.tgz", + "integrity": "sha512-HDLWbmTnXxhE1MrMgSWjVgdRt+bVYHvfNbW3GTsyIokRSqTHonUTrxV3RhpPDjGIWaHt+ELtDCTYCtUFgL2/Nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-selector-tokenizer": "^0.8", + "culori": "^3", + "picocolors": "^1", + "postcss-js": "^4" + }, + "engines": { + "node": ">=16.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/daisyui" + } + }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2a37475 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "daisyui": "^4.12.22" + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..6c4bfed --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + tests + + + + + + src + + + + + + + + + + diff --git a/public/img/screen1.webp b/public/img/screen1.webp new file mode 100644 index 0000000000000000000000000000000000000000..01af181afcd34e7033b78ce9b208a824f6e32134 GIT binary patch literal 67808 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
D@J1#m!*zljHL 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%0A%@6n#`f0Zzi{rk+Uri!t2 zsYqi2X%EtC;NbtSC5dGEIN%;aoO-*YGckln;1AGDLjnWVW%u@T`c4_S){3Frm_$1x3>@ zc7Y!>0{c{kW~QW?wX+XO;qg6b$BZt}xNDi3o&*Gcf$V*l*e$i|zzB#4xz0wRhSXJ^ zYRv*2MfOkK|JPlyLTOZ`O9<5u0h(!f0Cp`-+{kx%={Cu>d8$XijKJ4*SQm2t8V90| z{Ub3jApT)mQssqOWg8sEils0}08Ud?=EpHSa5kR-VNBg}hAPfLiC2l56>(Taecow? z=cpkq!mW@1KKB4$2EGamU%)w!9l7{a(ArRa2Kn++MAR}@J8)$BdDHEG@Fp>BMPCEE z5l{+bE=xlv(#Y?XT|YPEmlhr6%L1p(Z7PSs*Pn2OoKIWXz3Ntj5fO5+xKrwI2e&aJf zeZq~iAb4TJlGcgMxdueT&WmR5u!%ZxF|3|Gu8Hkhx;MqtY*g1{XHF|uZAxUJoF4rO zPs_$XoLocM7p4kS2iNh-$YucD+=l(2$}!VK75jZJD`uWUkp99jgM-kT586zY!cU-4 zKpq6jV8_<*AN=8C7QCDAV2+)zUKVddSocXg`l`ZMPGBmdVWuf2({P6!3Rf=@?lRRn z=M7+jyEpS0Kcc&`xdcn|LV}0hISJ4JU{rV*Ge~>fKA$Vb3Ou%U%SrL<(s^;{_}{cp zW$N+`1@~@tRwTPP4gk${@0&FkM_LC*4>C7{95iPB}w>v8mU7P>_1mH?A z0000Xg#DZV0Fq*3x$FQ7yMPKR02UMg0Ppn1xB`Sw9X^=X00fj!00twrMv~JlqyR?xU`)kpnPp!)^BR>l^Fl|W$BIfX8DLY^Qx;<3rh5f4w>WkT~ z=c-A39hTiunHX2U-#?_gCCnoatM#VRU{k12RJf7DV3a&zKUAkM^G*pX9C3io!5?NG zg_JW?FVxQQAVHXxY41?CiCJ@;x#scWxFURM{+u1#cQRC7tr8WKzQ90#e5{E$!a8EL zUGdB*55g8h??%nE~mRc(@|ihLv;_@#ZI*i4B1>loU!d_tGn@V z+TN1yt}vUu^EG7obA)^$qcz=oS4rhRMF_+krKV`c42YE?1=d)4$r`{oVu3CCa_cli~& zEAQv3xvQ#=Or>}3BuGd+fL$!|SCAo++(-n0gfrr0L+IiMti(&68 z;=$_|#f_7%4Ri;MPTm@wQziI3gb!Q-UT^yXIu4Cml0~p|!vKKpR+X871#1JzbTt>} zo$(w2NGFcBb8$bxXGeB$YxeSsfJY>=@T;f1-Tl&Embzg(D!)`u;5TUhy{Kc2SNTP{c9fZ2BY;k}9a-ql`6T%4ZP)EwWOd2ta|M!7F2aS0uW$k;}Oh$SR z{?*(_8LE#Di!Gf+2K1vCKC-?EZPqe%wH!D|96qtLA2Y-Ici0Q@X2W3alb7lKM&2fK zThUI_f@RmEnPZ^Rj^E?3{~=`AbVk@1nyCf3o_GD-nOTm?)mq%wavIS@S}|kv%=la2 zK=*!ev~pUKfBDwB2h!U;(WVu6=@;8yXho<@QR+_iUr06{p9)yBnKuz)rZWjBz1nXdu4EJkBpcwn9^w5tCGsXBysy<@Is9Z_0QG`jA=7k2Y}5${x@{na@yJkm1SbOyV#{h5rt_c)khyB2l$^r=+!g2cDCF>l z+E0S$%#Ii7zFzLJI2Wl(qVFkkru4utq7{WwXYNiHR89d;LTSpHo9Dgt#1jgg_yV|f zP*X&=30%h`Yx@r~fi`}+BRlvM)5CzdAjvB5w7eqAyQj%qJ~g)%2-MZ~&`5P=7E&B%&0dRCN=I!7RQ6Jo4Nrb!@56S{}0 z>vX-9y>=p$qqzO@+cy>=qoe8y>%JhNnd`mX3f7gIh7LF$iL_7=%JNEG>blr6T|y4t z0RHVvh?IyU?>o&|9-C>`e-%3&8coq6pJiMCU{p;K`bVbuucoWEL0ww^I;AGO!|3HJ z^CD`;&X^2CA`{{Fahp?oyp?e8XuL$2i1eQ7{pA8d><-+5n+PZiKZ}nTR&+UFmmkeF zJfd^4`^)cFcxBbyEWvr;WS0>Iel{9+bjjP51X%0z#2eOPl9G?}Yo|(3Ri)&6(QG_voRLtFLSV6Ec))wGUZU$>+ufIFr84^x%yB^HMu;3E=ZP zCH%$^0}A+iSEioVb!y_EMk~@0^Ujv3vWIi_t!Vnr3<&N?5r_#ptXtG^0*x&nuFPm-U%&HE z*|`Qff^c#-JRxJudPOiPMPmykfNN6z8q5zQV_A)dHLXfmg9hM~AHx+n#)1ZAh-N@g zy~6yh?ruBuVd>Z@Rr6F@Sg0M88_BED314;Lu@7#w6dzO?`yy=bOd24aQ~{c`2`{c1gEK-<7`W>davxTFp7&uM|P+F2@+9VoLE1{o`XF$K%|Cx z;#45e?QAlZ=s#TA;e>a^)M1^yBp9jZ9(C(*`DpDv=qQM0G9Xpu1U0mSRQF`wvT>iz z2Uxevi}B%X!(_6+Jg9aPiY?~lTxgGIc|`MBG?Rs6!HRCEsz9s#p#bxYq_|pb`hLSNLQP_1ZwRGb#zs7+A^7HXa;8hx-&)9OV1Ul==>8Lcgl*-#?r#c9v01 zaNB;c;Lquxhoj)#i86I*hh$CHd=bzXvV6bZ~GIE1O}UJSm>qYq<>Z~|a*Z?3w|{NWLKmC8~O{q<2oin#wD zPZtxW`rbh|dS16J+M2L2!$lr#!fW$`YQC`?4bT?Q>Gsf{5kbcrRq3<|9Z%B|cUdK# z5=t334+egSysc`kVryO~)py|b&esvb$372 zio-mg3XG&zlWHk>Q%bsW=mI(%rEAQIv?%b<`diE-udOd{=C+Ie-0?HtYGxWVtf}a) z+?QtviqrFPR@9l~-1vAfOK*+ zNwUd5^Hhyvf!VYWkAoR5Q~@B_&`ah4vqEQ$LRW%6MVzu0iKuz=B2h;$&JLeOFrpBD zw~c46duG9o<>fMtV;YYJyxO_8Nk@AoFRUhCH$)3 zxr#hnUw*E)glqkfpu*h6Grd~~pZ_jU{^;afv1}Rrn^(wdB{F{OW1=)y=fWL%^@hXs z-LY=|ss#4Nx8wJMmcm8s4`jBkhO|fajpei7Y=W5={I#u$_dM{OOZ1`B>Yq-MYW5*9 z^;&{2mq^f|5SlGlAD4b)z@u0@^XTqgxfVY$FD!A|Tu_T<3(B6OOF&p+GhdjZj#o#% z`qJsQO`2WdyNyZ-+`?iwB6mSw4rNdlC3X&O;dv`%|o)Bl~YLwI$ zRja3=#MeH>tfq5SIi(*j;>1Q$BIdL$T14|)y=oMZ*4#;i; z#stb$=}#<+ zVKkK#@9fXLn+tMU#$dlcI1l~g)|j7h)7C@&M=`6Z9*-H_hweX}|@ z;rj9jJ5|NI5NY*4;Y0w%nHkrxl|R8S*Tp;x4t^VyQ)TR?)c)GLU=0AszyCuycl6c+ zqkl==4Y8bEdqE-OCL`MbeeL;~xiZ=;mZm|Cus7+2D^css2C54G+~lHoX*WdquH(wB z#yLa)cE4c0Lc^O$?s&w4@Nu5Tgd|;QO@Ma79)OekM2!VyRtMOT_6!7gY!ITC-t}kd z<=*F6*ew)Fia(T8(Z1+LV?f*wwV^AVg0$OE(qOjPpHpqxz|r#S(n)w13o|S?Gc?v} ze4!(~ecin4BMQ<;fEGI5qyw}AQy{hoV?$_AZ{Upx!T5FbB;>fZJ9T?;l5Mwe^s5N685 zdf}JxrqB;unK?$vKSVCYoB#!7E zE=d^?Vl3K}%JsIN+<1SX(y&~8+X4W>2MU%Wl;d1|{x7K%yo6PIx0}@9pyHfij;!Vk-khjzr;Su;|@+GbG<0f@>*IoSOAi zAgm1ESz~joSn<}ON+*)zLIjR^6<(5id6tX%k)CH<8!}GvVnIjP#vI(wQ-$zDrA3pc z`VpTb1b-D<6NzwQ47L;9je=#L)j4FRF{%9YUkg}6BC*-kpMqmdo=3mfaj8ub#R@87 z#I4j#k6;Uv;vX{_f_B- z`~4ANJrKz8RvnzCm?iNy7Pea~7u90;N_QMic_&+RNJc${-3Q&wn|Am<8M2=^B$}Ii zT15_EjiVsCa9J+3AZZ-`M2FMFG!ll+hXe@V}aX zFF65BP;uP9>wDKMJC@X-(XOC_f?@snHicZxH-B+^yDu#{p5v(|gsDgbsV0o@iE7(IIRcwc=3q+qn zvV0fM5=4tC=JxS(L?-M=xXB)ZF)d?ZvOErzzCEBx!|HW*z}|?i;R3Y33Eu290V3xzl;LCkEWpLXS720(!=jc4~0d)W*l3hVQhU9ryUgaBdML;(`X5 zP{@Buoa>?i(f6nvs~b;|Utto{gzEfM?)pbm*N%$L^!xDwh@oK6AW9$i-k z(XY~kpyfXRB-5h@st)ActOy7$^A)`8oY0Wvx)_if`!R?lrxWnf8IP5JKN;H&f5J&N1puSu-R6pg5tZZ?%52s& zbop0vCGBcEw{?|PNfaJdh7NEWeX5YX52MB1JxuH_R8HCR>ul^45CNq*o54IH`S@-9 ztl-vqY^Hk4!0=4&5ljfh5tc3XEXt$y;io!yc}-^kOh|jfN)O~Y%qC7mQ~vhxJhpVa z#xd|A3%(q_PgLYflZkeLm6G(Jz_;vZoF9JcW5JT%SLzI7nf*w4rc|x86}k@c;Uwqf z0+g%2fe&MI6-=2&%mvX7rG$wejm>!|hy>@#!H@?ocX&rY05H`T?4Bc?;Tu}yN5X{L z#Z#WVvdM^tK@IThFR39p0L|oxefmYSKdE8wW28}yj`Y?rZ zpn<#u1L5u~?E-ybDNlf)1jlU!)>(IW2+zU>0Q(RtN8h;(lA#0{yzZ^!5!I{q95D81 zMn8|T&L}u^3yUeb*-s+^atkb=*2Ff)wxh^3L90Z6fk{>B_;8a$nH0lv4yvvg>?|nQ zgigbLRd8>r;TDu9*I|WO!$g5*?1-dV{@-J}JWHUF@qxBvaIA7-2A?*h;9t6t>udKo z4l+8(xdD)B9d|-Wv^6LZ)QjOqBa6O$@zt_Q%H$B@+Z2}saFmX+g$3uSLF1e6vd?U9 zor$TS68XKXvx1EKwAP&vxmT?rWz+!okzbd40`L0T3LY5vU@V)Q7t$jAbL9c7T`JPx zc~+Y9CWN{+o+tq!t)+P?x|WOvSKrRo;oj9QCEt&ymU%Zjr*TLRwQ6dMTwy1&vi(B< z1!{LPNkPk1N5ttp=FbctXhhWdk}y8_xe-)7vU#wJ*MGy&?gm4m6bsuOrs#{>aG^7lA8z}-rV3D(iX$0#L_hR^d9O~ftGnE zoA;I8=Q(H~yTY4Va98@9(JzHS9|ECE;v$R|3Li^{nT{R=t1Qk=NxLxnR4n*L0=B$Y zsKmdi4fSGY`!$9i*H2JX0%Uc?9nwUULEws*)v|GtvXAgBT(ErO-`A?Fs<#U4t5|$+ zy{ijP47%G?aIfcYX|<@Jx?Qp{@}w&kBiaidvD{zZGsi#G^$03_mAw1e<9_&(y3bDE zXu>8_i9bYR%}gsw<9o61IuS5#pkZe4rMe#zUHt8T4gDDKKl}mJ#8Ds>I)hqS2`zuJ zc>q41Tb;}-l7sRf44elnZ#UN;$95=H{JPqDsp=BmN8x)lN(Go^TRshY=XFqOv|-`l zbaIom(esv84<~$~tw0h2Yfb62UJMYRsWlbaEOgfqvo^v9K((OsO$pCkCMtaQ1ty#p zYEHij0()@)cQzM_>2fBuWztNlqX!w)i%eAhPCUCjT%sr<;c9>>N4DizI?pK06t)z| z8bQWj?SbuGFg?b;c4S9Jivj@^@6v*-Vgk$4KG*<#H*I8!W=pTs(=M=3Owz{>qp6Yr zhwbbjU)?v=Q|5x0ADR!~zrX*r&`gkguoHe1yYT3(!}>2z=!r}&{)pN_kQ2FurGLLD z*rKP-T(xY1`lt}HNO93S4kKC%HZ%u8LP(Qua|J~q1zcU1P8PW6F}m!Et)Fl`Q{7#BSjC&)=k5Oyx(SO^?d3j`gDsc9CtD2iKtkQELLCLP`E6diq!m7u~Z$ zcapRVN}k}RWZ45qU>i?X;3^rV-U>I0d-4HNf59Xqmm$qdAJ_d}LiB$pRyfHvmJ}!-Pn#a2z{4teUX<6QuyV-0WBb_JYAX6 zkA=acFBGJLaC6UXxYYQXWbk!xeh)}}55cmd%$z;nn?x2b!{lQbF{JaMa1U0lHyDxG zU7KexuzK{}-i3HB;?qi;#r$AHSkpKFJ3iq+U`Ohf10h`Dk}!T$(e=n&kqN8*X3pAT z&LxGvGgK9R2=e`oA&@l(CBmy>`i@E_ZBI1AfQhe9Ung3XaM@J75S;Xe(j#W!de~1K znluRnurHCm>lSM=*%fW}uOCU-_0ADB_L|<$oaekn0KNeGnRuVG8{p)S!m;VH0|Vty z7oQoJO7V_%FEiPG^>7cBZ-J&wa^T*_wN9Ns;Tmx2;RMBoL}+SVs6>di=w>KIg2LbP z@#H=}HtTFnsLN&>s&a)e9))=gmQk}=^Nk;S!Ch(~EGot5tF1^g=mIw`pOjqg$y845 zTs1>_WcVZ7Y#f5T_1!e7W1v}WdLGZY50l?KDS^@A*UF+Be3m0uGQ=Wb1F6ka%J=a| z9vJ*tcCE?UOKxC&g514@+2u(Zg2mnh8C@1&KT(o(zeRpn`l=1?uNOHg(HWHeE9dZ0>J_7xeInaLp?7d*-K$| zIxM$5KlRc{^5qZ6|ICu>aJoZ9r!D33sM5-9rK1pdnS5>sWO5{v&Hks1p$UrnNH9M%i$ydMDwo6*NxA zw>no^2N5X>Ub~S`#lh0V5>wh)IDhnI7L!n(sByYTfjVi7_nh0NG^aY%YQ{tq46tRn z)q|+2l^K!i#!AyLbJw_0ci8#alH@X=pAw5>jct1t41pL5i+EwhV3bq*WTP#3#0AMp zpS>NOU2;$#<57bnuS#tXL9E0I3fV4n)p6U>>y)`9J4!$u&zx>2P4H!}{0k?{AoLY{ zz6yE%^-^FYTKm(4`|okNsn(bA^BM5S%pwr$(CZQFKM+O}Pks7sLbt|@=vJMIze90>=#AWzq`YO*7m-it?1z-Je zeKK!o6O(CdVf8d^E}tamoQ{ShYB8b4O`V8lu~ai({Z~BSP2P`~MlHFKZ27`?Ug>gb@j&|Q2fVQr4pX6|bRP!THixHc z&%t>&3_Z7dmnf@2GhL`{GM6Y}&+7J;A+7MYn*gq>^*TN}4;MC5rkS_3@9AA+#Z-+< zK(Vv-&jO&$V*M<4e=IDV9BV&$^{ijEP&g~J4@!98J{09M9~0lmOj-;5XDd!7M7R$R zs{6y}!s=`u`q%plKMU}$s`J(rzR(H>$l8uhG&h8^BZyIh&RMEQZz&@I?+M$j!zeb< zr00ev$RtG_#e8wKO%s=M6>qpE@ZK5ySHBXLbh|n#ahoVe&Np0hNU;u(Y8eE;hETH@ zh5-09Ba@nHk`t9@qF${4(R+ZccU{D#2`lGX!%QSbV2r{e@ZHi;BBR9Cx&Gu4Mq{p_ zuft2!-mv&^3n7Z{Sx*5DG@pW)`d&YrM3cf?*nxMq{EC3)QXO9TLa;|NKfM{_B!rix zJ^Xn{1#z|d$+NI7HF0QEGL;(Y2w~u3e^+M@B^>brzHcUs5EJETyi3b8`8qOpQ2m0g z=3j7Q2Nm~0XmA`?#=Expc@&1=n;IQlFNg0C6tQiInw7y{b}i4BxT=Y zEcQDH>x=`xpjNDA>KC$WyW;1+Jrw~x6M@2ld%Bc|H}RxgWQj|ZEn>b6l)owBJ@4Sp zw5!9)t<5ARmG%N|_a9oi?2FKr-9opB$_|jFAS{3oIOx&%WQ~bNWbkFi{aMQk2XNHi z&Q8%6hLwR$B7@~?_UdZk@<;kjymyM}3g1`RT)l_iXft{b1j;!hyJWJVdnc`Z+vZGxeDT8>$4_R>UE-dU+AeeZ0=I9)J=Scz23BDE+@M zSUiU3&eT0~UdE5Rwde22r^ln7p)?BYhOOBXvQ)+;QwE#fc})swn{k%rbgzs#7_WZr z+aql6)M{ovZ^ko;sS#^6*6Is2ofDYoK~YpdohqDm)G9~biPwYqQpr&x-PoivRNkjZ ziNY1qxF-M7SH+#p>=@2`hs&+*}UPTKR+tg4ZIth3VE9k{T7%R5xc7ZM+ zZ<4&mdiq&L5mCZ_?AXAi3ST6K+vPEChyx052lxdsX;1iPWl%d`9(rJoJezGzMv-De zmkMqxDL3%ocDxBwld?NXOH zvk4i?B`)CO>H?H4vdf#mdK#rOj2cqkgyr+2FWUn)NBk=Tt*?D8BJQdC;43Ag&)90& z%lz)|B(SyJPmiS>AGHp_{%RPenQyY^!jv!zKg6EnnFdkg24DlUv2Xt7+}X&A?#j$$H~V84Ls3|BTl8{*oXkxRnEK?~UN?Cx zP_yCIH%Scpmro9eA0kkR>uFRovnraYmNjaUzqD}qiOr{i=Kv69Sq_Kr;F99Q^IOEx z9$T`8nl=Hx-5*^AANS&cEu;>!J_iA!U(m<0?jx2w&RxY%GAjV)tqR%LfLHD)X5l0i zxX53uIm(i(ZqX+?a_9j_=KsdY?uX(M%~7S|hNdckon5)u&cBO~(680+N<0{0tL@r{ zH*?Z!Dzj`;aa<5fkhgEm(OIlm(~=h8~a`P6yb0&*j2!qu5o4EaB`*+8gKI&Uz zueN#zqUH83Xax|P|g<_Z8ih|)Xw47>lmX= zC^l~6oNvUwNe1Q|MgXLNl~H_l5?hb-BEs%Vh30D4$$O?ar(TO*`y~)G8H%s z1<{4UD(|d3a*$B5m$f^K{=gNStpjsbwR$m7n%+t}iQ#hn%!Z1l4PALWx}tK-f&S6} zzz-hVtjfImu23O>(nPQn8}xoK`3=NRuJ(yL8)eTWi9j`MMsoD^SM%PA&zkARy&b|B zN!hA0_i%~lY|8iuW^QpX389+f_|%N zZeHJ`^r?2xa@EnGi!Imp+ZKA+gUx5gaPNVJ$QV7f`o=ud$|~^`)AORRlZ}qQ3?%|+ zLsK}KXS_AdE1vpw3uTkKpm1YGpg4?sRP;Klp)bSET6qCQ#I%8)xlz z;j)+QNzh0HPwYa~JZlllZ(SgYsYYLZ0Gz$MDAv;S#YhMksyzFCzKeA32BWRP2otjQ){5LTcHOa% zjS(-VT7ukg&8b?Z9$o}Ka+=ZnkR_tQ6^?Ykh+Y5R0FwqZ!xO^yEE*=3IkGi|1P~gA zp)2XCO?W3+HJuv_GPRB*dz^f7?)9<752J!6uW+Az@mAQ_SshAWa|}?O7&p$=-|eq3 zC8uymwi8{XYT$f8C;D6wRXoz@yHM=uxPiYoT{2j*E~Jgo!6(+0L!bWe&rC>ddyAcn zSV);PX(M-`L4^7lhuk;5`v$bH;oTpxG$uyclXvWQ?`mB}<` zLHS*I5|`0|qR2d6I!Gh32cr%+!x3%+JuH+4Qq>ccAfDXOL~bay>p>wwN{FjQuosX;0M{{@ z_xwP@1DCrKUSd2LWoK@|P^AG(EN?7iDwGzijrV?bLI$I;&0^>}OZMfc`i9g)q-N(B z0RwpOQ4PF9jSy^w_^(*3OQx)Qinw=QBXp!00b|C)eZJFpe~vj~P*E=l2}(98f?Elt z%leDP6P(O!3JN;CtoO1l-^ppuV2}*EyuC6!3(u?_1a1a;tV2RlfS%ESQ!Z$7N$Xcu;JV^lhVFL zM7Wyvkmes)P8Ac9lc8*U!T-ea*zRER-T70G`&5$$C&)P>PNtW|2-sB$A)>af@6ktO zfOI`1%S%$o2)%A;-rX|KS!Y(=_28!@dx7@$< z!FPJ+uX4^Rdy6^B=w0!Gb9X)rRyB#9xf|oa8A?`~pKWz}(`8`^ryIIvox8bkDKy@@ z-L_HB-GmXr@$>MXcT02PT}^i;{9AS6 z8qngHGFLnFoyCDRwT~7I4|D8f;uTot3vbowc%BPjo8>SAiqF7lDpTVWVx#7nB=I36 zp^0pqM#iG$w1?T~&a+2>3c{mg;LV_C5jV2?=;f7l$TL6yHytJ$=AJJ}(P1pPy#WIP z)*(6A*Ua|fJwQ*xt43iIh|Xm07JYl;10%KQz91{2?fyoX^^8i1d@KRVNz)Txa0wF_ zx;}z|^uBNSWfb zb$?otr8*F=$)sUzE7)JA^AgpT0r6UVFo^^O>f{gJ128wMTcPjLM6%k&8!p^Nw@WW% zI45@3^}Uq*Y6nZ&W*w-=k{rIB=Ba=z8Bw1FEq;MXXp6=}uYw6%vukV0a5lm5q!F+! ziM2|TF9dUF40F_(JqRZnBE(ybMk2}8RII8_1)+Cx-elYrzHUn?rPXfiP)ubtbtd4ir70)9-f-ITYsI*luWcj6Q%ow&R?J6L4J$|@A7Uj~AX)q!CVOD!hU zuDq_;UXQCMoIEY2p_5D2i!$A&4gL!B@#7&J_*|HH?4Rp8h4?6<$@I|D3&hs7UlbP! z_d8oDzj-@abQEZdFR*6p%E@ORV^6|Gl%RpKN}pU zLyAk~{0(}y7A@fL5-nFn%m3bKt&>>wFRV2nBoZbq1jWS6*z!mkdpXfVdB%|z`}^@} zY^EcE*!H7-*{913p+^6R(XAFf)2*m)QEL$Sx63rapA^+)`!k&N$1GK1 z4ZlcEnzkUfcJ?Yw=9Z?}M36tL-7=Fdx+HzeMPrl*_m@mW1xpVvNuq2w%=!J_!SD5V z)xA`^Ad9@zzvR}b^?)R@Ot*C%4vrP6A`VZ2=2nWX-P4CDuXO06by*Chny=rTj<6Mh z(){hFm8FwLxlV733cuSEm$h!|J2RqUw9uPCgmV9e&TTp_9`LdL0GxNc=8~o`KePD4 z9!}vx5J|xUztD9_DP8vzY=tb+J;33izHNR#9fuD*o;O*-X+y@oz!g7RcdGF6$gU^~ z?(1o+EKi01&Gz^cWMi0{$keFr9mI1oEYpAAKp7BzEy+<#WQk+-N5wMc;aNZ$1#E2h z&U<8kOgsUGTbeL+bjg}*3O#Zr{@F(|I!N!olh$+7qqpsKZ9kbU z<|7+j+rHCX*%>K)?(+z?#rfzSKx#jmO(}0dQ4emFp11e~m8jnX@Q>)6cVq#Ukxa=g zAu90i&U~Hz&Y&hm$|sDBuqXJi@;+R8^4XvPLj8zX;LfAuHdCKOw-gBwz$wG`B9+5# zfVoo3Mt2CqorD$98X;HE(hOOe01tULWDy$13Gk)M_xMZ(8|dmEV$zrt>`a&Jl+=DZ zbSp548LaeDo1>35f`_vGh9T$n0MSozr3;DU=+hp=2(Rm&X1Ajf7(l{6YF2<8iKsZj zPL+E76y=qzpEzPU!^~`KY{}2S&%;a-Wg6c~ZI{-vd2zobY2M0>g6A}(*CEkP9Sk(m zH2@X4zdtBAhee<5J)KqvVP?`JwF2si2h)nKEptL{8ZDk=@x(sRhXGgYkWd46 zh`lMScFa1IadFlK2UDaU-!{wj)Kigaf8~u3^4#PJl(PT;F$t|hRgla#TtVx9Xc^zs zl%#EQiKz0hVjO$oLf;>qLcERP_PsP^-pM-17fyq{%Ff!Y)naE6CBCuOoXE-=vUqwy zCGFB#K)U?ZqV}&>L*iq{l`#`7jI;qCSzlJ<3%hkw%k0&Qo8RK0-3sNp^IXb!1SNIm z@VKB&@74HCJ8rpZogqFaq)q%usp)9a`6o<+N+vBq_E-ce!}nkRQ+BH$q>V!=LzaXh zPP#i|9npO7$LnLoxK7f~t)%M`)Y0_sEC(=>us~USml+aXTgeASKof43K`#vHL^4m& z9;4XxDA|FKT@E#`A+6+(%TlEC+NlbghDP-O=z(L}#~Xn+QlX?s8kYV&8q*EzvL&nw zX@Z13q6eKDv81aT#FMDgljCpMs$S5nhBHo57i4KJAi@hNI)B7axNV3z6x1nkCVmHk-SmxHEqno!g{rw7)oZb*}gz#3o zERm66be-pt9aoJpEn8Y=fAeyPF1izRgTi%3e`eBg6i9}ap#VlO&7-3OzFebxT8^DE z|6`F$`~XH@1i}A}Ytqb0AeE^@wAecDqg z#*(`2;P?jm`Mj7yRge^b;1b3an^3{PPlv){IEGJ6{}-SSNi z4NP88wf}+H1K0EfICY&eo5apNvGOyS&jItI(@aw}Z=9KNGN{vyMV{#mDMZKO=gXG^ zN}R(NPK#sq_g1C_y?A15`WvoaJ#{B0!>EA0 zJpd5K;ji0!7bLHkvX7=j(BmXGjV=nPKO0}EP!{zA^^(6J_w|aY zTlX%DQo`3v1v5GGT6i^rZ&Y+3z(Stcn1|nTzGTh{_s5H*U-ptlW?O_RH8U7zzrC-K zv^((E^enrlt3*C}v$+4hHi_DaUlyH#6l8(+)LS%qutjSA`eY`1w)m*lB6T3Yg zPGG2DPIWbyu_qb;PdNdB(VKDP6xLT=8N`5CgQCy}?WrADa%|yls>O%?gV5kZf*7o^ zg-Y#Y3oFjkS$p4kAhl}H+4QVTLR&G_^4Cr+cJTs_6_xC0;0riru23>Z%x@I zauFpi+`F((HhLC&^uhdtDC(&v2O5TYCQ~*Cwu2sswWXd6Y3!N0W+&cWNaRmHl~eLH z6j_17A)PBd+7y%o8`hY=p&6!!qs3H^+@l`Kh1NwxMvq z@y66n(L`lzvTAr@-j1jK#UEb^42X zLw5*@rMhWq!RT`7H%T4hZ#85(@DvbZ@je=rg(MGmpW8-HW3fw^kO&d9tm+% zHl~Rfy-J6IEfX-*{?eO%EzLq*Vea{R0IR8lv_eD-@#7XhaWMJRu=(!CUy_TfP@~Mr zDaOR^3X6Q8agI8bF^0>If84|UN4|^4*6^DUAyNjtH0J2khr}{Ywd$m2F7S*0!rM)ckHBSBfCTNzPTij0C<6ZrRj{|s69CG5rZzXHC z6ZByitj6x|iyJ2lf#Rl%g{j?N8y`wyXHXA7(@Du=(AdY;{s-e^+dHedBX@#uJyJk^ z_gFhcj8pz$G~4&Y-+9IhdGd%)H4SZZ3AZk;=De{a3aPR=nEY7}(mNk&S2h+=!2_Cd zlrRP|8z{=(e5>>dD}rIq5CdKxraM!nT=pD<1!eSU$F!4JXtv&z)-Ml_zL2t|sw6D5L8 zG!rtpc{Y$I)L5QA!jqjq!_6b#UWJT33)EStvs^%>U&Sk6rsq?JzDUHb{0cM^i|QQK zps4G8zbC#>x6`1hZjPEA<)pqT)}w;8IYFiU6jbSME5@}qbP0NMb`F`U}F0h`2b`WoHm292Y+Dl91$+0Le^=V-13C`2@i zw!`+iHgl-B{R?A|ttG0dfUBnd9iP@U2DL2s8)UC0zgT%gC}w&HTUuwos~=a7su+q+ z0iP#Pm2gy&-8P4UAC(Os(CXo{3z@w%Mt#H9A6-Nb*7es}R!KptGEG9;i<*q= z&ah#c-@il;KW$%hhfPwnqV?SflJ@~%`R(Y58Jq$gr7}+q~P#OIvb`W z-=8;v6{`b~bt}^9`DR%y^Luen%fwN|mHcfwOyU#&JSCRBb&mO3x(@zHJ>VA1m*)|% zTDk6XH}oPzD#r)GE5>Du$Twp(Quei1shem8Y&2g!aWsW~tg{>NCiS2G;vxBZC8e~l zCf8{3=-e3+>646_=^YUd|I#fCc*8vKX>1$Q>v>X`nEf<3+vYQj`^*7nhB_N@tjiTx1FQouuZZOYke(p3klc}5P(Odr1n6gU3;rT0-Z2&p0t z>%rrFIa*EzHh_O+HWLPojbl06KSM;uW^^ZVDGQ{WARnM8aJOxg+u9%>>Y-lp!t2@038L3yX?^&Ig@ zfWB42)Lb{cTC3r?4j*|9$6e?KI@I*Nv>G{{1SZ(MVCeLzd0r!C)P=IARRSC(t%9c> z>wE60%K}d1mo}jR4?RA;zb;O$Ldlx3QN+ zO487dITyv@2oK0*qxah1!rbAoia)+`L?P!v*&t`B=_x_DiFGW=6odf?pr&rur!4;Ir&+UW#1jT3V)+V{Kd zQ?q#vMK)tHsjwHF0lBFE1JXvC%(-^IcgOzDga?GaaT^%VZZoC=GMK$a$lpl^+Z=(! zEwBFx?S_-nJD1AjTZk%VBgedls&t`18v0!c;A`fSWsPhZVxHT^KVJ0oq+xwZ%w-ne zQjs;&DARGAdMBfavqkS3?fVELGHm62-O0hng9HBPuJFsKb3?QwhM_1(q+x+JtpINC z-N2bzVl@-(DBj{C-MO^iD>c<=6Tk;i2N1}ig%m28tZC?VCSp3DV8gB3u!VHcP+P~y z<4C4T1V$e{TPxxfRuqeE$?^t9|FJ* zZ-h`mt9o2$z}+f~+d7|sUr+y{;P6bk7-J;=yJ-a=7z(X!9i_VHIGm`}ui(rIiTx~p zSrbsC_LK6~g3)%ws9N|qhnCpgyA&t}&vw9N8Hh%Na|hzTFZwL4qVj;u!PPzseRxbX zG1Q7t;?IPhUgz+unfxmT)~?aylND%zVwPArI)W-GHQaj0g?vX~6PIH;~=X!o24sXYCXl>;*xai!z)YyZFum zQIpD*JlRXBK=UijbZt4NUY01K=-bE;+&KvsJa{Pb!o$y=q zm3#5y^=qqlr~gLFz7nEN53f>?^>kYBvSBNYBGzY!_b{0>$*1vlikdPROYx}96@i1s zY}*DR6jJ1uvqT&3_H5{8K@%FX3aSK&FsoN_>P<(QC#NkQ>V-ibTmKuWzE0Q-!6f0s z`%{QO8>!z2+0rQk^ z*d_Gkxn=T)_ zs;wVoU~KLfLMW#STW{(x9rtBSRprn%?|o(~{GKNpTlaSxJ9n{AVL_5jVyIq%v5=O> zD~}yg6?1x*R|9WTldbQ-alVCCmvRyxIC*AmiwF|$Q$uCB(>>|X2BI!2@RNY()!9q! zh&VXGSYnJ4_+SzP+PnPnRP+OgpV$7{T>`2)g`;C6m?tm$hGbZj;M&2r?!mwXlHVd7 z9EObhOiSCopDLF~a9P)(h_^9CBfpk>Cm$2upG>{$i~~Cun8G<@`4NPaj(LNaz$zAa zlq#W0(9i)rpP|=J&=A?Y+`2T7PTWs%R)RrSDGCLo0kiK#x#7J`wcpa>h_V>U3fEVv zQY+qIeo}*|O#5L-tw?9Iv}bTaqYI%SMswnRM8q-@<@1HnTlf9*9wn?L+i|UD_pcLU zE5g#gMwTo{WtZ7$UrJ12VcK&np!{hhk5 zGXyvks`928c`MvaTrd4QpQD)k5xy4uS&&%lVii&M>(0Bfci`cbzJ>DZaA`q5wde-q<$F)&f{XI|`H(bc#hC5stj6?TxowgRH+X&T zlIXalyALrh!C=WxtOto0t+7D%UoEbU?_<+B%!qiVf}6`)-yT&^%DRo!OjlBlN@q>b z9@4EpnOp80cXqsuwTu&=yHJnuu$ zM;@AVL9sm9@MjE~BUS$IQ|E_^oF^q48$8O>fBBW#2IC@N@`ePVmMzN$^d-6qY z6coNXrm>_^A-nwjSUVs0B=G(N3?(H68Etq1gf4AYVdr18$=d<*fxeS$+_wVy<1H?6 z_Wa$FGlGFR^84bj*=+Q+oNke`|EEEcm+M~e%k^pyi3H0wB*=@urdbv2k>uaMI~Wl- z>V%j$--IWkb?qdT)HUaK1ah~nuC1LS?7PLUcQ^7g6HlTH7&Dnf0~m2)AzNOvCMwD8 zwG>+jf6=N&vEjd2$lN>NjI~mGK7!>stjHEyE1lt3oUN!NKSj2hOZ@0}OdKXG3iLEO4 z?wZ~|1g>Ok(O4MYMS&EH@o7{acJ-u(z2X=w5D5WhUOg?0u77CI*N2|thxRLqCAs!B z&RWuW?c;2NEbfd2D$q9k*Xn6tJ#xRnjs=gAA2CE+K73(0aFlL~Gh7bSS@FcaUflkLmyb(x80;#g*K;Mo(oOgwNJev1^(Y61Db?awR#`*rF~ zk8Y)`t97swIJQ0}IA}q&q2=bb#J}lYFNj`AJN>hi8f>zubm&pEb<9;-um()9!nM~F z!1gNg{NEWh3mZNuX=Q<$z(*cfC-u5emN|ozff$8MBlQ3P5Zp#l3IbKreHi5`RgK&& zzL3|P4}EM~avKzB=}5A{guc`nO?FPPdV0LGBE-NF_<#U~G-czm0K!e9)WF#QhRzF! zm%M+7I0+}ij7QKbO&r}7hsLZWo1EIwUkD9zB9t@tkKoJ-ih_oya4f5ms_Zxql;B%Jje-?3*#lA1g&ZVZc~@AuR67Jl z@{|i%txtG_#8+?B1|j-%&(RByIhwMBSaWyNdtaP3DvUhAZvSda)8m*QIl!*)rR1uG zk)K5X8&=wMLB8hMXbt=2#GUDv<-C^`ij~p`luA|)II?lAjAbnl?LK@cFS(CShF>nC zSk$m~;q?B=j0(&4)loe)6yH3xzk6O+9sBuG)}qoOr))%;ZO`?e9UcQ<@HBATf@y?} zG}RE4v9DMpZO|Sl+2ZOeNq<{o8>{P5wcKx+Wd}(2s24eW&WM2P?%GTjtGPVqQE^IA z%%#I`N>p$}6BS3dHHyq`LxCVg*I*bDdQ|jZEZ#FstI4O8uR7Lu#LTXjuhyi1B)*mjDe=&5ue^qRIRn;h7KRr87VYJA8YpjZ=RpsL z&$yh_Gbel0iFpDx_h275Osze?fhaTy%k`6uvwXfZc}IAxT)47R3jLj6$|nRd2!xTx z{)XvDzV6Z>>@puBPDS4e|F#qM_CZOg3(XvhWNYr?sr_pT6Guf`qEiGSnw7rv6umje z2z#rfF&PJf>RW`PGpKBlB~e=Ne2Yn%c7f3jJxL>E1=kFlUT+(NGc4D4_^I(A5Z2Vr zhd!8fqK#K2+I(;izdL(5*s?s~)U_E3lG=taelSZEwQC3e7HOezzw?jp zVN%ix`HL<+jXh8jT%LwP&{~%c`Q~RXua*-ZUS0WCdO1m5^6<3FbpW7Q-7r-(A5N1g zH0i`pHvLcv$A_j&&i482^*cvdCv7pH{*0e~WHZPib|FmjCHP;Or=ElNplC4SFf1lF0-WlhcvO*iM!)TPny?_kqCBwLpvNO^-r;V&x&d+xel zgf3eLlUf!`7o1UE;vs#ieV>Ibes< zmKGu&k@1FPpd7hc8hXn}2tjsdjd6N0a3X2H?)Un5)a_OE;huh*G@{zGkkHAjbPVD&cz%e%uqZab&!7N? z9p@lLg^tZQ!X|2-tPRLyDzdGUC4}tsyqvWy0X_YwDCFMs+&s-AbxOj_0zf#PQxuQ3 zD-(vv>IGjP+vtjSQ*p^}>-^EmqJ|0Ts|p*fdC9GHt4%o4`!r|O&)FIRrtvXWt34|O z*12=Z6LLvSle|$~KwR&;LN@OJH^Os87Ew+Pso&r;mKUC? zZ0Od9ELnDqYE^r$u9OyrC}p>m3x*yCT4iTu4g88pU<3y#f03xXShqLL3a)`=1jXo^l_57}p7T~7@|XIsghlMW0C8*kyf$5;E~3nN1J&oA` z$rkypB?&$I+2!T1rnqX5+XtP2haCED+mw2@lOCe4g%K(t?%QeRPMO`eLg0^LUGVwc z3Wm8YvaKXmO%m;Gq#GrESIerNhoPvYNJ$GMS}~*jr-o8DW%BRrfplheL5pS$yNKq2 z7Q!Fq_V$35&7)){ML(HT>E9ygbT8mwVReR~i4D`LO-zH9 z#~uLi$~1~aA*`!q5cBsGMevO9OY4S-rGX@!ld5(R+A@vb$Jpl<$`OW=_N$x$kxGJe zSsf*jg{>>@(ru8-7^%3De7)teJzA`xo6-H{HsI?{h&K>{1v7}45JT%3UCkBFXRgoL z&eC^&u~Km{_YC9&y`~zxs~<4QIU@S3z@R;sNaew+9bCxP6O=(MlfS>X*TiDA14-~P z>Oi;Jyn&u|0_F=Iu*>nh_x zD?F0dOqEP=KZy6Zp#FUz_?(H*joJ-wjf@n?ejBgjZL%V#jU9)xVz`oN`$v0;hUK87 zTtceFt0=GLT0!c{=5Q%zhQIfRs9x5I-Tn@7a2iwf5Hv#p>?{NxgF-Eb<(jBYgIB`8 z^UooxTh*Qq_f+;^z>eT4^Isc|5>Fc$!}SuS#Ft`7(xFzFCr?2KBUeh^S%?uLdMnx6RrZuiM9mP~cv&d8tob1P1XOFKN_c z5ErK`dLP%=S%21x$#**0!dThJF>cpc`~jbg)4(H~zVMEZ9<)$^H*dLBjF`bib3vw~ zU@a7FPswahde6IW)yxn*$NcU~LbvlG%I>~|3RVL1HRs%q?mZiL3=f8y097{%E-nA9 zJ}zevBB!0azk}5VMfGsFuQ=)z=2$hj;^Z%d)wq)9KPr?)Ws6cgsmR;|@9&A0VXYCt zCczYm=TKi5j+rum6Ck*VOUL~qM2O{iX^?H*s-?6WwRfPFOiRp4j$-picWp%~e>{GD zc3%G>r(=-Zu;1YqZ0Mvk%k^aF&P%7o#{@MJlGs~?nG$?PuW9ATE3VF2n46F+!SrY* z41U^YxC8jpsVH{~^N)t$;QrfZJkEbs88Ghjw{Q37bex^Q_^Z%7Romov(=%A7yfPN4 z^A7sh_n`@FjD6`eHT zdC6k<`E0|qj@gEQWmtz7%mpfT?~3ZwF;R5~r(yFtg%}eTI*T{(q0Ffg3N?N(uiE zk@I~8;C_40j85Gs{7MDcGaEsOr6vIS6KFNXZ)`&H1{78k?^2ZV2ZOq*3lWuo=aB@J z0?W-;YA@ea0m{C0Fe!2*dwBUbhNIb>bMuDD+4Ll|V!#4OvQ$%|8Wl5Efa+akkmPce zZDU$}C=b5NM+{S3=Ehsu&IgdRkY@>qYcp?iWe3hd=6>%DXS3%iqWXXW?+g=BPX}R2 z2la)uz#F@;R_uzq>Fs?fZPme|YlnHk zMShbNf{Ag{yrsg*D;XvU3+_-qBu4zM)G!usID}je%%_QjSA`#l0E!#W~R+5g7?Ay@JR%139G4IJNjx8JM3Tq}7vXj$P4Y zb#?qcZQ(DWjAKUrNoK`wa{L8kcC(0^tt62$G>C);*7S-rR73 zxt^_OLHsugxGp!*^xj*oJCniSLy{5gvesc!YOf(Xj65oTkO-%`a_yM6$B`2gNNd!g?x(ZgroJTXN{=V&CRVrJOnq*6V>tgq-WTkrgu=C5P+d44MNq_LExMiqMp-7Sa$IR>}~>pW8psU6zGb}x-yiXuH8UoW}pwr8wMAT1s>g7M!9{eOZS1b6B2zrp?=r_rqN l&*$EWeF-lAKe3(fA)EhwxBu$`$c{24cjy0;t>6#<{ul0ACaddArgument('username', InputArgument::REQUIRED, 'Username') + ->addArgument('password', InputArgument::REQUIRED, 'Password') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $username = $input->getArgument('username'); + $password = $input->getArgument('password'); + + try { + $this->userService->createUser($username, $password); + $io->success('User created'); + } catch (\Exception $e) { + $io->error($e->getMessage()); + } + + return Command::SUCCESS; + } +} diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php new file mode 100644 index 0000000..e1aa9d3 --- /dev/null +++ b/src/Controller/AdminController.php @@ -0,0 +1,102 @@ +pollRepository->findLatest(10); + + return $this->render('admin/index.html.twig', [ + 'polls' => $polls, + ]); + } + + #[Route('/show/{id}', name: 'show')] + public function show(Poll $poll): Response + { + return $this->render('admin/show.html.twig', [ + 'poll' => $poll, + ]); + } + + #[Route('/create', name: 'create')] + public function create(Request $request): Response + { + if ($this->pollService->checkIfPollIsActive()) { + $this->addFlash(FlashTypeEnum::ERROR->value, 'There is already an active poll.'); + + return $this->redirectToRoute('app_admin_index'); + } + + $poll = $this->pollService->createPoll(); + + return $this->handleForm($request, $poll, 'admin/create.html.twig'); + } + + #[Route('/edit/{id}', name: 'edit')] + public function edit(Request $request, Poll $poll): Response + { + if ($this->pollService->checkIfPollHasVotes($poll)) { + $this->addFlash(FlashTypeEnum::ERROR->value, 'This poll has votes and cannot be edited.'); + + return $this->redirectToRoute('app_admin_show', ['id' => $poll->getId()]); + } + + return $this->handleForm($request, $poll, 'admin/create.html.twig'); + } + + #[Route('/delete/{id}', name: 'delete', methods: ['POST'])] + public function delete(Request $request, Poll $poll): Response + { + $token = $request->request->get('_token'); + if ($this->isCsrfTokenValid('delete'.$poll->getId(), (string) $token)) { + $this->pollService->removePoll($poll); + } + + return $this->redirectToRoute('app_admin_index'); + } + + #[Route('/_results/{id}', name: 'results')] + public function results(Poll $poll): Response + { + return $this->render('admin/_results.html.twig', [ + 'poll' => $poll, + ]); + } + + private function handleForm(Request $request, Poll $poll, string $template): Response + { + $form = $this->createForm(PollType::class, $poll); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->pollService->persistPoll($poll); + + return $this->redirectToRoute('app_admin_show', ['id' => $poll->getId()]); + } + + return $this->render($template, [ + 'form' => $form, + ]); + } +} diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php new file mode 100644 index 0000000..a6eeda2 --- /dev/null +++ b/src/Controller/HomeController.php @@ -0,0 +1,18 @@ +render('home/index.html.twig', [ + 'controller_name' => 'HomeController', + ]); + } +} diff --git a/src/Controller/ObsController.php b/src/Controller/ObsController.php new file mode 100644 index 0000000..a8f73cb --- /dev/null +++ b/src/Controller/ObsController.php @@ -0,0 +1,36 @@ +pollService->getActivePoll(); + + return $this->render('obs/index.html.twig', [ + 'poll' => $poll, + ]); + } + + #[Route('/obs/results', name: 'app_obs_results')] + public function results(): Response + { + $poll = $this->pollService->getActivePoll(); + + return $this->render('obs/_results.html.twig', [ + 'poll' => $poll, + ]); + } +} diff --git a/src/Controller/PollController.php b/src/Controller/PollController.php new file mode 100644 index 0000000..90c668c --- /dev/null +++ b/src/Controller/PollController.php @@ -0,0 +1,64 @@ + 'shortCode'])] + Poll $poll, + Request $request, + ): Response { + // If the poll is expired, display an error message + if ($this->pollService->checkIfPollIsExpired($poll)) { + return $this->render('poll/error.html.twig', [ + 'message' => 'This poll is no longer available.', + ]); + } + + $voterId = $this->visitorService->getClientIdFromRequest($request); + + // Check If Visitor has already voted + if ($this->visitorService->checkIfVisitorHasVoted($voterId, $poll)) { + return $this->render('poll/success.html.twig', [ + 'title' => $poll->getTitle(), + ]); + } + + $vote = $this->visitorService->createVote($poll, $voterId); + + $form = $this->createForm(VoteType::class, $vote); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->visitorService->saveVote($vote); + + return $this->redirectToRoute('app_poll_show', ['shortCode' => $poll->getShortCode()]); + } + + return $this->render('poll/show.html.twig', [ + 'poll' => $poll, + 'voterId' => $voterId, + 'form' => $form, + ]); + } +} diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php new file mode 100644 index 0000000..76bf5c4 --- /dev/null +++ b/src/Controller/SecurityController.php @@ -0,0 +1,32 @@ +getLastAuthenticationError(); + + // last username entered by the user + $lastUsername = $authenticationUtils->getLastUsername(); + + return $this->render('security/login.html.twig', [ + 'last_username' => $lastUsername, + 'error' => $error, + ]); + } + + #[Route(path: '/logout', name: 'app_logout')] + public function logout(): void + { + throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.'); + } +} diff --git a/src/Entity/.gitignore b/src/Entity/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/Entity/Poll.php b/src/Entity/Poll.php new file mode 100644 index 0000000..8b60573 --- /dev/null +++ b/src/Entity/Poll.php @@ -0,0 +1,226 @@ + + */ + #[ORM\OneToMany(targetEntity: Vote::class, mappedBy: 'poll', orphanRemoval: true)] + private Collection $votes; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $question1 = null; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $question2 = null; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $question3 = null; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $question4 = null; + + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $question5 = null; + + public function __construct() + { + $this->votes = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function setTitle(string $title): static + { + $this->title = $title; + + return $this; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDescription(?string $description): static + { + $this->description = $description; + + return $this; + } + + public function getShortCode(): ?string + { + return $this->shortCode; + } + + public function setShortCode(string $shortCode): static + { + $this->shortCode = $shortCode; + + return $this; + } + + public function getStartAt(): ?\DateTimeImmutable + { + return $this->startAt; + } + + public function setStartAt(\DateTimeImmutable $startAt): static + { + $this->startAt = $startAt; + + return $this; + } + + public function getEndAt(): ?\DateTimeImmutable + { + return $this->endAt; + } + + public function setEndAt(\DateTimeImmutable $endAt): static + { + $this->endAt = $endAt; + + return $this; + } + + /** + * @return Collection + */ + public function getVotes(): Collection + { + return $this->votes; + } + + public function addVote(Vote $vote): static + { + if (!$this->votes->contains($vote)) { + $this->votes->add($vote); + $vote->setPoll($this); + } + + return $this; + } + + public function removeVote(Vote $vote): static + { + if ($this->votes->removeElement($vote)) { + // set the owning side to null (unless already changed) + if ($vote->getPoll() === $this) { + $vote->setPoll(null); + } + } + + return $this; + } + + public function getQuestion1(): ?string + { + return $this->question1; + } + + public function setQuestion1(?string $question1): static + { + $this->question1 = $question1; + + return $this; + } + + public function getQuestion2(): ?string + { + return $this->question2; + } + + public function setQuestion2(?string $question2): static + { + $this->question2 = $question2; + + return $this; + } + + public function getQuestion3(): ?string + { + return $this->question3; + } + + public function setQuestion3(?string $question3): static + { + $this->question3 = $question3; + + return $this; + } + + public function getQuestion4(): ?string + { + return $this->question4; + } + + public function setQuestion4(?string $question4): static + { + $this->question4 = $question4; + + return $this; + } + + public function getQuestion5(): ?string + { + return $this->question5; + } + + public function setQuestion5(?string $question5): static + { + $this->question5 = $question5; + + return $this; + } + + public function getVotesForChoice(int $choice): int + { + return $this->votes + ->filter(fn (Vote $vote) => $vote->getChoice() === $choice) + ->count(); + } + + public function getTotalVotes(): int + { + return $this->votes->count(); + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php new file mode 100644 index 0000000..62b276e --- /dev/null +++ b/src/Entity/User.php @@ -0,0 +1,112 @@ + The user roles + */ + #[ORM\Column] + private array $roles = []; + + /** + * @var string The hashed password + */ + #[ORM\Column] + private ?string $password = null; + + public function getId(): ?int + { + return $this->id; + } + + public function getUsername(): ?string + { + return $this->username; + } + + public function setUsername(string $username): static + { + $this->username = $username; + + return $this; + } + + /** + * A visual identifier that represents this user. + * + * @see UserInterface + * + * @phpstan-return non-empty-string + */ + public function getUserIdentifier(): string + { + $identifier = strval($this->username); + + return empty($identifier) ? 'anonymous' : $identifier; + } + + /** + * @see UserInterface + * + * @return list + */ + public function getRoles(): array + { + $roles = $this->roles; + // guarantee every user at least has ROLE_USER + $roles[] = 'ROLE_USER'; + + return array_unique($roles); + } + + /** + * @param list $roles + */ + public function setRoles(array $roles): static + { + $this->roles = $roles; + + return $this; + } + + /** + * @see PasswordAuthenticatedUserInterface + */ + public function getPassword(): ?string + { + return $this->password; + } + + public function setPassword(string $password): static + { + $this->password = $password; + + return $this; + } + + /** + * @see UserInterface + */ + public function eraseCredentials(): void + { + // If you store any temporary, sensitive data on the user, clear it here + // $this->plainPassword = null; + } +} diff --git a/src/Entity/Vote.php b/src/Entity/Vote.php new file mode 100644 index 0000000..33e0088 --- /dev/null +++ b/src/Entity/Vote.php @@ -0,0 +1,81 @@ +id; + } + + public function getPoll(): ?Poll + { + return $this->poll; + } + + public function setPoll(?Poll $poll): static + { + $this->poll = $poll; + + return $this; + } + + public function getVoterId(): ?string + { + return $this->voterId; + } + + public function setVoterId(string $voterId): static + { + $this->voterId = $voterId; + + return $this; + } + + public function getCreatedAt(): ?\DateTimeImmutable + { + return $this->createdAt; + } + + public function setCreatedAt(\DateTimeImmutable $createdAt): static + { + $this->createdAt = $createdAt; + + return $this; + } + + public function getChoice(): ?int + { + return $this->choice; + } + + public function setChoice(int $choice): static + { + $this->choice = $choice; + + return $this; + } +} diff --git a/src/Enum/FlashTypeEnum.php b/src/Enum/FlashTypeEnum.php new file mode 100644 index 0000000..a1ff254 --- /dev/null +++ b/src/Enum/FlashTypeEnum.php @@ -0,0 +1,21 @@ + 'alert-success', + self::ERROR => 'alert-error', + self::WARNING => 'alert-warning', + self::INFO => 'alert-info', + }; + } +} diff --git a/src/Form/PollType.php b/src/Form/PollType.php new file mode 100644 index 0000000..0695254 --- /dev/null +++ b/src/Form/PollType.php @@ -0,0 +1,65 @@ +add('title') + ->add('description') + ->add('question1') + ->add('question2') + ->add('question3') + ->add('question4') + ->add('question5') + ->add('startAt', null, [ + 'widget' => 'single_text', + 'data' => new \DateTimeImmutable(), + ]) + ->add('endAt', null, [ + 'widget' => 'single_text', + 'data' => new \DateTimeImmutable('+2 minutes'), + ]) + ->add('duration', ChoiceType::class, [ + 'mapped' => false, + 'choices' => array_combine( + array_map(fn ($i) => 1 === $i ? '1 minute' : "$i minutes", range(1, 10)), + range(1, 10) + ), + 'data' => 2, + 'attr' => [ + 'class' => 'duration-select', + ], + ]) + ; + + $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { + $data = $event->getData(); + $startAt = new \DateTimeImmutable(); + $duration = (int) ($data['duration'] ?? 2); + + $data['startAt'] = $startAt->format('Y-m-d\TH:i:s'); + $data['endAt'] = $startAt->modify("+{$duration} minutes")->format('Y-m-d\TH:i:s'); + unset($data['duration']); + + $event->setData($data); + }); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Poll::class, + ]); + } +} diff --git a/src/Form/VoteType.php b/src/Form/VoteType.php new file mode 100644 index 0000000..830a98c --- /dev/null +++ b/src/Form/VoteType.php @@ -0,0 +1,43 @@ +getData(); + $poll = $vote->getPoll(); + + $choices = []; + for ($i = 1; $i <= 5; ++$i) { + $getter = 'getQuestion'.$i; + if ($question = $poll->$getter()) { + $choices[$i] = $question; + } + } + + $builder + ->add('choice', ChoiceType::class, [ + 'choices' => array_combine($choices, array_keys($choices)), + 'expanded' => true, + 'multiple' => false, + 'label' => false, + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Vote::class, + ]); + } +} diff --git a/src/Repository/.gitignore b/src/Repository/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/Repository/PollRepository.php b/src/Repository/PollRepository.php new file mode 100644 index 0000000..759849c --- /dev/null +++ b/src/Repository/PollRepository.php @@ -0,0 +1,67 @@ + + */ +class PollRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Poll::class); + } + + /** + * @return Poll[] + */ + public function findLatest(int $int): array + { + return $this->createQueryBuilder('p') + ->orderBy('p.startAt', 'DESC') + ->setMaxResults($int) + ->getQuery() + ->getResult() + ; + } + + public function findOneActive(): ?Poll + { + return $this->createQueryBuilder('p') + ->andWhere('p.startAt <= :now') + ->andWhere('p.endAt >= :now') + ->setParameter('now', new \DateTimeImmutable('now', new \DateTimeZone('UTC'))) + ->getQuery() + ->getOneOrNullResult() + ; + } + + // /** + // * @return Poll[] Returns an array of Poll objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('p') + // ->andWhere('p.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('p.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?Poll + // { + // return $this->createQueryBuilder('p') + // ->andWhere('p.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php new file mode 100644 index 0000000..4f2804e --- /dev/null +++ b/src/Repository/UserRepository.php @@ -0,0 +1,60 @@ + + */ +class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, User::class); + } + + /** + * Used to upgrade (rehash) the user's password automatically over time. + */ + public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void + { + if (!$user instanceof User) { + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class)); + } + + $user->setPassword($newHashedPassword); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->flush(); + } + + // /** + // * @return User[] Returns an array of User objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('u') + // ->andWhere('u.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('u.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?User + // { + // return $this->createQueryBuilder('u') + // ->andWhere('u.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/src/Repository/VoteRepository.php b/src/Repository/VoteRepository.php new file mode 100644 index 0000000..aadb21d --- /dev/null +++ b/src/Repository/VoteRepository.php @@ -0,0 +1,43 @@ + + */ +class VoteRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Vote::class); + } + + // /** + // * @return Vote[] Returns an array of Vote objects + // */ + // public function findByExampleField($value): array + // { + // return $this->createQueryBuilder('v') + // ->andWhere('v.exampleField = :val') + // ->setParameter('val', $value) + // ->orderBy('v.id', 'ASC') + // ->setMaxResults(10) + // ->getQuery() + // ->getResult() + // ; + // } + + // public function findOneBySomeField($value): ?Vote + // { + // return $this->createQueryBuilder('v') + // ->andWhere('v.exampleField = :val') + // ->setParameter('val', $value) + // ->getQuery() + // ->getOneOrNullResult() + // ; + // } +} diff --git a/src/Service/Poll/PollService.php b/src/Service/Poll/PollService.php new file mode 100644 index 0000000..33cc4ff --- /dev/null +++ b/src/Service/Poll/PollService.php @@ -0,0 +1,79 @@ +pollRepository->findOneActive(); + } + + public function checkIfPollIsActive(): bool + { + return null !== $this->pollRepository->findOneActive(); + } + + public function checkIfPollHasVotes(Poll $poll): bool + { + return $poll->getVotes()->count() > 0; + } + + public function checkIfPollIsExpired(Poll $poll): bool + { + return $poll->getEndAt() < new \DateTimeImmutable('now', new \DateTimeZone('UTC')); + } + + /** + * Create a new Poll instance. + */ + public function createPoll(): Poll + { + $poll = new Poll(); + + $poll + ->setStartAt(new \DateTimeImmutable('now', new \DateTimeZone('UTC'))) + ->setEndAt(new \DateTimeImmutable('+2 minutes', new \DateTimeZone('UTC'))) + ->setShortCode($this->generateShortCode()) + ; + + return $poll; + } + + /** + * Persist a Poll instance. + */ + public function persistPoll(Poll $poll): Poll + { + $this->entityManager->persist($poll); + $this->entityManager->flush(); + + return $poll; + } + + public function removePoll(Poll $poll): void + { + $this->entityManager->remove($poll); + $this->entityManager->flush(); + } + + private function generateShortCode(): string + { + $prefix = base_convert(date('Ymd'), 10, 36); + $suffix = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyz'), 0, 4); + + return $prefix.$suffix; + } +} diff --git a/src/Service/User/UserService.php b/src/Service/User/UserService.php new file mode 100644 index 0000000..7086375 --- /dev/null +++ b/src/Service/User/UserService.php @@ -0,0 +1,43 @@ +userRepository->findOneBy(['username' => $username]); + if ($existingUser) { + throw new \Exception('User already exists'); + } + + try { + $this->entityManager->beginTransaction(); + $user = new User(); + $user->setUsername($username); + $user->setPassword($this->passwordEncoder->hashPassword($user, $password)); + + $this->entityManager->persist($user); + $this->entityManager->flush(); + $this->entityManager->commit(); + } catch (\Exception $e) { + throw new \Exception('Error creating user'); + } + + return $user; + } +} diff --git a/src/Service/Visitor/VisitorService.php b/src/Service/Visitor/VisitorService.php new file mode 100644 index 0000000..c4c1f94 --- /dev/null +++ b/src/Service/Visitor/VisitorService.php @@ -0,0 +1,54 @@ +entityManager->persist($vote); + $this->entityManager->flush(); + } + + public function createVote(Poll $poll, string $voterId): Vote + { + $vote = new Vote(); + $vote->setVoterId($voterId); + $vote->setPoll($poll); + $vote->setCreatedAt(new \DateTimeImmutable()); + + return $vote; + } + + public function checkIfVisitorHasVoted(string $voterId, Poll $poll): bool + { + return $poll->getVotes()->exists(function ($key, $vote) use ($voterId) { + return $vote->getVoterId() === $voterId; + }); + } + + public function getClientIdFromRequest(Request $request): string + { + $ip = $request->getClientIp(); + $ip = $ip ?: random_bytes(3); + $ipEncoded = base_convert($ip, 10, 36); + + $userAgent = $request->headers->get('User-Agent'); + $userAgent = $userAgent ?: 'unknown'; + $userAgentEncoded = base_convert($userAgent, 10, 36); + + return $ipEncoded.$userAgentEncoded; + } +} diff --git a/symfony.lock b/symfony.lock index 8ca246f..e28f3bc 100644 --- a/symfony.lock +++ b/symfony.lock @@ -1,4 +1,60 @@ { + "doctrine/doctrine-bundle": { + "version": "2.13", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "2.13", + "ref": "8d96c0b51591ffc26794d865ba3ee7d193438a83" + }, + "files": [ + "config/packages/doctrine.yaml", + "src/Entity/.gitignore", + "src/Repository/.gitignore" + ] + }, + "doctrine/doctrine-migrations-bundle": { + "version": "3.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.1", + "ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33" + }, + "files": [ + "config/packages/doctrine_migrations.yaml", + "migrations/.gitignore" + ] + }, + "phpunit/phpunit": { + "version": "9.6", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "9.6", + "ref": "7364a21d87e658eb363c5020c072ecfdc12e2326" + }, + "files": [ + ".env.test", + "phpunit.xml.dist", + "tests/bootstrap.php" + ] + }, + "symfony/asset-mapper": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.4", + "ref": "5ad1308aa756d58f999ffbe1540d1189f5d7d14a" + }, + "files": [ + "assets/app.js", + "assets/styles/app.css", + "config/packages/asset_mapper.yaml", + "importmap.php" + ] + }, "symfony/console": { "version": "7.2", "recipe": { @@ -11,6 +67,18 @@ "bin/console" ] }, + "symfony/debug-bundle": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.3", + "ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b" + }, + "files": [ + "config/packages/debug.yaml" + ] + }, "symfony/flex": { "version": "2.4", "recipe": { @@ -24,6 +92,18 @@ ".env.dev" ] }, + "symfony/form": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "7.2", + "ref": "7d86a6723f4a623f59e2bf966b6aad2fc461d36b" + }, + "files": [ + "config/packages/csrf.yaml" + ] + }, "symfony/framework-bundle": { "version": "7.2", "recipe": { @@ -43,6 +123,78 @@ "src/Kernel.php" ] }, + "symfony/mailer": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "4.3", + "ref": "09051cfde49476e3c12cd3a0e44289ace1c75a4f" + }, + "files": [ + "config/packages/mailer.yaml" + ] + }, + "symfony/maker-bundle": { + "version": "1.61", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.0", + "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" + } + }, + "symfony/messenger": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.0", + "ref": "ba1ac4e919baba5644d31b57a3284d6ba12d52ee" + }, + "files": [ + "config/packages/messenger.yaml" + ] + }, + "symfony/monolog-bundle": { + "version": "3.10", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.7", + "ref": "aff23899c4440dd995907613c1dd709b6f59503f" + }, + "files": [ + "config/packages/monolog.yaml" + ] + }, + "symfony/notifier": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.0", + "ref": "178877daf79d2dbd62129dd03612cb1a2cb407cc" + }, + "files": [ + "config/packages/notifier.yaml" + ] + }, + "symfony/phpunit-bridge": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.3", + "ref": "a411a0480041243d97382cac7984f7dce7813c08" + }, + "files": [ + ".env.test", + "bin/phpunit", + "phpunit.xml.dist", + "tests/bootstrap.php" + ] + }, "symfony/routing": { "version": "7.2", "recipe": { @@ -55,5 +207,75 @@ "config/packages/routing.yaml", "config/routes.yaml" ] + }, + "symfony/security-bundle": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.4", + "ref": "2ae08430db28c8eb4476605894296c82a642028f" + }, + "files": [ + "config/packages/security.yaml", + "config/routes/security.yaml" + ] + }, + "symfony/translation": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.3", + "ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b" + }, + "files": [ + "config/packages/translation.yaml", + "translations/.gitignore" + ] + }, + "symfony/twig-bundle": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.4", + "ref": "cab5fd2a13a45c266d45a7d9337e28dee6272877" + }, + "files": [ + "config/packages/twig.yaml", + "templates/base.html.twig" + ] + }, + "symfony/validator": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "7.0", + "ref": "8c1c4e28d26a124b0bb273f537ca8ce443472bfd" + }, + "files": [ + "config/packages/validator.yaml" + ] + }, + "symfony/web-profiler-bundle": { + "version": "7.2", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "6.1", + "ref": "e42b3f0177df239add25373083a564e5ead4e13a" + }, + "files": [ + "config/packages/web_profiler.yaml", + "config/routes/web_profiler.yaml" + ] + }, + "symfonycasts/tailwind-bundle": { + "version": "v0.6.1" + }, + "twig/extra-bundle": { + "version": "v3.17.0" } } diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..e8dd7d7 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./assets/**/*.js", "./templates/**/*.html.twig"], + theme: { + extend: {}, + }, + plugins: [require("daisyui")], + daisyui: { + themes: ["night"], + }, +}; diff --git a/templates/admin/_results.html.twig b/templates/admin/_results.html.twig new file mode 100644 index 0000000..2ace241 --- /dev/null +++ b/templates/admin/_results.html.twig @@ -0,0 +1,31 @@ +
+ {% for i in 1..5 %} + {% set question = attribute(poll, 'question' ~ i) %} + {% if question %} + {% set voteCount = poll.getVotesForChoice(i) %} +
+
+ {{ i }} + {{ question }} + {{ voteCount }} votes +
+ +
+ {% if poll.totalVotes > 0 %} + {{ ((voteCount / poll.totalVotes) * 100)|round(1) }}% + {% else %} + 0% + {% endif %} +
+
+ {% endif %} + {% endfor %} + +
+ Total votes: {{ poll.totalVotes }} +
+
diff --git a/templates/admin/create.html.twig b/templates/admin/create.html.twig new file mode 100644 index 0000000..dcb923d --- /dev/null +++ b/templates/admin/create.html.twig @@ -0,0 +1,174 @@ +{% extends 'base.html.twig' %} + +{% block title %}{% if app.request.attributes.get('_route') == 'app_admin_edit' %}Edit Poll{% else %}New Poll{% endif %} - OpenStreamPoll{% endblock %} + +{% block body %} + {% set question1_id = form.question1.vars.id %} + {% set question2_id = form.question2.vars.id %} + +
+
+
+
+

+ {% if app.request.attributes.get('_route') == 'app_admin_edit' %} + Edit Poll + {% else %} + New Poll + {% endif %} +

+ + {{ form_start(form, {'attr': {'class': 'space-y-6', 'x-data': '{ + canSubmit: false, + init() { + this.$nextTick(() => { + this.checkSubmission(); + }); + }, + checkSubmission() { + const q1 = document.getElementById("' ~ question1_id ~ '"); + const q2 = document.getElementById("' ~ question2_id ~ '"); + + if (q1 && q2) { + const q1Value = q1.value.trim(); + const q2Value = q2.value.trim(); + this.canSubmit = q1Value.length > 0 && q2Value.length > 0; + } else { + this.canSubmit = false; + } + }, + clearOption(questionId) { + const element = document.getElementById(questionId); + if (element) { + element.value = ""; + element.dispatchEvent(new Event("input", { bubbles: true })); + this.checkSubmission(); + } + } + }'}}) }} +
+ {# Section question principale et description #} +
+
+
+ {{ form_label(form.title, 'Question', { + 'label_attr': { + 'class': 'label' + } + }) }} + {{ form_widget(form.title, { + 'attr': { + 'class': 'textarea textarea-bordered w-full', + 'placeholder': 'Enter your question here...', + 'rows': '2' + } + }) }} + {{ form_errors(form.title) }} +
+ +
+ {{ form_label(form.description, 'Additional Information (optional)', { + 'label_attr': { + 'class': 'label' + } + }) }} + {{ form_widget(form.description, { + 'attr': { + 'class': 'textarea textarea-bordered w-full', + 'rows': '3', + 'placeholder': 'Add any additional context or information...' + } + }) }} + {{ form_errors(form.description) }} +
+
+
+ + {# Section réponses possibles #} +
+
+

+ Answer Options + (Options 1 and 2 required) +

+ + {% for i in 1..5 %} +
+
+ {{ form_widget(attribute(form, 'question' ~ i), { + 'attr': { + 'class': 'input input-bordered w-full', + 'placeholder': 'Option ' ~ i ~ (i <= 2 ? ' (required)' : ''), + '@input.debounce.250ms': 'checkSubmission()', + 'required': i <= 2 ? 'required' : false, + 'id': attribute(form, 'question' ~ i).vars.id + } + }) }} + {% if i > 2 %} + + {% endif %} + {{ form_errors(attribute(form, 'question' ~ i)) }} +
+
+ {% endfor %} +
+
+ + {# Section paramètres #} +
+
+

Settings

+ {{ form_widget(form.startAt, {'attr': {'class': 'hidden'}}) }} + {{ form_widget(form.endAt, {'attr': {'class': 'hidden'}}) }} + +
+ {{ form_label(form.duration, 'Poll Duration', { + 'label_attr': { + 'class': 'label' + } + }) }} +
+ {{ form_widget(form.duration, { + 'attr': { + 'class': 'input input-bordered w-full pl-3 pr-10 py-2' + } + }) }} +
+ + + +
+
+

Choose the duration of your poll (1-10 minutes)

+
+
+
+
+ +
+ + Cancel + + +
+ {{ form_end(form) }} +
+
+
+
+{% endblock %} diff --git a/templates/admin/index.html.twig b/templates/admin/index.html.twig new file mode 100644 index 0000000..e0d93f9 --- /dev/null +++ b/templates/admin/index.html.twig @@ -0,0 +1,261 @@ +{% extends 'base.html.twig' %} + +{% block title %}Administration - OpenStreamPoll{% endblock %} + +{% block body %} +
+
+
+
+ +
+

Polls Management

+ +
+ + + +
+
+ + +
+ {% for poll in polls %} +
+
+
+

{{ poll.title }}

+ +
+ +

{{ poll.description|default('No description') }}

+ +
+ {% if "now"|date('U') >= poll.startAt|date('U') and "now"|date('U') <= poll.endAt|date('U') %} +
Open
+ {% else %} +
Closed
+ {% endif %} + {% if poll.totalVotes > 0 %} +
{{ poll.totalVotes }} votes
+ {% endif %} +
+ +
+ Time left: + +
+
+
+ {% endfor %} +
+ + + +
+
+
+ + + +
+ + {% for poll in polls %} + + + + {% endfor %} + + +{% endblock %} diff --git a/templates/admin/show.html.twig b/templates/admin/show.html.twig new file mode 100644 index 0000000..35b74b2 --- /dev/null +++ b/templates/admin/show.html.twig @@ -0,0 +1,160 @@ +{% extends 'base.html.twig' %} + +{% block title %}{{ poll.title }} - OpenStreamPoll{% endblock %} + +{% block body %} +
+
+
+
+
+
+

{{ poll.title }}

+
+ +
+
+ +
+ + + Back to list + + {% if poll.totalVotes == 0 %} + + Edit + + {% endif %} +
+ + +
+
+
+ +
+
+

Information

+
+
+
Status
+
+ {% if "now"|date('U') >= poll.startAt|date('U') and "now"|date('U') <= poll.endAt|date('U') %} +
Open
+ {% else %} +
Closed
+ {% endif %} +
+ +
+
Time Left
+
+ + + + Finished + +
+
+ + + + +
+
+

Description

+

{{ poll.description|default('No description') }}

+
+
+ +
+
+

Answer Options

+
+ {% for i in 1..5 %} + {% set question = attribute(poll, 'question' ~ i) %} + {% if question %} +
+ {{ i }} +

{{ question }}

+
+ {% endif %} + {% endfor %} +
+
+
+ +
+
+

Results

+
+
+ {% for i in 1..5 %} +
+ {% endfor %} +
+
+
+
+ + + + + + +{% endblock %} diff --git a/templates/base.html.twig b/templates/base.html.twig new file mode 100644 index 0000000..e1de5d8 --- /dev/null +++ b/templates/base.html.twig @@ -0,0 +1,19 @@ + + + + + {% block title %}Welcome!{% endblock %} + + + {% block stylesheets %} + {% endblock %} + + {% block javascripts %} + {% block importmap %}{{ importmap('app') }}{% endblock %} + {% endblock %} + + + {% include 'components/_toast.html.twig' %} + {% block body %}{% endblock %} + + diff --git a/templates/base_obs.html.twig b/templates/base_obs.html.twig new file mode 100644 index 0000000..573a51f --- /dev/null +++ b/templates/base_obs.html.twig @@ -0,0 +1,15 @@ + + + + + {% block title %}OBS Stream Poll{% endblock %} + + + {% block javascripts %} + {% block importmap %}{{ importmap('app_obs') }}{% endblock %} + {% endblock %} + + + {% block body %}{% endblock %} + + diff --git a/templates/components/_toast.html.twig b/templates/components/_toast.html.twig new file mode 100644 index 0000000..0b72ba5 --- /dev/null +++ b/templates/components/_toast.html.twig @@ -0,0 +1,57 @@ +
+ {% for type, messages in app.flashes %} + {% for message in messages %} +
+ {% endfor %} + {% endfor %} + + +
diff --git a/templates/home/index.html.twig b/templates/home/index.html.twig new file mode 100644 index 0000000..87f260d --- /dev/null +++ b/templates/home/index.html.twig @@ -0,0 +1,345 @@ +{% extends 'base.html.twig' %} + +{% block title %}OpenStreamPoll - Open Source Live Polling Platform{% endblock %} + +{% block body %} + +
+ +
+ +
+ + +
+
+
+
+
+
+ + +
+ +
+
+ +
+
+ +
+ OpenStreamPoll Interface + +
+
+
+
+ + +
+ +
+
+ + + +
+ Product of the Day in a Parallel World +
+ +

OpenStreamPoll

+ +

Create instant polls for your live streams and get real-time feedback from your audience. Simple, fast, and effective.

+ +
+ + + + + + View on GitHub + +
+
+
+ + + +
+ + +
+
+
+

Powerful Features for Streamers

+ +
+ +
+
+
+ + + +
+

Flexible Poll Creation

+

Create polls with up to 5 options, perfect for engaging your audience with multiple choices.

+
+
+ + +
+
+
+ + + +
+

Custom Duration

+

Set poll duration from 1 to 10 minutes to match your stream's pace.

+
+
+ + +
+
+
+ + + +
+

Live Results

+

Watch vote results update in real-time on your dashboard.

+
+
+ + +
+
+
+ + + +
+

Easy Sharing

+

Share unique poll URLs with your chat for instant audience participation.

+
+
+ + +
+
+
+ + + +
+

Secure Voting

+

IP and browser-based protection against duplicate votes.

+
+
+ + +
+
+
+ + + +
+

Stream Integration

+

Easy integration with OBS using dedicated overlay URLs.

+
+
+
+
+
+ + +
+ +
+
+
+
+ +
+

Live Demo

+ +
+
+

What's your favorite programming language?

+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+ +
+
+
+
+ +
+
+

100% Open Source

+

Deploy your own instance in minutes

+
+ +
+
+
+

Zero-Config Deployment

+
    +
  • + + + + Just need a VPS with SSH access +
  • +
  • + + + + Docker-ready configuration included +
  • +
  • + + + + Point your domain and you're ready! +
  • +
+ +
+
+ +
+
+
+
git clone https://github.com/yoanbernabeu/OpenStreamPoll.git
+
cd OpenStreamPoll
+
make deploy
+
🚀 Your instance is ready!
+
+
+
+
+
+
+ + +
+ +
+
+
+ +
+

Ready to Create Your First Poll?

+

It's free, open source, and takes just minutes to set up your own instance.

+
+ Get Started on GitHub + +
+
+
+{% endblock %} diff --git a/templates/obs/_results.html.twig b/templates/obs/_results.html.twig new file mode 100644 index 0000000..8226767 --- /dev/null +++ b/templates/obs/_results.html.twig @@ -0,0 +1,41 @@ +{% if poll %} +
+
+
{{ poll.title }}
+
+ 00:00 +
+
+ +
+ {% for i in 1..5 %} + {% set question = attribute(poll, 'question' ~ i) %} + {% if question %} + {% set voteCount = poll.getVotesForChoice(i) %} +
+
+ {{ question }} + {{ voteCount }} +
+ +
+ {% if poll.totalVotes > 0 %} + {{ ((voteCount / poll.totalVotes) * 100)|round(1) }}% + {% else %} + 0% + {% endif %} +
+
+ {% endif %} + {% endfor %} +
+ +
+ Total votes: {{ poll.totalVotes }} +
+
+{% endif %} diff --git a/templates/obs/index.html.twig b/templates/obs/index.html.twig new file mode 100644 index 0000000..8a3fa09 --- /dev/null +++ b/templates/obs/index.html.twig @@ -0,0 +1,6 @@ +{% extends 'base_obs.html.twig' %} + +{% block body %} +
+
+{% endblock %} diff --git a/templates/poll/error.html.twig b/templates/poll/error.html.twig new file mode 100644 index 0000000..d86ac37 --- /dev/null +++ b/templates/poll/error.html.twig @@ -0,0 +1,23 @@ +{% extends 'base.html.twig' %} + +{% block title %}Poll Not Available{% endblock %} + +{% block body %} +
+
+
+
+
+ + + +
+ +

Poll Not Available

+

{{ message }}

+ +
+
+
+
+{% endblock %} diff --git a/templates/poll/show.html.twig b/templates/poll/show.html.twig new file mode 100644 index 0000000..c8b0009 --- /dev/null +++ b/templates/poll/show.html.twig @@ -0,0 +1,112 @@ +{% extends 'base.html.twig' %} + +{% block title %}{{ poll.title }}{% endblock %} + +{% block body %} +
+
+ {# Hero section avec titre et description #} +
+
+

{{ poll.title }}

+ {% if poll.description %} +

{{ poll.description }}

+ {% endif %} +
+
+ + {# Timer section #} +
+
+
+
+
+
Time remaining
+
+ 00:00 +
+
Poll ended
+
+
+
+
+
+ + {# Questions section #} +
+
+

Make your choice

+ + {{ form_start(form, {'attr': {'class': 'space-y-4', 'x-data': '{ selected: null }'}}) }} +
+ {% for child in form.choice %} + + {% endfor %} +
+ +
+ +
+ {{ form_end(form) }} +
+
+ + {# Footer info #} +
+

Visitor ID: {{ voterId }}

+
+
+
+ + +{% endblock %} diff --git a/templates/poll/success.html.twig b/templates/poll/success.html.twig new file mode 100644 index 0000000..4813385 --- /dev/null +++ b/templates/poll/success.html.twig @@ -0,0 +1,40 @@ +{% extends 'base.html.twig' %} + +{% block title %}Vote Submitted - {{ title }}{% endblock %} + +{% block body %} +
+
+ +
+
+
+
+ + + +
+ +

Thank You!

+

Your vote has been successfully recorded.

+
+
+
+
+ + +{% endblock %} diff --git a/templates/security/login.html.twig b/templates/security/login.html.twig new file mode 100644 index 0000000..670fc74 --- /dev/null +++ b/templates/security/login.html.twig @@ -0,0 +1,51 @@ +{% extends 'base.html.twig' %} + +{% block title %}Log in!{% endblock %} + +{% block body %} +
+
+
+
+

Sign in

+ +
+ {% if error %} +
+ {{ error.messageKey|trans(error.messageData, 'security') }} +
+ {% endif %} + + {% if app.user %} +
+ You are logged in as {{ app.user.userIdentifier }}, Logout +
+ {% endif %} + +
+ + +
+ +
+ + +
+ + + +
+ +
+
+
+
+
+
+{% endblock %} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..469dcce --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,11 @@ +bootEnv(dirname(__DIR__).'/.env'); +} diff --git a/translations/.gitignore b/translations/.gitignore new file mode 100644 index 0000000..e69de29