Initial commit
Change-Id: I57962228cb1045dc5c596d50d2ea1f055f4b4e26
diff --git a/.env b/.env
new file mode 100644
index 0000000..2c6c8a4
--- /dev/null
+++ b/.env
@@ -0,0 +1,29 @@
+# In all environments, the following files are loaded if they exist,
+# the latter taking precedence over the former:
+#
+# * .env contains default values for the environment variables needed by the app
+# * .env.local uncommitted file with local overrides
+# * .env.$APP_ENV committed environment-specific defaults
+# * .env.$APP_ENV.local uncommitted environment-specific overrides
+#
+# Real environment variables win over .env files.
+#
+# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
+# https://symfony.com/doc/current/configuration/secrets.html
+#
+# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
+# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
+
+###> symfony/framework-bundle ###
+APP_ENV=dev
+APP_SECRET=8d81455a0174e4f5cd172573e04c6677
+###< 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://root:%23fireDb91@127.0.0.1:3306/leaf_ota?serverVersion=8&charset=utf8mb4"
+# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=15&charset=utf8"
+###< doctrine/doctrine-bundle ###
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a67f91e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+
+###> symfony/framework-bundle ###
+/.env.local
+/.env.local.php
+/.env.*.local
+/config/secrets/prod/prod.decrypt.private.php
+/public/bundles/
+/var/
+/vendor/
+###< symfony/framework-bundle ###
diff --git a/bin/console b/bin/console
new file mode 100644
index 0000000..c933dc5
--- /dev/null
+++ b/bin/console
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+<?php
+
+use App\Kernel;
+use Symfony\Bundle\FrameworkBundle\Console\Application;
+
+if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
+ throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
+}
+
+require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
+
+return function (array $context) {
+ $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
+
+ return new Application($kernel);
+};
diff --git a/components/footer.html.twig b/components/footer.html.twig
new file mode 100644
index 0000000..9581e9f
--- /dev/null
+++ b/components/footer.html.twig
@@ -0,0 +1,3 @@
+<footer>
+ © 2022-2023 The LeafOS Project
+</footer>
\ No newline at end of file
diff --git a/components/navbar.html.twig b/components/navbar.html.twig
new file mode 100644
index 0000000..940364d
--- /dev/null
+++ b/components/navbar.html.twig
@@ -0,0 +1,40 @@
+{% if showSidenav %}
+ <input type="checkbox" id="hamburger-sidenav" class="hamburger-sidenav" />
+{% endif %}
+<nav class="navbar">
+ {% if showSidenav %}
+ <label for="hamburger-sidenav" class="label-sidenav">
+ <span class="icon-bar top-bar"></span>
+ <span class="icon-bar middle-bar"></span>
+ <span class="icon-bar bottom-bar"></span>
+ </label>
+ {% endif %}
+ <input type="checkbox" id="hamburger" class="hamburger" />
+ <label for="hamburger">
+ <span class="icon-bar top-bar"></span>
+ <span class="icon-bar middle-bar"></span>
+ <span class="icon-bar bottom-bar"></span>
+ </label>
+
+ <ul>
+ <li class="nav-logo">
+ <a href="{{ path('leaf_home') }}" class="logo">
+ <svg id="vector" xmlns="http://www.w3.org/2000/svg" height="30px" viewBox="0 0 140.2 76.8">
+ <path fill="#90ee90" d="M28.88 31.84C35.54 40 45.19 48.78 51 58.5c5.14 10.73 14.22 25.34 -3.33 13.65 -13.43 -6.58 -29.21 -10 -38.22 -22.22C0.3 42.26 -2.77 -3.82 2.74 0.25 24.46 11 48 9.35 60.23 23.48a40.75 40.75 0 0 1 8.15 14.85c2.81 7.88 5.2 -7.21 7.53 -9.22C79.66 22.69 85.58 18 92.06 14.8c14.06 -5.15 29.14 -7 42.88 -13.31 2.26 -1 4.25 -1.55 4.8 -0.43 1.28 18.32 0.77 39.76 -12.86 53.37C114.91 65.51 98 67.91 84.12 76.7c-3.83 1 -0.62 -5.45 0.17 -8 5.56 -16 17.39 -24.86 29.34 -37.27C85.69 39.75 77.73 81 73.41 67.29c-1.25 -2 -0.53 -7.12 -3.5 -7.3 -3.17 0.58 -2.27 13.27 -8.27 7.83C53.88 54 43.86 37.9 28.88 31.84Z" id="path_0"></path>
+ </svg>
+ </a>
+ </li>
+ <li>
+ <a href="{{ path('leaf_about') }}" class="{{ route == 'leaf_about' ? 'active' : '' }} nav-link">About</a>
+ </li>
+ <li>
+ <a href="{{ path('leaf_gallery') }}" class="{{ route == 'leaf_gallery' ? 'active' : '' }} nav-link">Gallery</a>
+ </li>
+ <li>
+ <a href="{{ path('leaf_wiki') }}" class="{{ route == 'leaf_wiki' ? 'active' : '' }} nav-link">Wiki</a>
+ </li>
+ <li>
+ <a href="{{ path('leaf_community') }}" class="{{ route == 'leaf_community' ? 'active' : '' }} nav-link">Community</a>
+ </li>
+ </ul>
+</nav>
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..3307015
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,76 @@
+{
+ "type": "project",
+ "license": "proprietary",
+ "minimum-stability": "stable",
+ "prefer-stable": true,
+ "require": {
+ "php": ">=8.1",
+ "ext-ctype": "*",
+ "ext-iconv": "*",
+ "doctrine/doctrine-bundle": "^2.9",
+ "doctrine/doctrine-migrations-bundle": "^3.2",
+ "doctrine/orm": "^2.14",
+ "symfony/asset": "6.2.*",
+ "symfony/console": "6.2.*",
+ "symfony/dotenv": "6.2.*",
+ "symfony/flex": "^2",
+ "symfony/framework-bundle": "6.2.*",
+ "symfony/runtime": "6.2.*",
+ "symfony/twig-bundle": "6.2.*",
+ "symfony/yaml": "6.2.*",
+ "twig/extra-bundle": "^2.12|^3.0",
+ "twig/twig": "^2.12|^3.0"
+ },
+ "config": {
+ "allow-plugins": {
+ "php-http/discovery": true,
+ "symfony/flex": true,
+ "symfony/runtime": true
+ },
+ "sort-packages": true
+ },
+ "autoload": {
+ "psr-4": {
+ "App\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "App\\Tests\\": "tests/"
+ }
+ },
+ "replace": {
+ "symfony/polyfill-ctype": "*",
+ "symfony/polyfill-iconv": "*",
+ "symfony/polyfill-php72": "*",
+ "symfony/polyfill-php73": "*",
+ "symfony/polyfill-php74": "*",
+ "symfony/polyfill-php80": "*",
+ "symfony/polyfill-php81": "*"
+ },
+ "scripts": {
+ "auto-scripts": {
+ "cache:clear": "symfony-cmd",
+ "assets:install %PUBLIC_DIR%": "symfony-cmd"
+ },
+ "post-install-cmd": [
+ "@auto-scripts"
+ ],
+ "post-update-cmd": [
+ "@auto-scripts"
+ ]
+ },
+ "conflict": {
+ "symfony/symfony": "*"
+ },
+ "extra": {
+ "symfony": {
+ "allow-contrib": false,
+ "require": "6.2.*"
+ }
+ },
+ "require-dev": {
+ "symfony/maker-bundle": "^1.48",
+ "symfony/var-dumper": "6.2.*"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..3933a47
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,4541 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "8df65add26c29885f3a2bc7b4d4c7c1b",
+ "packages": [
+ {
+ "name": "doctrine/cache",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/cache.git",
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~7.1 || ^8.0"
+ },
+ "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": {
+ "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine 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": [
+ "abstraction",
+ "apcu",
+ "cache",
+ "caching",
+ "couchdb",
+ "memcached",
+ "php",
+ "redis",
+ "xcache"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/cache/issues",
+ "source": "https://github.com/doctrine/cache/tree/2.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-20T20:07:39+00:00"
+ },
+ {
+ "name": "doctrine/collections",
+ "version": "2.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/collections.git",
+ "reference": "db8cda536a034337f7dd63febecc713d4957f9ee"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/db8cda536a034337f7dd63febecc713d4957f9ee",
+ "reference": "db8cda536a034337f7dd63febecc713d4957f9ee",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^10.0",
+ "ext-json": "*",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^9.5",
+ "vimeo/psalm": "^4.22"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Collections\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.",
+ "homepage": "https://www.doctrine-project.org/projects/collections.html",
+ "keywords": [
+ "array",
+ "collections",
+ "iterators",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/collections/issues",
+ "source": "https://github.com/doctrine/collections/tree/2.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-27T23:41:38+00:00"
+ },
+ {
+ "name": "doctrine/common",
+ "version": "3.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/common.git",
+ "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/common/zipball/8b5e5650391f851ed58910b3e3d48a71062eeced",
+ "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/persistence": "^2.0 || ^3.0",
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9.0 || ^10.0",
+ "doctrine/collections": "^1",
+ "phpstan/phpstan": "^1.4.1",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0",
+ "squizlabs/php_codesniffer": "^3.0",
+ "symfony/phpunit-bridge": "^6.1",
+ "vimeo/psalm": "^4.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "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": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.",
+ "homepage": "https://www.doctrine-project.org/projects/common.html",
+ "keywords": [
+ "common",
+ "doctrine",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/common/issues",
+ "source": "https://github.com/doctrine/common/tree/3.4.3"
+ },
+ "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%2Fcommon",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-10-09T11:47:59+00:00"
+ },
+ {
+ "name": "doctrine/dbal",
+ "version": "3.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/dbal.git",
+ "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/57815c7bbcda3cd18871d253c1dd8cbe56f8526e",
+ "reference": "57815c7bbcda3cd18871d253c1dd8cbe56f8526e",
+ "shasum": ""
+ },
+ "require": {
+ "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"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "11.1.0",
+ "fig/log-test": "^1",
+ "jetbrains/phpstorm-stubs": "2022.3",
+ "phpstan/phpstan": "1.10.3",
+ "phpstan/phpstan-strict-rules": "^1.5",
+ "phpunit/phpunit": "9.6.4",
+ "psalm/plugin-phpunit": "0.18.4",
+ "squizlabs/php_codesniffer": "3.7.2",
+ "symfony/cache": "^5.4|^6.0",
+ "symfony/console": "^4.4|^5.4|^6.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": {
+ "Doctrine\\DBAL\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ }
+ ],
+ "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": [
+ "abstraction",
+ "database",
+ "db2",
+ "dbal",
+ "mariadb",
+ "mssql",
+ "mysql",
+ "oci8",
+ "oracle",
+ "pdo",
+ "pgsql",
+ "postgresql",
+ "queryobject",
+ "sasql",
+ "sql",
+ "sqlite",
+ "sqlserver",
+ "sqlsrv"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/dbal/issues",
+ "source": "https://github.com/doctrine/dbal/tree/3.6.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-02T19:26:24+00:00"
+ },
+ {
+ "name": "doctrine/deprecations",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5|^8.5|^9.5",
+ "psr/log": "^1|^2|^3"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
+ },
+ "time": "2022-05-02T15:47:09+00:00"
+ },
+ {
+ "name": "doctrine/doctrine-bundle",
+ "version": "2.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/DoctrineBundle.git",
+ "reference": "9819c00c2eea750b99902f244309b824911b72b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/9819c00c2eea750b99902f244309b824911b72b2",
+ "reference": "9819c00c2eea750b99902f244309b824911b72b2",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/cache": "^1.11 || ^2.0",
+ "doctrine/dbal": "^3.6.0",
+ "doctrine/persistence": "^2.2 || ^3",
+ "doctrine/sql-formatter": "^1.0.1",
+ "php": "^7.4 || ^8.0",
+ "symfony/cache": "^5.4 || ^6.0",
+ "symfony/config": "^5.4 || ^6.0",
+ "symfony/console": "^5.4 || ^6.0",
+ "symfony/dependency-injection": "^5.4 || ^6.0",
+ "symfony/deprecation-contracts": "^2.1 || ^3",
+ "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7",
+ "symfony/framework-bundle": "^5.4 || ^6.0",
+ "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3"
+ },
+ "conflict": {
+ "doctrine/annotations": ">=3.0",
+ "doctrine/orm": "<2.11 || >=3.0",
+ "twig/twig": "<1.34 || >=2.0 <2.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1 || ^2",
+ "doctrine/coding-standard": "^9.0",
+ "doctrine/deprecations": "^1.0",
+ "doctrine/orm": "^2.11 || ^3.0",
+ "friendsofphp/proxy-manager-lts": "^1.0",
+ "phpunit/phpunit": "^9.5.26 || ^10.0",
+ "psalm/plugin-phpunit": "^0.18.4",
+ "psalm/plugin-symfony": "^4",
+ "psr/log": "^1.1.4 || ^2.0 || ^3.0",
+ "symfony/phpunit-bridge": "^6.1",
+ "symfony/property-info": "^5.4 || ^6.0",
+ "symfony/proxy-manager-bridge": "^5.4 || ^6.0",
+ "symfony/security-bundle": "^5.4 || ^6.0",
+ "symfony/twig-bridge": "^5.4 || ^6.0",
+ "symfony/validator": "^5.4 || ^6.0",
+ "symfony/web-profiler-bundle": "^5.4 || ^6.0",
+ "symfony/yaml": "^5.4 || ^6.0",
+ "twig/twig": "^1.34 || ^2.12 || ^3.0",
+ "vimeo/psalm": "^4.30"
+ },
+ "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": {
+ "Doctrine\\Bundle\\DoctrineBundle\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "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": "Symfony DoctrineBundle",
+ "homepage": "https://www.doctrine-project.org",
+ "keywords": [
+ "database",
+ "dbal",
+ "orm",
+ "persistence"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/DoctrineBundle/issues",
+ "source": "https://github.com/doctrine/DoctrineBundle/tree/2.9.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-bundle",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-23T20:02:57+00:00"
+ },
+ {
+ "name": "doctrine/doctrine-migrations-bundle",
+ "version": "3.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git",
+ "reference": "3393f411ba25ade21969c33f2053220044854d01"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/3393f411ba25ade21969c33f2053220044854d01",
+ "reference": "3393f411ba25ade21969c33f2053220044854d01",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/doctrine-bundle": "~1.0|~2.0",
+ "doctrine/migrations": "^3.2",
+ "php": "^7.2|^8.0",
+ "symfony/framework-bundle": "~3.4|~4.0|~5.0|~6.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^8.0",
+ "doctrine/orm": "^2.6",
+ "doctrine/persistence": "^1.3||^2.0",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-deprecation-rules": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpstan/phpstan-strict-rules": "^0.12",
+ "phpunit/phpunit": "^8.0|^9.0",
+ "vimeo/psalm": "^4.11"
+ },
+ "type": "symfony-bundle",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Bundle\\MigrationsBundle\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "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": "Symfony DoctrineMigrationsBundle",
+ "homepage": "https://www.doctrine-project.org",
+ "keywords": [
+ "dbal",
+ "migrations",
+ "schema"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues",
+ "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.2.2"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-migrations-bundle",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-01T18:08:07+00:00"
+ },
+ {
+ "name": "doctrine/event-manager",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/event-manager.git",
+ "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32",
+ "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "conflict": {
+ "doctrine/common": "<2.9"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.8.8",
+ "phpunit/phpunit": "^9.5",
+ "vimeo/psalm": "^4.28"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ },
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
+ "homepage": "https://www.doctrine-project.org/projects/event-manager.html",
+ "keywords": [
+ "event",
+ "event dispatcher",
+ "event manager",
+ "event system",
+ "events"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/event-manager/issues",
+ "source": "https://github.com/doctrine/event-manager/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-10-12T20:59:15+00:00"
+ },
+ {
+ "name": "doctrine/inflector",
+ "version": "2.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/inflector.git",
+ "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
+ "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.3",
+ "phpunit/phpunit": "^8.5 || ^9.5",
+ "vimeo/psalm": "^4.25"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
+ "homepage": "https://www.doctrine-project.org/projects/inflector.html",
+ "keywords": [
+ "inflection",
+ "inflector",
+ "lowercase",
+ "manipulation",
+ "php",
+ "plural",
+ "singular",
+ "strings",
+ "uppercase",
+ "words"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/inflector/issues",
+ "source": "https://github.com/doctrine/inflector/tree/2.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-10-20T09:10:12+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b",
+ "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^11",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^0.16 || ^1",
+ "phpstan/phpstan": "^1.4",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.30 || ^5.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/1.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-30T00:15:36+00:00"
+ },
+ {
+ "name": "doctrine/lexer",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
+ "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^10",
+ "phpstan/phpstan": "^1.3",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^4.11 || ^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/2.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-14T08:49:07+00:00"
+ },
+ {
+ "name": "doctrine/migrations",
+ "version": "3.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/migrations.git",
+ "reference": "e542ad8bcd606d7a18d0875babb8a6d963c9c059"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/migrations/zipball/e542ad8bcd606d7a18d0875babb8a6d963c9c059",
+ "reference": "e542ad8bcd606d7a18d0875babb8a6d963c9c059",
+ "shasum": ""
+ },
+ "require": {
+ "composer-runtime-api": "^2",
+ "doctrine/dbal": "^3.5.1",
+ "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": "^4.4.16 || ^5.4 || ^6.0",
+ "symfony/stopwatch": "^4.4 || ^5.4 || ^6.0",
+ "symfony/var-exporter": "^6.2"
+ },
+ "conflict": {
+ "doctrine/orm": "<2.12"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "doctrine/orm": "^2.13",
+ "doctrine/persistence": "^2 || ^3",
+ "doctrine/sql-formatter": "^1.0",
+ "ext-pdo_sqlite": "*",
+ "phpstan/phpstan": "^1.5",
+ "phpstan/phpstan-deprecation-rules": "^1",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "phpstan/phpstan-symfony": "^1.1",
+ "phpunit/phpunit": "^9.5.24",
+ "symfony/cache": "^4.4 || ^5.4 || ^6.0",
+ "symfony/process": "^4.4 || ^5.4 || ^6.0",
+ "symfony/yaml": "^4.4 || ^5.4 || ^6.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": {
+ "Doctrine\\Migrations\\": "lib/Doctrine/Migrations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Michael Simonson",
+ "email": "contact@mikesimonson.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": [
+ "database",
+ "dbal",
+ "migrations"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/migrations/issues",
+ "source": "https://github.com/doctrine/migrations/tree/3.6.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fmigrations",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-15T18:49:46+00:00"
+ },
+ {
+ "name": "doctrine/orm",
+ "version": "2.14.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/orm.git",
+ "reference": "de7eee5ed7b1b35c99b118f26f210a8281e6db8e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/orm/zipball/de7eee5ed7b1b35c99b118f26f210a8281e6db8e",
+ "reference": "de7eee5ed7b1b35c99b118f26f210a8281e6db8e",
+ "shasum": ""
+ },
+ "require": {
+ "composer-runtime-api": "^2",
+ "doctrine/cache": "^1.12.1 || ^2.1.1",
+ "doctrine/collections": "^1.5 || ^2.0",
+ "doctrine/common": "^3.0.3",
+ "doctrine/dbal": "^2.13.1 || ^3.2",
+ "doctrine/deprecations": "^0.5.3 || ^1",
+ "doctrine/event-manager": "^1.2 || ^2",
+ "doctrine/inflector": "^1.4 || ^2.0",
+ "doctrine/instantiator": "^1.3",
+ "doctrine/lexer": "^1.2.3 || ^2",
+ "doctrine/persistence": "^2.4 || ^3",
+ "ext-ctype": "*",
+ "php": "^7.1 || ^8.0",
+ "psr/cache": "^1 || ^2 || ^3",
+ "symfony/console": "^4.2 || ^5.0 || ^6.0",
+ "symfony/polyfill-php72": "^1.23",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "conflict": {
+ "doctrine/annotations": "<1.13 || >= 3.0"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.13 || ^2",
+ "doctrine/coding-standard": "^9.0.2 || ^11.0",
+ "phpbench/phpbench": "^0.16.10 || ^1.0",
+ "phpstan/phpstan": "~1.4.10 || 1.9.8",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psr/log": "^1 || ^2 || ^3",
+ "squizlabs/php_codesniffer": "3.7.1",
+ "symfony/cache": "^4.4 || ^5.4 || ^6.0",
+ "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2",
+ "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0",
+ "vimeo/psalm": "4.30.0 || 5.4.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",
+ "symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
+ },
+ "bin": [
+ "bin/doctrine"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\ORM\\": "lib/Doctrine/ORM"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "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/2.14.1"
+ },
+ "time": "2023-01-16T18:36:59+00:00"
+ },
+ {
+ "name": "doctrine/persistence",
+ "version": "3.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/persistence.git",
+ "reference": "8bf8ab15960787f1a49d405f6eb8c787b4841119"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/persistence/zipball/8bf8ab15960787f1a49d405f6eb8c787b4841119",
+ "reference": "8bf8ab15960787f1a49d405f6eb8c787b4841119",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/event-manager": "^1 || ^2",
+ "php": "^7.2 || ^8.0",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0"
+ },
+ "conflict": {
+ "doctrine/common": "<2.10"
+ },
+ "require-dev": {
+ "composer/package-versions-deprecated": "^1.11",
+ "doctrine/coding-standard": "^11",
+ "doctrine/common": "^3.0",
+ "phpstan/phpstan": "1.9.4",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "phpunit/phpunit": "^8.5 || ^9.5",
+ "symfony/cache": "^4.4 || ^5.4 || ^6.0",
+ "vimeo/psalm": "4.30.0 || 5.3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Persistence\\": "src/Persistence"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ },
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
+ }
+ ],
+ "description": "The Doctrine 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": {
+ "issues": "https://github.com/doctrine/persistence/issues",
+ "source": "https://github.com/doctrine/persistence/tree/3.1.4"
+ },
+ "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%2Fpersistence",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-03T11:13:07+00:00"
+ },
+ {
+ "name": "doctrine/sql-formatter",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/sql-formatter.git",
+ "reference": "25a06c7bf4c6b8218f47928654252863ffc890a5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/25a06c7bf4c6b8218f47928654252863ffc890a5",
+ "reference": "25a06c7bf4c6b8218f47928654252863ffc890a5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4"
+ },
+ "bin": [
+ "bin/sql-formatter"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\SqlFormatter\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jeremy Dorn",
+ "email": "jeremy@jeremydorn.com",
+ "homepage": "https://jeremydorn.com/"
+ }
+ ],
+ "description": "a PHP SQL highlighting library",
+ "homepage": "https://github.com/doctrine/sql-formatter/",
+ "keywords": [
+ "highlight",
+ "sql"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/sql-formatter/issues",
+ "source": "https://github.com/doctrine/sql-formatter/tree/1.1.3"
+ },
+ "time": "2022-05-23T21:33: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/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/log",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/3.0.0"
+ },
+ "time": "2021-07-14T16:46:02+00:00"
+ },
+ {
+ "name": "symfony/asset",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/asset.git",
+ "reference": "223df790e684ecc7bc37323c2d1e265129ca02de"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/asset/zipball/223df790e684ecc7bc37323c2d1e265129ca02de",
+ "reference": "223df790e684ecc7bc37323c2d1e265129ca02de",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "conflict": {
+ "symfony/http-foundation": "<5.4"
+ },
+ "require-dev": {
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/http-foundation": ""
+ },
+ "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/v6.2.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": "2023-02-14T08:44:56+00:00"
+ },
+ {
+ "name": "symfony/cache",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/cache.git",
+ "reference": "76babfd82f6bfd8f6cbe851a153b95dd074ffc53"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/cache/zipball/76babfd82f6bfd8f6cbe851a153b95dd074ffc53",
+ "reference": "76babfd82f6bfd8f6cbe851a153b95dd074ffc53",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/cache": "^2.0|^3.0",
+ "psr/log": "^1.1|^2|^3",
+ "symfony/cache-contracts": "^1.1.7|^2|^3",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/var-exporter": "^6.2.7"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.13.1",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/http-kernel": "<5.4",
+ "symfony/var-dumper": "<5.4"
+ },
+ "provide": {
+ "psr/cache-implementation": "2.0|3.0",
+ "psr/simple-cache-implementation": "1.0|2.0|3.0",
+ "symfony/cache-implementation": "1.1|2.0|3.0"
+ },
+ "require-dev": {
+ "cache/integration-tests": "dev-master",
+ "doctrine/dbal": "^2.13.1|^3.0",
+ "predis/predis": "^1.1",
+ "psr/simple-cache": "^1.0|^2.0|^3.0",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/filesystem": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/messenger": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Cache\\": ""
+ },
+ "classmap": [
+ "Traits/ValueWrapper.php"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides extended PSR-6, PSR-16 (and tags) implementations",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "caching",
+ "psr6"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/cache/tree/v6.2.8"
+ },
+ "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-03-30T07:37:32+00:00"
+ },
+ {
+ "name": "symfony/cache-contracts",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/cache-contracts.git",
+ "reference": "eeb71f04b6f7f34ca6d15633df82e014528b1632"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/eeb71f04b6f7f34ca6d15633df82e014528b1632",
+ "reference": "eeb71f04b6f7f34ca6d15633df82e014528b1632",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/cache": "^3.0"
+ },
+ "suggest": {
+ "symfony/cache-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.3-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.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": "2023-03-01T10:32:47+00:00"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "249271da6f545d6579e0663374f8249a80be2893"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/249271da6f545d6579e0663374f8249a80be2893",
+ "reference": "249271da6f545d6579e0663374f8249a80be2893",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/filesystem": "^5.4|^6.0",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/finder": "<5.4"
+ },
+ "require-dev": {
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/messenger": "^5.4|^6.0",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/yaml": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/yaml": "To use the yaml reference dumper"
+ },
+ "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/v6.2.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": "2023-02-14T08:44:56+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/3582d68a64a86ec25240aaa521ec8bc2342b369b",
+ "reference": "3582d68a64a86ec25240aaa521ec8bc2342b369b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/string": "^5.4|^6.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/dotenv": "<5.4",
+ "symfony/event-dispatcher": "<5.4",
+ "symfony/lock": "<5.4",
+ "symfony/process": "<5.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/lock": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command-line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v6.2.8"
+ },
+ "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-03-29T21:42:15+00:00"
+ },
+ {
+ "name": "symfony/dependency-injection",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dependency-injection.git",
+ "reference": "b6195feacceb88fc58a02b69522b569e4c6188ac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b6195feacceb88fc58a02b69522b569e4c6188ac",
+ "reference": "b6195feacceb88fc58a02b69522b569e4c6188ac",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^1.1|^2.0",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/service-contracts": "^1.1.6|^2.0|^3.0",
+ "symfony/var-exporter": "^6.2.7"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2",
+ "symfony/config": "<6.1",
+ "symfony/finder": "<5.4",
+ "symfony/proxy-manager-bridge": "<6.2",
+ "symfony/yaml": "<5.4"
+ },
+ "provide": {
+ "psr/container-implementation": "1.1|2.0",
+ "symfony/service-implementation": "1.1|2.0|3.0"
+ },
+ "require-dev": {
+ "symfony/config": "^6.1",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/config": "",
+ "symfony/expression-language": "For using expressions in service container configuration",
+ "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
+ "symfony/yaml": ""
+ },
+ "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/v6.2.8"
+ },
+ "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-03-30T13:35:57+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
+ "reference": "e2d1534420bd723d0ef5aec58a22c5fe60ce6f5e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.3-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.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": "2023-03-01T10:25:55+00:00"
+ },
+ {
+ "name": "symfony/doctrine-bridge",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/doctrine-bridge.git",
+ "reference": "70e9e36a590699c26c1a0a0c46b0eaa7a6bb019d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/70e9e36a590699c26c1a0a0c46b0eaa7a6bb019d",
+ "reference": "70e9e36a590699c26c1a0a0c46b0eaa7a6bb019d",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/event-manager": "^1.2|^2",
+ "doctrine/persistence": "^2|^3",
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^1.1|^2|^3"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.13.1",
+ "doctrine/lexer": "<1.1",
+ "doctrine/orm": "<2.7.4",
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/cache": "<5.4",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/form": "<5.4.21|>=6,<6.2.7",
+ "symfony/http-kernel": "<6.2",
+ "symfony/messenger": "<5.4",
+ "symfony/property-info": "<5.4",
+ "symfony/security-bundle": "<5.4",
+ "symfony/security-core": "<6.0",
+ "symfony/validator": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.10.4|^2",
+ "doctrine/collections": "^1.0|^2.0",
+ "doctrine/data-fixtures": "^1.1",
+ "doctrine/dbal": "^2.13.1|^3.0",
+ "doctrine/orm": "^2.7.4",
+ "psr/log": "^1|^2|^3",
+ "symfony/cache": "^5.4|^6.0",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/doctrine-messenger": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/form": "^5.4.21|^6.2.7",
+ "symfony/http-kernel": "^6.2",
+ "symfony/messenger": "^5.4|^6.0",
+ "symfony/property-access": "^5.4|^6.0",
+ "symfony/property-info": "^5.4|^6.0",
+ "symfony/proxy-manager-bridge": "^5.4|^6.0",
+ "symfony/security-core": "^6.0",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/uid": "^5.4|^6.0",
+ "symfony/validator": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "suggest": {
+ "doctrine/data-fixtures": "",
+ "doctrine/dbal": "",
+ "doctrine/orm": "",
+ "symfony/form": "",
+ "symfony/property-info": "",
+ "symfony/validator": ""
+ },
+ "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/v6.2.8"
+ },
+ "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-03-09T16:20:02+00:00"
+ },
+ {
+ "name": "symfony/dotenv",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dotenv.git",
+ "reference": "4481aa45be7a11d2335c1d5b5bbe2f0c6199b105"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dotenv/zipball/4481aa45be7a11d2335c1d5b5bbe2f0c6199b105",
+ "reference": "4481aa45be7a11d2335c1d5b5bbe2f0c6199b105",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "conflict": {
+ "symfony/console": "<5.4",
+ "symfony/process": "<5.4"
+ },
+ "require-dev": {
+ "symfony/console": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.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/v6.2.8"
+ },
+ "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-03-10T10:06:03+00:00"
+ },
+ {
+ "name": "symfony/error-handler",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/error-handler.git",
+ "reference": "61e90f94eb014054000bc902257d2763fac09166"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/61e90f94eb014054000bc902257d2763fac09166",
+ "reference": "61e90f94eb014054000bc902257d2763fac09166",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^1|^2|^3",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "require-dev": {
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/serializer": "^5.4|^6.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/v6.2.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": "2023-02-14T08:44:56+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
+ "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/event-dispatcher-contracts": "^2|^3"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4"
+ },
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/stopwatch": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8"
+ },
+ "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-03-20T16:06:02+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
+ "reference": "0ad3b6f1e4e2da5690fefe075cd53a238646d8dd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1"
+ },
+ "suggest": {
+ "symfony/event-dispatcher-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.3-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.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": "2023-03-01T10:32:47+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "82b6c62b959f642d000456f08c6d219d749215b3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/82b6c62b959f642d000456f08c6d219d749215b3",
+ "reference": "82b6c62b959f642d000456f08c6d219d749215b3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides basic utilities for the filesystem",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v6.2.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": "2023-02-14T08:44:56+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb",
+ "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Finds files and directories via an intuitive fluent interface",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v6.2.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": "2023-02-16T09:57:23+00:00"
+ },
+ {
+ "name": "symfony/flex",
+ "version": "v2.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/flex.git",
+ "reference": "2ff8465e7172790a47ab3c129f2b514eb2d8a286"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/flex/zipball/2ff8465e7172790a47ab3c129f2b514eb2d8a286",
+ "reference": "2ff8465e7172790a47ab3c129f2b514eb2d8a286",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^2.1",
+ "php": ">=8.0"
+ },
+ "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.2.5"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-18T08:03:15+00:00"
+ },
+ {
+ "name": "symfony/framework-bundle",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/framework-bundle.git",
+ "reference": "92bf9008afea94408d10148dcff89b259b8fc328"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/92bf9008afea94408d10148dcff89b259b8fc328",
+ "reference": "92bf9008afea94408d10148dcff89b259b8fc328",
+ "shasum": ""
+ },
+ "require": {
+ "composer-runtime-api": ">=2.1",
+ "ext-xml": "*",
+ "php": ">=8.1",
+ "symfony/cache": "^5.4|^6.0",
+ "symfony/config": "^6.1",
+ "symfony/dependency-injection": "^6.2.8",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/error-handler": "^6.1",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/filesystem": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/http-foundation": "^6.2",
+ "symfony/http-kernel": "^6.2.1",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/routing": "^5.4|^6.0"
+ },
+ "conflict": {
+ "doctrine/annotations": "<1.13.1",
+ "doctrine/persistence": "<1.3",
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/asset": "<5.4",
+ "symfony/console": "<5.4",
+ "symfony/dom-crawler": "<5.4",
+ "symfony/dotenv": "<5.4",
+ "symfony/form": "<5.4",
+ "symfony/http-client": "<5.4",
+ "symfony/lock": "<5.4",
+ "symfony/mailer": "<5.4",
+ "symfony/messenger": "<6.2",
+ "symfony/mime": "<6.2",
+ "symfony/property-access": "<5.4",
+ "symfony/property-info": "<5.4",
+ "symfony/security-core": "<5.4",
+ "symfony/security-csrf": "<5.4",
+ "symfony/serializer": "<6.1",
+ "symfony/stopwatch": "<5.4",
+ "symfony/translation": "<6.2.8",
+ "symfony/twig-bridge": "<5.4",
+ "symfony/twig-bundle": "<5.4",
+ "symfony/validator": "<5.4",
+ "symfony/web-profiler-bundle": "<5.4",
+ "symfony/workflow": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.13.1|^2",
+ "doctrine/persistence": "^1.3|^2|^3",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/asset": "^5.4|^6.0",
+ "symfony/browser-kit": "^5.4|^6.0",
+ "symfony/console": "^5.4.9|^6.0.9",
+ "symfony/css-selector": "^5.4|^6.0",
+ "symfony/dom-crawler": "^5.4|^6.0",
+ "symfony/dotenv": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/form": "^5.4|^6.0",
+ "symfony/html-sanitizer": "^6.1",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/lock": "^5.4|^6.0",
+ "symfony/mailer": "^5.4|^6.0",
+ "symfony/messenger": "^6.2",
+ "symfony/mime": "^6.2",
+ "symfony/notifier": "^5.4|^6.0",
+ "symfony/polyfill-intl-icu": "~1.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/property-info": "^5.4|^6.0",
+ "symfony/rate-limiter": "^5.4|^6.0",
+ "symfony/security-bundle": "^5.4|^6.0",
+ "symfony/semaphore": "^5.4|^6.0",
+ "symfony/serializer": "^6.1",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/string": "^5.4|^6.0",
+ "symfony/translation": "^6.2.8",
+ "symfony/twig-bundle": "^5.4|^6.0",
+ "symfony/uid": "^5.4|^6.0",
+ "symfony/validator": "^5.4|^6.0",
+ "symfony/web-link": "^5.4|^6.0",
+ "symfony/workflow": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0",
+ "twig/twig": "^2.10|^3.0"
+ },
+ "suggest": {
+ "ext-apcu": "For best performance of the system caches",
+ "symfony/console": "For using the console commands",
+ "symfony/form": "For using forms",
+ "symfony/property-info": "For using the property_info service",
+ "symfony/serializer": "For using the serializer service",
+ "symfony/validator": "For using validation",
+ "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering",
+ "symfony/yaml": "For using the debug:config and lint:yaml commands"
+ },
+ "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/v6.2.8"
+ },
+ "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-03-31T09:55:36+00:00"
+ },
+ {
+ "name": "symfony/http-foundation",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "511a524affeefc191939348823ac75e9921c2112"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/511a524affeefc191939348823ac75e9921c2112",
+ "reference": "511a524affeefc191939348823ac75e9921c2112",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-mbstring": "~1.1"
+ },
+ "conflict": {
+ "symfony/cache": "<6.2"
+ },
+ "require-dev": {
+ "predis/predis": "~1.0",
+ "symfony/cache": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4",
+ "symfony/mime": "^5.4|^6.0",
+ "symfony/rate-limiter": "^5.2|^6.0"
+ },
+ "suggest": {
+ "symfony/mime": "To use the file extension guesser"
+ },
+ "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/v6.2.8"
+ },
+ "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-03-29T21:42:15+00:00"
+ },
+ {
+ "name": "symfony/http-kernel",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "9563229e56076070d92ca30c089e801e8a4629a3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9563229e56076070d92ca30c089e801e8a4629a3",
+ "reference": "9563229e56076070d92ca30c089e801e8a4629a3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^1|^2|^3",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/error-handler": "^6.1",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4.21|^6.2.7",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "symfony/browser-kit": "<5.4",
+ "symfony/cache": "<5.4",
+ "symfony/config": "<6.1",
+ "symfony/console": "<5.4",
+ "symfony/dependency-injection": "<6.2",
+ "symfony/doctrine-bridge": "<5.4",
+ "symfony/form": "<5.4",
+ "symfony/http-client": "<5.4",
+ "symfony/mailer": "<5.4",
+ "symfony/messenger": "<5.4",
+ "symfony/translation": "<5.4",
+ "symfony/twig-bridge": "<5.4",
+ "symfony/validator": "<5.4",
+ "twig/twig": "<2.13"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
+ },
+ "require-dev": {
+ "psr/cache": "^1.0|^2.0|^3.0",
+ "symfony/browser-kit": "^5.4|^6.0",
+ "symfony/config": "^6.1",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/css-selector": "^5.4|^6.0",
+ "symfony/dependency-injection": "^6.2",
+ "symfony/dom-crawler": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/http-client-contracts": "^1.1|^2|^3",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/routing": "^5.4|^6.0",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/translation-contracts": "^1.1|^2|^3",
+ "symfony/uid": "^5.4|^6.0",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "suggest": {
+ "symfony/browser-kit": "",
+ "symfony/config": "",
+ "symfony/console": "",
+ "symfony/dependency-injection": ""
+ },
+ "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/v6.2.8"
+ },
+ "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-03-31T12:00:10+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "511a08c03c1960e08a883f4cffcacd219b758354"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354",
+ "reference": "511a08c03c1960e08a883f4cffcacd219b758354",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+ "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+ "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
+ {
+ "name": "symfony/routing",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "69062e2823f03b82265d73a966999660f0e1e404"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/69062e2823f03b82265d73a966999660f0e1e404",
+ "reference": "69062e2823f03b82265d73a966999660f0e1e404",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "conflict": {
+ "doctrine/annotations": "<1.12",
+ "symfony/config": "<6.2",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/yaml": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.12|^2",
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^6.2",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/config": "For using the all-in-one router or any loader",
+ "symfony/expression-language": "For using expression matching",
+ "symfony/http-foundation": "For using a Symfony Request object",
+ "symfony/yaml": "For using the YAML loader"
+ },
+ "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/v6.2.8"
+ },
+ "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-03-14T15:00:05+00:00"
+ },
+ {
+ "name": "symfony/runtime",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/runtime.git",
+ "reference": "f8b0751b33888329be8f8f0481bb81d279ec4157"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/runtime/zipball/f8b0751b33888329be8f8f0481bb81d279ec4157",
+ "reference": "f8b0751b33888329be8f8f0481bb81d279ec4157",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0|^2.0",
+ "php": ">=8.1"
+ },
+ "conflict": {
+ "symfony/dotenv": "<5.4"
+ },
+ "require-dev": {
+ "composer/composer": "^1.0.2|^2.0",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/dotenv": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.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/v6.2.8"
+ },
+ "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-03-14T15:48:35+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "a8c9cedf55f314f3a186041d19537303766df09a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a8c9cedf55f314f3a186041d19537303766df09a",
+ "reference": "a8c9cedf55f314f3a186041d19537303766df09a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^2.0"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
+ },
+ "suggest": {
+ "symfony/service-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.3-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.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": "2023-03-01T10:32:47+00:00"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "f3adc98c1061875dd2edcd45e5b04e63d0e29f8f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f3adc98c1061875dd2edcd45e5b04e63d0e29f8f",
+ "reference": "f3adc98c1061875dd2edcd45e5b04e63d0e29f8f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/service-contracts": "^1|^2|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides a way to profile code",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/stopwatch/tree/v6.2.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": "2023-02-14T08:44:56+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef",
+ "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/translation-contracts": "<2.0"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/intl": "^6.2",
+ "symfony/translation-contracts": "^2.0|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v6.2.8"
+ },
+ "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-03-20T16:06:02+00:00"
+ },
+ {
+ "name": "symfony/translation-contracts",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dfec258b9dd17a6b24420d464c43bffe347441c8",
+ "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "suggest": {
+ "symfony/translation-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.3-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.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": "2023-03-01T10:32:47+00:00"
+ },
+ {
+ "name": "symfony/twig-bridge",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/twig-bridge.git",
+ "reference": "30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927",
+ "reference": "30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/translation-contracts": "^1.1|^2|^3",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/console": "<5.4",
+ "symfony/form": "<6.2.7",
+ "symfony/http-foundation": "<5.4",
+ "symfony/http-kernel": "<6.2",
+ "symfony/mime": "<6.2",
+ "symfony/translation": "<5.4",
+ "symfony/workflow": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.12|^2",
+ "egulias/email-validator": "^2.1.10|^3|^4",
+ "league/html-to-markdown": "^5.0",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/asset": "^5.4|^6.0",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/form": "^6.2.7",
+ "symfony/html-sanitizer": "^6.1",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^6.2",
+ "symfony/intl": "^5.4|^6.0",
+ "symfony/mime": "^6.2",
+ "symfony/polyfill-intl-icu": "~1.0",
+ "symfony/property-info": "^5.4|^6.0",
+ "symfony/routing": "^5.4|^6.0",
+ "symfony/security-acl": "^2.8|^3.0",
+ "symfony/security-core": "^5.4|^6.0",
+ "symfony/security-csrf": "^5.4|^6.0",
+ "symfony/security-http": "^5.4|^6.0",
+ "symfony/serializer": "^6.2",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/web-link": "^5.4|^6.0",
+ "symfony/workflow": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0",
+ "twig/cssinliner-extra": "^2.12|^3",
+ "twig/inky-extra": "^2.12|^3",
+ "twig/markdown-extra": "^2.12|^3"
+ },
+ "suggest": {
+ "symfony/asset": "For using the AssetExtension",
+ "symfony/expression-language": "For using the ExpressionExtension",
+ "symfony/finder": "",
+ "symfony/form": "For using the FormExtension",
+ "symfony/html-sanitizer": "For using the HtmlSanitizerExtension",
+ "symfony/http-kernel": "For using the HttpKernelExtension",
+ "symfony/routing": "For using the RoutingExtension",
+ "symfony/security-core": "For using the SecurityExtension",
+ "symfony/security-csrf": "For using the CsrfExtension",
+ "symfony/security-http": "For using the LogoutUrlExtension",
+ "symfony/stopwatch": "For using the StopwatchExtension",
+ "symfony/translation": "For using the TranslationExtension",
+ "symfony/var-dumper": "For using the DumpExtension",
+ "symfony/web-link": "For using the WebLinkExtension",
+ "symfony/yaml": "For using the YamlExtension"
+ },
+ "type": "symfony-bridge",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Bridge\\Twig\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides integration for Twig with various Symfony components",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/twig-bridge/tree/v6.2.8"
+ },
+ "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-03-31T09:14:44+00:00"
+ },
+ {
+ "name": "symfony/twig-bundle",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/twig-bundle.git",
+ "reference": "8bb562655c6ae4b8fae9cf72077591f38b961566"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/8bb562655c6ae4b8fae9cf72077591f38b961566",
+ "reference": "8bb562655c6ae4b8fae9cf72077591f38b961566",
+ "shasum": ""
+ },
+ "require": {
+ "composer-runtime-api": ">=2.1",
+ "php": ">=8.1",
+ "symfony/config": "^6.1",
+ "symfony/dependency-injection": "^6.1",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^6.2",
+ "symfony/twig-bridge": "^6.2",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "conflict": {
+ "symfony/framework-bundle": "<5.4",
+ "symfony/translation": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.10.4|^2",
+ "symfony/asset": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/form": "^5.4|^6.0",
+ "symfony/framework-bundle": "^5.4|^6.0",
+ "symfony/routing": "^5.4|^6.0",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/web-link": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.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/v6.2.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": "2023-02-14T08:44:56+00:00"
+ },
+ {
+ "name": "symfony/var-dumper",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "d37ab6787be2db993747b6218fcc96e8e3bb4bd0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d37ab6787be2db993747b6218fcc96e8e3bb4bd0",
+ "reference": "d37ab6787be2db993747b6218fcc96e8e3bb4bd0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/console": "<5.4"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/uid": "^5.4|^6.0",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "suggest": {
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+ "ext-intl": "To show region name in time zone dump",
+ "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+ },
+ "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/v6.2.8"
+ },
+ "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-03-29T21:42:15+00:00"
+ },
+ {
+ "name": "symfony/var-exporter",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-exporter.git",
+ "reference": "8302bb670204500d492c6b8c595ee9a27da62cd6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/8302bb670204500d492c6b8c595ee9a27da62cd6",
+ "reference": "8302bb670204500d492c6b8c595ee9a27da62cd6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\VarExporter\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Allows exporting any serializable PHP data structure to plain PHP code",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "clone",
+ "construct",
+ "export",
+ "hydrate",
+ "instantiate",
+ "lazy-loading",
+ "proxy",
+ "serialize"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-exporter/tree/v6.2.8"
+ },
+ "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-03-14T15:48:45+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/e8e6a1d59e050525f27a1f530aa9703423cb7f57",
+ "reference": "e8e6a1d59e050525f27a1f530aa9703423cb7f57",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "symfony/console": "<5.4"
+ },
+ "require-dev": {
+ "symfony/console": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "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/v6.2.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": "2023-02-16T09:57:23+00:00"
+ },
+ {
+ "name": "twig/extra-bundle",
+ "version": "v3.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/twig-extra-bundle.git",
+ "reference": "a961e553a624eebdbd423ad5ab931497ca6d87cd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/a961e553a624eebdbd423ad5ab931497ca6d87cd",
+ "reference": "a961e553a624eebdbd423ad5ab931497ca6d87cd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/framework-bundle": "^4.4|^5.0|^6.0",
+ "symfony/twig-bundle": "^4.4|^5.0|^6.0",
+ "twig/twig": "^2.7|^3.0"
+ },
+ "require-dev": {
+ "league/commonmark": "^1.0|^2.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0",
+ "twig/cache-extra": "^3.0",
+ "twig/cssinliner-extra": "^2.12|^3.0",
+ "twig/html-extra": "^2.12|^3.0",
+ "twig/inky-extra": "^2.12|^3.0",
+ "twig/intl-extra": "^2.12|^3.0",
+ "twig/markdown-extra": "^2.12|^3.0",
+ "twig/string-extra": "^2.12|^3.0"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.5-dev"
+ }
+ },
+ "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.5.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-08T07:44:55+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v3.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15",
+ "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.5-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v3.5.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-08T07:49:20+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.15.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
+ "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4"
+ },
+ "time": "2023-03-05T19:49:14+00:00"
+ },
+ {
+ "name": "symfony/maker-bundle",
+ "version": "v1.48.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/maker-bundle.git",
+ "reference": "2e428e8432e9879187672fe08f1cc335e2a31dd6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/2e428e8432e9879187672fe08f1cc335e2a31dd6",
+ "reference": "2e428e8432e9879187672fe08f1cc335e2a31dd6",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/inflector": "^2.0",
+ "nikic/php-parser": "^4.11",
+ "php": ">=8.0",
+ "symfony/config": "^5.4.7|^6.0",
+ "symfony/console": "^5.4.7|^6.0",
+ "symfony/dependency-injection": "^5.4.7|^6.0",
+ "symfony/deprecation-contracts": "^2.2|^3",
+ "symfony/filesystem": "^5.4.7|^6.0",
+ "symfony/finder": "^5.4.3|^6.0",
+ "symfony/framework-bundle": "^5.4.7|^6.0",
+ "symfony/http-kernel": "^5.4.7|^6.0"
+ },
+ "conflict": {
+ "doctrine/doctrine-bundle": "<2.4",
+ "doctrine/orm": "<2.10",
+ "symfony/doctrine-bridge": "<5.4"
+ },
+ "require-dev": {
+ "composer/semver": "^3.0",
+ "doctrine/doctrine-bundle": "^2.4",
+ "doctrine/orm": "^2.10.0",
+ "symfony/http-client": "^5.4.7|^6.0",
+ "symfony/phpunit-bridge": "^5.4.7|^6.0",
+ "symfony/polyfill-php80": "^1.16.0",
+ "symfony/process": "^5.4.7|^6.0",
+ "symfony/security-core": "^5.4.7|^6.0",
+ "symfony/yaml": "^5.4.3|^6.0",
+ "twig/twig": "^2.0|^3.0"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Bundle\\MakerBundle\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "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": [
+ "code generator",
+ "generator",
+ "scaffold",
+ "scaffolding"
+ ],
+ "support": {
+ "issues": "https://github.com/symfony/maker-bundle/issues",
+ "source": "https://github.com/symfony/maker-bundle/tree/v1.48.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-14T10:48:46+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": true,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=8.1",
+ "ext-ctype": "*",
+ "ext-iconv": "*"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
diff --git a/config/bundles.php b/config/bundles.php
new file mode 100644
index 0000000..4491fe8
--- /dev/null
+++ b/config/bundles.php
@@ -0,0 +1,10 @@
+<?php
+
+return [
+ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
+ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
+ Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
+ Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
+ Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
+ Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
+];
diff --git a/config/packages/cache.yaml b/config/packages/cache.yaml
new file mode 100644
index 0000000..6899b72
--- /dev/null
+++ b/config/packages/cache.yaml
@@ -0,0 +1,19 @@
+framework:
+ cache:
+ # Unique name of your app: used to compute stable namespaces for cache keys.
+ #prefix_seed: your_vendor_name/app_name
+
+ # The "app" cache stores to the filesystem by default.
+ # The data in this cache should persist between deploys.
+ # Other options include:
+
+ # Redis
+ #app: cache.adapter.redis
+ #default_redis_provider: redis://localhost
+
+ # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
+ #app: cache.adapter.apcu
+
+ # Namespaced pools use the above "app" backend by default
+ #pools:
+ #my.dedicated.cache: null
diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml
new file mode 100644
index 0000000..bdff96f
--- /dev/null
+++ b/config/packages/doctrine.yaml
@@ -0,0 +1,44 @@
+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: '15'
+ orm:
+ auto_generate_proxy_classes: true
+ enable_lazy_ghost_objects: true
+ naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
+ auto_mapping: true
+ mappings:
+ App:
+ is_bundle: false
+ dir: '%kernel.project_dir%/src/Entity'
+ prefix: 'App\Entity'
+ alias: App
+
+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/framework.yaml b/config/packages/framework.yaml
new file mode 100644
index 0000000..6d85c29
--- /dev/null
+++ b/config/packages/framework.yaml
@@ -0,0 +1,25 @@
+# see https://symfony.com/doc/current/reference/configuration/framework.html
+framework:
+ secret: '%env(APP_SECRET)%'
+ #csrf_protection: true
+ http_method_override: false
+ handle_all_throwables: true
+
+ # Enables session support. Note that the session will ONLY be started if you read or write from it.
+ # Remove or comment this section to explicitly disable session support.
+ session:
+ handler_id: null
+ cookie_secure: auto
+ cookie_samesite: lax
+ storage_factory_id: session.storage.factory.native
+
+ #esi: true
+ #fragments: true
+ php_errors:
+ log: true
+
+when@test:
+ framework:
+ test: true
+ session:
+ storage_factory_id: session.storage.factory.mock_file
diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml
new file mode 100644
index 0000000..4b766ce
--- /dev/null
+++ b/config/packages/routing.yaml
@@ -0,0 +1,12 @@
+framework:
+ router:
+ utf8: true
+
+ # Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
+ # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
+ #default_uri: http://localhost
+
+when@prod:
+ framework:
+ router:
+ strict_requirements: null
diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml
new file mode 100644
index 0000000..1782214
--- /dev/null
+++ b/config/packages/twig.yaml
@@ -0,0 +1,8 @@
+twig:
+ default_path: '%kernel.project_dir%/templates'
+ paths:
+ 'components': 'components'
+
+when@test:
+ twig:
+ strict_variables: true
diff --git a/config/preload.php b/config/preload.php
new file mode 100644
index 0000000..5ebcdb2
--- /dev/null
+++ b/config/preload.php
@@ -0,0 +1,5 @@
+<?php
+
+if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
+ require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
+}
diff --git a/config/routes.yaml b/config/routes.yaml
new file mode 100644
index 0000000..41ef814
--- /dev/null
+++ b/config/routes.yaml
@@ -0,0 +1,5 @@
+controllers:
+ resource:
+ path: ../src/Controller/
+ namespace: App\Controller
+ type: attribute
diff --git a/config/routes/framework.yaml b/config/routes/framework.yaml
new file mode 100644
index 0000000..0fc74bb
--- /dev/null
+++ b/config/routes/framework.yaml
@@ -0,0 +1,4 @@
+when@dev:
+ _errors:
+ resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
+ prefix: /_error
diff --git a/config/services.yaml b/config/services.yaml
new file mode 100644
index 0000000..e912eeb
--- /dev/null
+++ b/config/services.yaml
@@ -0,0 +1,26 @@
+# This file is the entry point to configure your own services.
+# Files in the packages/ subdirectory configure your dependencies.
+
+# Put parameters here that don't need to change on each machine where the app is deployed
+# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
+parameters:
+ devices_dir: '%kernel.project_dir%/content/devices/'
+ screenshots_dir: '%kernel.project_dir%/public/assets/images/screenshots'
+
+services:
+ # default configuration for services in *this* file
+ _defaults:
+ autowire: true # Automatically injects dependencies in your services.
+ autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
+
+ # makes classes in src/ available to be used as services
+ # this creates a service per class whose id is the fully-qualified class name
+ App\:
+ resource: '../src/'
+ exclude:
+ - '../src/DependencyInjection/'
+ - '../src/Entity/'
+ - '../src/Kernel.php'
+
+ # add more service definitions when explicit configuration is needed
+ # please note that last definitions always *replace* previous ones
diff --git a/content/devices/beyond0lte.yml b/content/devices/beyond0lte.yml
new file mode 100644
index 0000000..ef5da9a
--- /dev/null
+++ b/content/devices/beyond0lte.yml
@@ -0,0 +1,30 @@
+status: active
+name: Galaxy S10e
+vendor: Samsung
+codename: beyond0lte
+models: [SM-G970F, SM-G970F/DS, SM-G970N]
+image: beyond0lte.webp
+release: 2019-03-08
+maintainers: [Linux4]
+versions: [2.0]
+
+soc: Samsung Exynos 9820
+architecture: arm64
+cpu: Exynos M4 & Cortex-A75 & Cortex-A55
+cpu_cores: '8'
+cpu_freq: 2 x 2.73 GHz + 2x 2.31 + 4 x 1.95 GHz
+gpu: ARM Mali-G76 MP12
+ram: 6/8 GB
+storage: 128/256 GB
+sdcard: {sizeMax: '512 GB'}
+screen: {size: '147.3 mm (5.8 in)', density: 438, resolution: '2280x1080', technology: 'Full HD+ Dynamic AMOLED'}
+battery: {removable: False, capacity: 3100, tech: 'Li-Ion'}
+cameras:
+- {flash: 'LED', info: '12 MP'}
+- {flash: 'LED', info: '16 MP (ultrawide)'}
+- {flash: None, info: '10 MP'}
+network: [2G GSM, 3G UMTS, 4G LTE]
+wifi: 802.11 a/b/g/n/ac/ax, Dual-band, Wi-Fi Direct, Hotspot
+bluetooth: {spec: '5', profiles: [A2DP + aptX]}
+peripherals: [Accelerometer, Barometer, Compass, Fingerprint reader, GPS, Gyroscope, Proximity sensor, Qi wireless charging, Qi reverse wireless charging]
+dimensions: {width: '69.9 mm (2.75 in)', height: '142.2 mm (5.6 in)', depth: '7.9 mm (0.31 in)'}
\ No newline at end of file
diff --git a/content/devices/beyond1lte.yml b/content/devices/beyond1lte.yml
new file mode 100644
index 0000000..7fd1cef
--- /dev/null
+++ b/content/devices/beyond1lte.yml
@@ -0,0 +1,31 @@
+status: active
+name: Galaxy S10
+vendor: Samsung
+codename: beyond1lte
+models: [SM-G973F, SM-G973F/DS, SM-G973N]
+image: beyond1lte.webp
+release: 2019-03-08
+maintainers: [Linux4]
+versions: [2.0]
+
+soc: Samsung Exynos 9820
+architecture: arm64
+cpu: Exynos M4 & Cortex-A75 & Cortex-A55
+cpu_cores: '8'
+cpu_freq: 2 x 2.73 GHz + 2x 2.31 + 4 x 1.95 GHz
+gpu: ARM Mali-G76 MP12
+ram: 8 GB
+storage: 128/256 GB
+sdcard: {sizeMax: '512 GB'}
+screen: {size: '154.9 mm (6.1 in)', density: 550, resolution: '3040x1440', technology: 'Quad HD+ Dynamic AMOLED'}
+battery: {removable: False, capacity: 3400, tech: 'Li-Ion'}
+cameras:
+- {flash: 'LED', info: '12 MP'}
+- {flash: 'LED', info: '12 MP (telephoto)'}
+- {flash: 'LED', info: '16 MP (ultrawide)'}
+- {flash: None, info: '10 MP'}
+network: [2G GSM, 3G UMTS, 4G LTE]
+wifi: 802.11 a/b/g/n/ac/ax, Dual-band, Wi-Fi Direct, Hotspot
+bluetooth: {spec: '5', profiles: [A2DP + aptX]}
+peripherals: [Accelerometer, Barometer, Compass, Fingerprint reader, GPS, Gyroscope, Heart rate sensor, Proximity sensor, Qi wireless charging, Qi reverse wireless charging]
+dimensions: {width: '70.4 mm (2.77 in)', height: '149.9 mm (5.9 in)', depth: '7.8 mm (0.31 in)'}
\ No newline at end of file
diff --git a/content/devices/beyond2lte.yml b/content/devices/beyond2lte.yml
new file mode 100644
index 0000000..638edc5
--- /dev/null
+++ b/content/devices/beyond2lte.yml
@@ -0,0 +1,32 @@
+status: active
+name: Galaxy S10+
+vendor: Samsung
+codename: beyond2lte
+models: [SM-G975F, SM-G975F/DS, SM-G975N]
+image: beyond2lte.webp
+release: 2019-03-08
+maintainers: [Linux4]
+versions: [2.0]
+
+soc: Samsung Exynos 9820
+architecture: arm64
+cpu: Exynos M4 & Cortex-A75 & Cortex-A55
+cpu_cores: '8'
+cpu_freq: 2 x 2.73 GHz + 2x 2.31 + 4 x 1.95 GHz
+gpu: ARM Mali-G76 MP12
+ram: 8/12 GB
+storage: 128/256 GB
+sdcard: {sizeMax: '512 GB'}
+screen: {size: '162.5 mm (6.4 in)', density: 522, resolution: '3040x1440', technology: 'Quad HD+ Dynamic AMOLED'}
+battery: {removable: False, capacity: 4100, tech: 'Li-Ion'}
+cameras:
+- {flash: 'LED', info: '12 MP'}
+- {flash: 'LED', info: '12 MP (telephoto)'}
+- {flash: 'LED', info: '16 MP (ultrawide)'}
+- {flash: None, info: '10 MP'}
+- {flash: None, info: '8 MP (depth sensor)'}
+network: [2G GSM, 3G UMTS, 4G LTE]
+wifi: 802.11 a/b/g/n/ac/ax, Dual-band, Wi-Fi Direct, Hotspot
+bluetooth: {spec: '5', profiles: [A2DP + aptX]}
+peripherals: [Accelerometer, Barometer, Compass, Fingerprint reader, GPS, Gyroscope, Heart rate sensor, Proximity sensor, Qi wireless charging, Qi reverse wireless charging]
+dimensions: {width: '74.1 mm (2.92 in)', height: '157.6 mm (6.2 in)', depth: '7.8 mm (0.31 in)'}
diff --git a/migrations/.gitignore b/migrations/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/migrations/.gitignore
diff --git a/public/assets/app.css b/public/assets/app.css
new file mode 100644
index 0000000..ce6370c
--- /dev/null
+++ b/public/assets/app.css
@@ -0,0 +1,155 @@
+@import url('https://fonts.cdnfonts.com/css/century-gothic');
+
+:root {
+ --color-leaf: #90ee90;
+ --color-leaf-text: #202124;
+}
+
+*, *:before, *:after {
+ box-sizing: inherit;
+}
+
+html {
+ box-sizing: border-box;
+ font-family: 'Century Gothic', sans-serif;
+ color-scheme: only light;
+}
+
+body {
+ margin: 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 300;
+}
+
+a.community {
+ text-decoration: none;
+ color: #1ec71e;
+ text-shadow: 1px 1px 2px #989898, -1px -1px 2px #ffffff;
+}
+
+.get-leaf {
+ text-decoration: none;
+ padding: 8px 12px;
+ background-color: #1ec71e;
+ color: white;
+ font-weight: 400;
+}
+
+footer {
+ font-size: 16px;
+ text-align: center;
+ padding: 40px;
+ background-color: #f8f9fa;
+}
+
+.container {
+ width: 100%;
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+@media (min-width: 576px) {
+ .container {
+ max-width: 540px;
+ }
+}
+
+@media (min-width: 768px) {
+ .container {
+ max-width: 720px;
+ }
+}
+
+@media (min-width: 992px) {
+ .container {
+ max-width: 960px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ max-width: 1140px;
+ }
+}
+
+.sidenav {
+ width: 260px;
+ box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3 px 6px rgba(0, 0, 0, 0.23);
+ height: 100vh;
+ background-color: #e7e9eb;
+ overflow-y: hidden;
+ overflow-x: hidden;
+ padding-top: 20px;
+ position: fixed;
+ top: 0;
+ padding-bottom: 0;
+ margin-top: 64px;
+}
+
+.sidenav h2 {
+ font-size: 21px;
+ padding-left: 16px;
+ margin: -4px 0 4px 0;
+ width: 204px;
+}
+
+.sidenav ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.sidenav a {
+ text-decoration: none;
+ display: block;
+ padding: 10px 16px;
+ color: inherit;
+}
+
+.sidenav a:hover {
+ color: #000000;
+ background-color: #cccccc;
+}
+
+.sidenav a.active {
+ background-color: #90ee90;
+ color: #202124;
+ font-weight: 700;
+}
+
+.sidenav~.content {
+ margin-left: 260px;
+ max-width: calc(100vw - 260px);
+}
+
+.content {
+ min-height: calc(100vh - (64px) - (40px * 2 + 16px));
+}
+
+.banner {
+ background-color: #90ee90;
+ color: #202124;
+ padding: 2.125rem 0;
+ margin-bottom: 2rem;
+ border-radius: 0;
+}
+
+@media (prefers-color-scheme: dark) {
+ html {
+ background-color: #1c1b22;
+ color: white;
+ }
+
+ a.community {
+ text-shadow: 1px 1px 2px #989898, -1px -1px 2px #000000;
+ }
+
+ footer,
+ .sidenav {
+ background-color: #0e0d11;
+ }
+}
\ No newline at end of file
diff --git a/public/assets/gallery.css b/public/assets/gallery.css
new file mode 100644
index 0000000..e459f42
--- /dev/null
+++ b/public/assets/gallery.css
@@ -0,0 +1,26 @@
+.content {
+ background-color: #129b5ad5;
+}
+
+.grid {
+ margin-left: auto;
+ margin-right: auto;
+ width: 90vw;
+ display: grid;
+ grid-template-columns: repeat(5, minmax(0, 1fr));
+ row-gap: 25px;
+ padding-bottom: 20px;
+}
+
+img {
+ border-radius: 20px;
+ width: 200px;
+ justify-self: center;
+ box-shadow: 1px 1px 8px black;
+}
+
+@media screen and (max-width: 600px) {
+ .grid {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+ }
+}
\ No newline at end of file
diff --git a/public/assets/images/devices/beyond0lte.webp b/public/assets/images/devices/beyond0lte.webp
new file mode 100644
index 0000000..a9635f1
--- /dev/null
+++ b/public/assets/images/devices/beyond0lte.webp
Binary files differ
diff --git a/public/assets/images/devices/beyond1lte.webp b/public/assets/images/devices/beyond1lte.webp
new file mode 100644
index 0000000..bf7b6d0
--- /dev/null
+++ b/public/assets/images/devices/beyond1lte.webp
Binary files differ
diff --git a/public/assets/images/devices/beyond2lte.webp b/public/assets/images/devices/beyond2lte.webp
new file mode 100644
index 0000000..bd50d5a
--- /dev/null
+++ b/public/assets/images/devices/beyond2lte.webp
Binary files differ
diff --git a/public/assets/images/screenshots/0.webp b/public/assets/images/screenshots/0.webp
new file mode 100644
index 0000000..5cb5693
--- /dev/null
+++ b/public/assets/images/screenshots/0.webp
Binary files differ
diff --git a/public/assets/images/screenshots/1.webp b/public/assets/images/screenshots/1.webp
new file mode 100644
index 0000000..27cbe51
--- /dev/null
+++ b/public/assets/images/screenshots/1.webp
Binary files differ
diff --git a/public/assets/images/screenshots/10.webp b/public/assets/images/screenshots/10.webp
new file mode 100644
index 0000000..6fa96d8
--- /dev/null
+++ b/public/assets/images/screenshots/10.webp
Binary files differ
diff --git a/public/assets/images/screenshots/11.webp b/public/assets/images/screenshots/11.webp
new file mode 100644
index 0000000..89ca565
--- /dev/null
+++ b/public/assets/images/screenshots/11.webp
Binary files differ
diff --git a/public/assets/images/screenshots/12.webp b/public/assets/images/screenshots/12.webp
new file mode 100644
index 0000000..8d748b0
--- /dev/null
+++ b/public/assets/images/screenshots/12.webp
Binary files differ
diff --git a/public/assets/images/screenshots/13.webp b/public/assets/images/screenshots/13.webp
new file mode 100644
index 0000000..c2dd354
--- /dev/null
+++ b/public/assets/images/screenshots/13.webp
Binary files differ
diff --git a/public/assets/images/screenshots/14.webp b/public/assets/images/screenshots/14.webp
new file mode 100644
index 0000000..486b061
--- /dev/null
+++ b/public/assets/images/screenshots/14.webp
Binary files differ
diff --git a/public/assets/images/screenshots/15.webp b/public/assets/images/screenshots/15.webp
new file mode 100644
index 0000000..6f5c285
--- /dev/null
+++ b/public/assets/images/screenshots/15.webp
Binary files differ
diff --git a/public/assets/images/screenshots/16.webp b/public/assets/images/screenshots/16.webp
new file mode 100644
index 0000000..abbf38d
--- /dev/null
+++ b/public/assets/images/screenshots/16.webp
Binary files differ
diff --git a/public/assets/images/screenshots/17.webp b/public/assets/images/screenshots/17.webp
new file mode 100644
index 0000000..95411e7
--- /dev/null
+++ b/public/assets/images/screenshots/17.webp
Binary files differ
diff --git a/public/assets/images/screenshots/18.webp b/public/assets/images/screenshots/18.webp
new file mode 100644
index 0000000..b141c0b
--- /dev/null
+++ b/public/assets/images/screenshots/18.webp
Binary files differ
diff --git a/public/assets/images/screenshots/19.webp b/public/assets/images/screenshots/19.webp
new file mode 100644
index 0000000..6f17582
--- /dev/null
+++ b/public/assets/images/screenshots/19.webp
Binary files differ
diff --git a/public/assets/images/screenshots/2.webp b/public/assets/images/screenshots/2.webp
new file mode 100644
index 0000000..5680144
--- /dev/null
+++ b/public/assets/images/screenshots/2.webp
Binary files differ
diff --git a/public/assets/images/screenshots/20.webp b/public/assets/images/screenshots/20.webp
new file mode 100644
index 0000000..aa0747f
--- /dev/null
+++ b/public/assets/images/screenshots/20.webp
Binary files differ
diff --git a/public/assets/images/screenshots/21.webp b/public/assets/images/screenshots/21.webp
new file mode 100644
index 0000000..ce3da1c
--- /dev/null
+++ b/public/assets/images/screenshots/21.webp
Binary files differ
diff --git a/public/assets/images/screenshots/22.webp b/public/assets/images/screenshots/22.webp
new file mode 100644
index 0000000..27d0930
--- /dev/null
+++ b/public/assets/images/screenshots/22.webp
Binary files differ
diff --git a/public/assets/images/screenshots/23.webp b/public/assets/images/screenshots/23.webp
new file mode 100644
index 0000000..a13adb3
--- /dev/null
+++ b/public/assets/images/screenshots/23.webp
Binary files differ
diff --git a/public/assets/images/screenshots/24.webp b/public/assets/images/screenshots/24.webp
new file mode 100644
index 0000000..d993c00
--- /dev/null
+++ b/public/assets/images/screenshots/24.webp
Binary files differ
diff --git a/public/assets/images/screenshots/25.webp b/public/assets/images/screenshots/25.webp
new file mode 100644
index 0000000..b650c7f
--- /dev/null
+++ b/public/assets/images/screenshots/25.webp
Binary files differ
diff --git a/public/assets/images/screenshots/26.webp b/public/assets/images/screenshots/26.webp
new file mode 100644
index 0000000..00be060
--- /dev/null
+++ b/public/assets/images/screenshots/26.webp
Binary files differ
diff --git a/public/assets/images/screenshots/27.webp b/public/assets/images/screenshots/27.webp
new file mode 100644
index 0000000..22935d9
--- /dev/null
+++ b/public/assets/images/screenshots/27.webp
Binary files differ
diff --git a/public/assets/images/screenshots/28.webp b/public/assets/images/screenshots/28.webp
new file mode 100644
index 0000000..da39b65
--- /dev/null
+++ b/public/assets/images/screenshots/28.webp
Binary files differ
diff --git a/public/assets/images/screenshots/29.webp b/public/assets/images/screenshots/29.webp
new file mode 100644
index 0000000..6e46604
--- /dev/null
+++ b/public/assets/images/screenshots/29.webp
Binary files differ
diff --git a/public/assets/images/screenshots/3.webp b/public/assets/images/screenshots/3.webp
new file mode 100644
index 0000000..3732ddb
--- /dev/null
+++ b/public/assets/images/screenshots/3.webp
Binary files differ
diff --git a/public/assets/images/screenshots/4.webp b/public/assets/images/screenshots/4.webp
new file mode 100644
index 0000000..92e9e38
--- /dev/null
+++ b/public/assets/images/screenshots/4.webp
Binary files differ
diff --git a/public/assets/images/screenshots/5.webp b/public/assets/images/screenshots/5.webp
new file mode 100644
index 0000000..e733e94
--- /dev/null
+++ b/public/assets/images/screenshots/5.webp
Binary files differ
diff --git a/public/assets/images/screenshots/6.webp b/public/assets/images/screenshots/6.webp
new file mode 100644
index 0000000..98a8945
--- /dev/null
+++ b/public/assets/images/screenshots/6.webp
Binary files differ
diff --git a/public/assets/images/screenshots/7.webp b/public/assets/images/screenshots/7.webp
new file mode 100644
index 0000000..d4f8fe7
--- /dev/null
+++ b/public/assets/images/screenshots/7.webp
Binary files differ
diff --git a/public/assets/images/screenshots/8.webp b/public/assets/images/screenshots/8.webp
new file mode 100644
index 0000000..a27a9fa
--- /dev/null
+++ b/public/assets/images/screenshots/8.webp
Binary files differ
diff --git a/public/assets/images/screenshots/9.webp b/public/assets/images/screenshots/9.webp
new file mode 100644
index 0000000..2b56b4b
--- /dev/null
+++ b/public/assets/images/screenshots/9.webp
Binary files differ
diff --git a/public/assets/navbar.css b/public/assets/navbar.css
new file mode 100644
index 0000000..b9972bb
--- /dev/null
+++ b/public/assets/navbar.css
@@ -0,0 +1,153 @@
+nav.navbar {
+ background-color: #333;
+ position: sticky;
+ top: 0;
+ z-index: 999;
+ box-shadow: 1px 1px 8px black;
+}
+
+nav.navbar input.hamburger[type=checkbox],
+nav.navbar input.hamburger[type=checkbox]+label,
+input.hamburger-sidenav[type=checkbox],
+input.hamburger-sidenav[type=checkbox]~nav.navbar label.label-sidenav {
+ display: none;
+}
+
+nav.navbar ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+}
+
+nav.navbar ul li {
+ float: left;
+}
+
+nav.navbar ul li a {
+ display: block;
+ color: white;
+ text-align: center;
+ padding: 14px 16px;
+ text-decoration: none;
+}
+
+nav.navbar ul li a.active {
+ background-color: #90ee90;
+ color: #202124;
+}
+
+nav.navbar ul li a:not(.logo) {
+ padding: 21px 16px;
+}
+
+nav.navbar ul li a:hover:not(.active) {
+ background-color: #111;
+}
+
+
+nav.navbar ul li.right {
+ float: right;
+}
+
+@media screen and (max-width: 600px) {
+ input.hamburger-sidenav[type=checkbox]~nav.navbar label.label-sidenav {
+ display: block;
+ cursor: pointer;
+ float: left;
+ }
+
+ input.hamburger-sidenav[type=checkbox]~nav.navbar label.label-sidenav .icon-bar {
+ display: block;
+ width: 48px;
+ height: 6px;
+ background-color: #cccccc;
+ margin: 10px;
+ transition: all 0.2s;
+ }
+
+ input.hamburger-sidenav[type=checkbox]~nav.navbar label.label-sidenav .top-bar {
+ width: 24px;
+ transform: translateY(9px) rotate(45deg);
+ }
+
+ input.hamburger-sidenav[type=checkbox]~nav.navbar label.label-sidenav .middle-bar {
+ opacity: 0;
+ }
+
+ input.hamburger-sidenav[type=checkbox]~nav.navbar label.label-sidenav .bottom-bar {
+ width: 24px;
+ transform: translateY(-9px) rotate(-45deg);
+ }
+
+ input.hamburger-sidenav[type=checkbox]:checked~nav.navbar label.label-sidenav .top-bar {
+ transform: translateY(9px) rotate(-45deg);
+ }
+
+ input.hamburger-sidenav[type=checkbox]:checked~nav.navbar label.label-sidenav .middle-bar {
+ opacity: 0;
+ }
+
+ input.hamburger-sidenav[type=checkbox]:checked~nav.navbar label.label-sidenav .bottom-bar {
+ transform: translateY(-9px) rotate(45deg);
+ }
+
+ div.sidenav {
+ display: none;
+ }
+
+ input.hamburger-sidenav[type=checkbox]:checked~div.sidenav {
+ display: block;
+ }
+
+ nav.navbar ul li.right, nav.navbar ul li:not(.nav-logo) {
+ float: none;
+ }
+
+ nav.navbar input.hamburger[type=checkbox]+label {
+ display: block;
+ cursor: pointer;
+ float: right;
+ }
+
+ nav.navbar input.hamburger[type=checkbox]+label .icon-bar {
+ display: block;
+ width: 48px;
+ height: 6px;
+ background-color: #cccccc;
+ margin: 10px;
+ transition: all 0.2s;
+ }
+
+ nav.navbar input.hamburger[type=checkbox]+label .top-bar {
+ transform: rotate(0);
+ }
+
+ nav.navbar input.hamburger[type=checkbox]+label .middle-bar {
+ opacity: 1;
+ }
+
+ nav.navbar input.hamburger[type=checkbox]:checked+label .top-bar {
+ transform: translateY(16px) rotate(45deg);
+ }
+
+ nav.navbar input.hamburger[type=checkbox]:checked+label .middle-bar {
+ opacity: 0;
+ }
+
+ nav.navbar input.hamburger[type=checkbox]:checked+label .bottom-bar {
+ transform: translateY(-16px) rotate(-45deg);
+ }
+
+ nav.navbar li:nth-of-type(2) {
+ margin-top: 64px;
+ }
+
+ nav.navbar li:not(.nav-logo) {
+ display: none;
+ }
+
+ nav.navbar input.hamburger[type=checkbox]:checked~ul li:not(.nav-logo) {
+ display: block;
+ }
+}
\ No newline at end of file
diff --git a/public/assets/wiki.css b/public/assets/wiki.css
new file mode 100644
index 0000000..c7f4229
--- /dev/null
+++ b/public/assets/wiki.css
@@ -0,0 +1,69 @@
+.device-info {
+ display: flex;
+}
+
+.specs {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.heading h2,
+.heading p {
+ text-align: center;
+ margin: 0;
+}
+
+.heading p {
+ font-size: small;
+}
+
+.sheet {
+ display: flex;
+ column-gap: 8px;
+}
+
+.specs img {
+ max-width: 200px;
+ object-fit: contain;
+ align-self: center;
+ padding: 1rem 0;
+}
+
+
+table {
+ margin: 1rem 0;
+ border-collapse: collapse;
+}
+
+th, td {
+ padding: 12px;
+}
+
+tr:not(:last-of-type) {
+ border-bottom: 1px solid #888;
+
+}
+
+tbody {
+ font-size: small
+}
+
+tbody p {
+ padding: 0;
+ margin: 0;
+}
+
+tbody ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+tbody td:nth-child(2) {
+ text-align: right;
+}
+
+.instructions {
+ flex: 2;
+}
\ No newline at end of file
diff --git a/public/index.php b/public/index.php
new file mode 100644
index 0000000..9982c21
--- /dev/null
+++ b/public/index.php
@@ -0,0 +1,9 @@
+<?php
+
+use App\Kernel;
+
+require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
+
+return function (array $context) {
+ return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
+};
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..634d282
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,26 @@
+<p align="center">
+ <a href="https://github.com/LeafOS-Project">
+ <img src="https://i.imgur.com/G0gNZxg.png"/>
+</p>
+<h2 align="center">LeafOS</h2>
+
+## 1. Getting started
+The LeafOS website runs on Symfony 6.2. You can check the [Symfony documentation](https://symfony.com/doc/current/setup.html) for the framework requirements. There are no additional requirements other than those.
+
+After the requirements have been met, you can install the required dependencies by running `composer install`.
+
+## 2. Running the site
+There are two ways to run the site locally: by using PHP built-in webserver or by using Apache/Nginx.
+
+### Method 1: Using the PHP built-in server
+After you've installed the required dependencies, you can start the PHP server by running the following command from the project root:
+
+```
+php -S localhost:8000 -t public/
+```
+
+After that, you can check the site by going to [localhost:8000](localhost:8000) on your browser. If the port 8000 is in use in your machine, simple change it to something else.
+
+### Method 2: using Apache/Nginx
+Both Apache and Nginx are supported by Symfony. There is a dedicated section on Symfony documentation for that, please refer to [this page](https://symfony.com/doc/current/setup/web_server_configuration.html) in order to configure Apache/Nginx.
+
diff --git a/src/Controller/AboutController.php b/src/Controller/AboutController.php
new file mode 100644
index 0000000..0327837
--- /dev/null
+++ b/src/Controller/AboutController.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class AboutController extends AbstractController
+{
+ #[Route('/about', name: 'leaf_about')]
+ public function index(): Response
+ {
+ return $this->render('about/index.html.twig');
+ }
+}
diff --git a/src/Controller/CommunityController.php b/src/Controller/CommunityController.php
new file mode 100644
index 0000000..cc02724
--- /dev/null
+++ b/src/Controller/CommunityController.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class CommunityController extends AbstractController
+{
+ #[Route('/community', name: 'leaf_community')]
+ public function index(): Response
+ {
+ return $this->render('community/index.html.twig');
+ }
+}
diff --git a/src/Controller/GalleryController.php b/src/Controller/GalleryController.php
new file mode 100644
index 0000000..c46e366
--- /dev/null
+++ b/src/Controller/GalleryController.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class GalleryController extends AbstractController {
+ #[Route('/gallery', name: 'leaf_gallery')]
+ public function index(): Response {
+ $screenshots = array_filter(scandir($this->getParameter('screenshots_dir')), function ($item) {
+ return !in_array($item, ['.', '..']);
+ });
+
+ natsort($screenshots);
+ return $this->render(
+ 'gallery/index.html.twig',
+ ['screenshots' => $screenshots]
+ );
+ }
+}
diff --git a/src/Controller/HomeController.php b/src/Controller/HomeController.php
new file mode 100644
index 0000000..879b239
--- /dev/null
+++ b/src/Controller/HomeController.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class HomeController extends AbstractController
+{
+ #[Route('/', name: 'leaf_home')]
+ public function index(): Response
+ {
+ return $this->render('home/index.html.twig');
+ }
+}
diff --git a/src/Controller/WikiController.php b/src/Controller/WikiController.php
new file mode 100644
index 0000000..e8be874
--- /dev/null
+++ b/src/Controller/WikiController.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace App\Controller;
+
+use App\Enum\OtaFlavor;
+use App\Service\DeviceService;
+use App\Service\LeafOtaService;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class WikiController extends AbstractController {
+ #[Route('/wiki', name: 'leaf_wiki')]
+ public function index(DeviceService $deviceService): Response {
+ return $this->render(
+ 'wiki/index.html.twig',
+ [
+ 'showSidenav' => true,
+ 'availableDevices' => $deviceService->getAvailableDevices()
+ ]
+ );
+ }
+
+ #[Route('/wiki/{device}', name: 'leaf_device')]
+ public function device(DeviceService $deviceService, LeafOtaService $otaService, string $device): Response {
+ $latestBuilds = [
+ 'vanilla' => $otaService->getLatestBuildForDevice($device, OtaFlavor::Vanilla->value),
+ 'gms' => $otaService->getLatestBuildForDevice($device, OtaFlavor::Gms->value),
+ 'microg' => $otaService->getLatestBuildForDevice($device, OtaFlavor::microG->value)
+ ];
+
+ $latestOTAs = [
+ 'vanilla' => $otaService->getLatestOTAForDevice($device, OtaFlavor::Vanilla->value),
+ 'gms' => $otaService->getLatestOTAForDevice($device, OtaFlavor::Gms->value),
+ 'microg' => $otaService->getLatestOTAForDevice($device, OtaFlavor::microG->value)
+ ];
+
+ $allBuilds = $otaService->getAllBuildsForDevice($device);
+ $allOTAs = $otaService->getAllOTAsForDevice($device);
+
+ return $this->render(
+ 'wiki/device.html.twig',
+ [
+ 'showSidenav' => true,
+ 'availableDevices' => $deviceService->getAvailableDevices(),
+ 'device' => $deviceService->getDeviceInfo($device),
+ 'downloads' => [
+ 'latestBuilds' => $latestBuilds,
+ 'latestOTAs' => $latestOTAs,
+ 'previousBuilds' => $allBuilds,
+ 'previousOTAs' => $allOTAs
+ ]
+ ]
+ );
+ }
+}
diff --git a/src/Entity/LeafOta.php b/src/Entity/LeafOta.php
new file mode 100644
index 0000000..322be8d
--- /dev/null
+++ b/src/Entity/LeafOta.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\LeafOtaRepository;
+use DateTime;
+use Doctrine\DBAL\Types\Types;
+use Doctrine\ORM\Mapping as ORM;
+use Doctrine\ORM\Mapping\GeneratedValue;
+
+#[ORM\Entity(repositoryClass: LeafOtaRepository::class)]
+class LeafOta {
+ #[ORM\Column(length: 255)]
+ private ?string $device = null;
+
+ #[ORM\Column(type: Types::BIGINT)]
+ private ?int $datetime = null;
+
+ #[ORM\Column(length: 255)]
+ private ?string $filename = null;
+
+ #[ORM\Id]
+ #[ORM\Column(length: 255)]
+ #[GeneratedValue(strategy: 'IDENTITY')]
+ private ?string $id = null;
+
+ #[ORM\Column(length: 255)]
+ private ?string $romtype = null;
+
+ #[ORM\Column(type: Types::BIGINT)]
+ private ?string $size = null;
+
+ #[ORM\Column(length: 255)]
+ private ?string $url = null;
+
+ #[ORM\Column(length: 255)]
+ private ?string $version = null;
+
+ #[ORM\Column(length: 255)]
+ private ?string $flavor = null;
+
+ #[ORM\Column(length: 255)]
+ private ?string $incremental = null;
+
+ #[ORM\Column(length: 255, nullable: true)]
+ private ?string $incremental_base = null;
+
+ #[ORM\Column(length: 255, nullable: true)]
+ private ?string $upgrade = null;
+
+ public function getId(): ?string {
+ return $this->id;
+ }
+
+ public function getDevice(): ?string {
+ return $this->device;
+ }
+
+ public function setDevice(string $device): self {
+ $this->device = $device;
+
+ return $this;
+ }
+
+ public function getDatetime(): ?\DateTimeInterface {
+ $dateTime = new DateTime();
+ $dateTime->setTimestamp($this->datetime);
+ return $dateTime;
+ }
+
+ public function setDatetime(int $datetime): self {
+ $this->datetime = $datetime;
+
+ return $this;
+ }
+
+ public function getFilename(): ?string {
+ return $this->filename;
+ }
+
+ public function setFilename(string $filename): self {
+ $this->filename = $filename;
+
+ return $this;
+ }
+
+ public function getRomtype(): ?string {
+ return $this->romtype;
+ }
+
+ public function setRomtype(string $romtype): self {
+ $this->romtype = $romtype;
+
+ return $this;
+ }
+
+ public function getSize(): ?string {
+ return $this->size;
+ }
+
+ public function setSize(string $size): self {
+ $this->size = $size;
+
+ return $this;
+ }
+
+ public function getUrl(): ?string {
+ return $this->url;
+ }
+
+ public function setUrl(string $url): self {
+ $this->url = $url;
+
+ return $this;
+ }
+
+ public function getVersion(): ?string {
+ return $this->version;
+ }
+
+ public function setVersion(string $version): self {
+ $this->version = $version;
+
+ return $this;
+ }
+
+ public function getFlavor(): ?string {
+ return $this->flavor;
+ }
+
+ public function setFlavor(string $flavor): self {
+ $this->flavor = $flavor;
+
+ return $this;
+ }
+
+ public function getIncremental(): ?string {
+ return $this->incremental;
+ }
+
+ public function setIncremental(string $incremental): self {
+ $this->incremental = $incremental;
+
+ return $this;
+ }
+
+ public function getIncrementalBase(): ?string {
+ return $this->incremental_base;
+ }
+
+ public function setIncrementalBase(string $incremental_base): self {
+ $this->incremental_base = $incremental_base;
+
+ return $this;
+ }
+
+ public function getUpgrade(): ?string {
+ return $this->upgrade;
+ }
+
+ public function setUpgrade(?string $upgrade): self {
+ $this->upgrade = $upgrade;
+
+ return $this;
+ }
+}
diff --git a/src/Enum/OtaFlavor.php b/src/Enum/OtaFlavor.php
new file mode 100644
index 0000000..f0c4956
--- /dev/null
+++ b/src/Enum/OtaFlavor.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace App\Enum;
+
+enum OtaFlavor: string {
+ case Vanilla = 'vanilla';
+ case Gms = 'gms';
+ case microG = 'microg';
+}
diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php
new file mode 100644
index 0000000..9dc812f
--- /dev/null
+++ b/src/EventListener/ExceptionListener.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace App\EventListener;
+
+use App\Exception\DeviceNotFoundException;
+use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\ExceptionEvent;
+use Twig\Environment;
+
+#[AsEventListener(event: 'kernel.exception', method: 'onKernelException')]
+final class ExceptionListener {
+
+ public function __construct(
+ private Environment $twig
+ ) {
+ }
+
+ public function onKernelException(ExceptionEvent $event) {
+ $throwable = $event->getThrowable();
+ $throwableClass = get_class($throwable);
+
+ switch ($throwableClass) {
+ case DeviceNotFoundException::class:
+ $html = $this->twig->render('errors/404.html.twig', [
+ 'subject' => 'device',
+ 'message' => $throwable->getMessage()
+ ]);
+ $response = new Response();
+ $response->setContent($html);
+
+ $event->setResponse($response);
+ break;
+ }
+ }
+}
diff --git a/src/Exception/DeviceNotFoundException.php b/src/Exception/DeviceNotFoundException.php
new file mode 100644
index 0000000..0b2355e
--- /dev/null
+++ b/src/Exception/DeviceNotFoundException.php
@@ -0,0 +1,5 @@
+<?php
+
+namespace App\Exception;
+
+class DeviceNotFoundException extends \Exception {};
\ No newline at end of file
diff --git a/src/Kernel.php b/src/Kernel.php
new file mode 100644
index 0000000..779cd1f
--- /dev/null
+++ b/src/Kernel.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace App;
+
+use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
+use Symfony\Component\HttpKernel\Kernel as BaseKernel;
+
+class Kernel extends BaseKernel
+{
+ use MicroKernelTrait;
+}
diff --git a/src/Repository/.gitignore b/src/Repository/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/Repository/.gitignore
diff --git a/src/Repository/LeafOtaRepository.php b/src/Repository/LeafOtaRepository.php
new file mode 100644
index 0000000..4755d79
--- /dev/null
+++ b/src/Repository/LeafOtaRepository.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\LeafOta;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @extends ServiceEntityRepository<LeafOta>
+ *
+ * @method LeafOta|null find($id, $lockMode = null, $lockVersion = null)
+ * @method LeafOta|null findOneBy(array $criteria, array $orderBy = null)
+ * @method LeafOta[] findAll()
+ * @method LeafOta[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+class LeafOtaRepository extends ServiceEntityRepository {
+ public function __construct(ManagerRegistry $registry) {
+ parent::__construct($registry, LeafOta::class);
+ }
+
+ public function save(LeafOta $entity, bool $flush = false): void {
+ $this->getEntityManager()->persist($entity);
+
+ if ($flush) {
+ $this->getEntityManager()->flush();
+ }
+ }
+
+ public function remove(LeafOta $entity, bool $flush = false): void {
+ $this->getEntityManager()->remove($entity);
+
+ if ($flush) {
+ $this->getEntityManager()->flush();
+ }
+ }
+
+ /**
+ * Queries the database for the latest full build
+ *
+ * @param string $device The device to query - required
+ * @param string $flavor The flavor to query - optional
+ *
+ * @return LeafOta|null The build information, if any
+ */
+ public function getLatestBuildForDevice(string $device, string $flavor = ''): ?LeafOta {
+ $q = $this->createQueryBuilder('ota');
+
+ $q->where('ota.device = :device')
+ ->setParameter('device', $device)
+ ->andWhere('ota.incremental_base IS NULL')
+ ->orderBy('ota.datetime', 'DESC');
+
+ if (!empty($flavor)) {
+ $q->andWhere('ota.flavor = :flavor')
+ ->setParameter('flavor', $flavor);
+ }
+
+ return $q
+ ->setMaxResults(1)
+ ->getQuery()
+ ->getOneOrNullResult();
+ }
+
+ public function getLatestOTAForDevice(string $device, string $flavor = ''): ?LeafOta {
+ $q = $this->createQueryBuilder('ota');
+
+ $q->where('ota.device = :device')
+ ->setParameter('device', $device)
+ ->andWhere('ota.incremental_base IS NOT NULL')
+ ->orderBy('ota.datetime', 'DESC');
+
+ if (!empty($flavor)) {
+ $q->andWhere('ota.flavor = :flavor')
+ ->setParameter('flavor', $flavor);
+ }
+
+ return $q->setMaxResults(1)
+ ->getQuery()
+ ->getOneOrNullResult();
+ }
+
+ public function getAllBuildsForDevice(string $device, string $flavor = ''): array {
+ $q = $this->createQueryBuilder('ota');
+
+ $q->where('ota.device = :device')
+ ->setParameter('device', $device)
+ ->andWhere('ota.incremental_base IS NULL')
+ ->orderBy('ota.datetime', 'DESC');
+
+ if (!empty($flavor)) {
+ $q->andWhere('ota.flavor = :flavor')
+ ->setParameter('flavor', $flavor);
+ }
+
+ return $q->getQuery()
+ ->getResult();
+ }
+
+ public function getAllOTAsForDevice(string $device, string $flavor = ''): array {
+ $q = $this->createQueryBuilder('ota');
+
+ $q->where('ota.device = :device')
+ ->setParameter('device', $device)
+ ->andWhere('ota.incremental_base IS NOT NULL')
+ ->orderBy('ota.datetime', 'DESC');
+
+ if (!empty($flavor)) {
+ $q->andWhere('ota.flavor = :flavor')
+ ->setParameter('flavor', $flavor);
+ }
+
+ return $q->getQuery()
+ ->getResult();
+ }
+}
diff --git a/src/Service/DeviceService.php b/src/Service/DeviceService.php
new file mode 100644
index 0000000..9d9af13
--- /dev/null
+++ b/src/Service/DeviceService.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Service;
+
+use App\Exception\DeviceNotFoundException;
+use Symfony\Component\DependencyInjection\Attribute\Autowire;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Yaml\Yaml;
+
+class DeviceService {
+ private string $devicesDirectory;
+
+ public function __construct(
+ #[Autowire(service: 'service_container')] ContainerInterface $container
+ ) {
+ $this->devicesDirectory = $container->getParameter('devices_dir');
+ }
+
+ public function getAvailableDevices(): array {
+ $availableDevices = scandir($this->devicesDirectory);
+
+ return array_filter(array_map(function (string $deviceYaml) {
+ if (!in_array($deviceYaml, ['..', '.'])) {
+ return Yaml::parseFile($this->devicesDirectory . $deviceYaml);
+ }
+ }, $availableDevices));
+ }
+
+ public function getDeviceInfo(string $device) {
+ $file = $this->devicesDirectory . $device . '.yml';
+
+ if (is_file($file)) {
+ return Yaml::parseFile($file);
+ } else {
+ throw new DeviceNotFoundException("The device \"" . $device . "\" doesn't exist.");
+ }
+ }
+}
diff --git a/src/Service/LeafOtaService.php b/src/Service/LeafOtaService.php
new file mode 100644
index 0000000..278bb2c
--- /dev/null
+++ b/src/Service/LeafOtaService.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Service;
+
+use App\Entity\LeafOta;
+use App\Repository\LeafOtaRepository;
+use DateTime;
+
+class LeafOtaService {
+ public function __construct(
+ private LeafOtaRepository $repository
+ ) {}
+
+ public function getLatestBuildForDevice(string $device, string $flavor = ''): ?LeafOta {
+ return $this->repository->getLatestBuildForDevice($device, $flavor);
+ }
+
+ public function getLatestOTAForDevice(string $device, string $flavor = ''): ?LeafOta {
+ return $this->repository->getLatestOTAForDevice($device, $flavor);
+ }
+
+ public function getAllBuildsForDevice(string $device, string $flavor = ''): array {
+ return $this->repository->getAllBuildsForDevice($device, $flavor);
+ }
+
+ public function getAllOTAsForDevice(string $device, string $flavor = ''): array {
+ return $this->repository->getAllOTAsForDevice($device, $flavor);
+ }
+}
\ No newline at end of file
diff --git a/src/Twig/Extension/FilesizeExtension.php b/src/Twig/Extension/FilesizeExtension.php
new file mode 100644
index 0000000..b503346
--- /dev/null
+++ b/src/Twig/Extension/FilesizeExtension.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Twig\Extension;
+
+use App\Twig\Runtime\FilesizeExtensionRuntime;
+use Twig\Extension\AbstractExtension;
+use Twig\TwigFilter;
+use Twig\TwigFunction;
+
+class FilesizeExtension extends AbstractExtension {
+ public function getFilters(): array {
+ return [
+ new TwigFilter(
+ 'human_readable_format',
+ [FilesizeExtensionRuntime::class, 'humanReadableFormat'],
+ ['is_safe' => ['html']]
+ ),
+ ];
+ }
+
+ public function getFunctions(): array {
+ return [
+ new TwigFunction(
+ 'human_readable_format',
+ [FilesizeExtensionRuntime::class, 'humanReadableFormat'],
+ ['is_safe' => ['html']]
+ ),
+ ];
+ }
+}
diff --git a/src/Twig/Runtime/FilesizeExtensionRuntime.php b/src/Twig/Runtime/FilesizeExtensionRuntime.php
new file mode 100644
index 0000000..b053ca0
--- /dev/null
+++ b/src/Twig/Runtime/FilesizeExtensionRuntime.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace App\Twig\Runtime;
+
+use App\Util\Filesize;
+use Twig\Extension\RuntimeExtensionInterface;
+
+class FilesizeExtensionRuntime implements RuntimeExtensionInterface {
+ public function humanReadableFormat($value) {
+ return Filesize::humanReadableFormat((int)$value);
+ }
+}
diff --git a/src/Util/Filesize.php b/src/Util/Filesize.php
new file mode 100644
index 0000000..958c98c
--- /dev/null
+++ b/src/Util/Filesize.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Util;
+
+class Filesize {
+ public static function humanReadableFormat(int $filesize): string {
+ $units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB'];
+ $power = ($filesize > 0) ? floor(log($filesize, 1024)) : 0;
+
+ return sprintf(
+ '%01.2f %s',
+ $filesize / pow(1024, $power),
+ $units[$power]
+ );
+ }
+}
diff --git a/symfony.lock b/symfony.lock
new file mode 100644
index 0000000..0d84cb5
--- /dev/null
+++ b/symfony.lock
@@ -0,0 +1,110 @@
+{
+ "doctrine/doctrine-bundle": {
+ "version": "2.9",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "2.8",
+ "ref": "6b43b7b6ff6bf2551f2933ebeb66721fa3db8fbc"
+ },
+ "files": [
+ "./config/packages/doctrine.yaml",
+ "./src/Entity/.gitignore",
+ "./src/Repository/.gitignore"
+ ]
+ },
+ "doctrine/doctrine-migrations-bundle": {
+ "version": "3.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "3.1",
+ "ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
+ },
+ "files": [
+ "./config/packages/doctrine_migrations.yaml",
+ "./migrations/.gitignore"
+ ]
+ },
+ "symfony/console": {
+ "version": "6.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "5.3",
+ "ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
+ },
+ "files": [
+ "./bin/console"
+ ]
+ },
+ "symfony/flex": {
+ "version": "2.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "1.0",
+ "ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
+ },
+ "files": [
+ "./.env"
+ ]
+ },
+ "symfony/framework-bundle": {
+ "version": "6.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "6.2",
+ "ref": "af47254c5e4cd543e6af3e4508298ffebbdaddd3"
+ },
+ "files": [
+ "./config/packages/cache.yaml",
+ "./config/packages/framework.yaml",
+ "./config/preload.php",
+ "./config/routes/framework.yaml",
+ "./config/services.yaml",
+ "./public/index.php",
+ "./src/Controller/.gitignore",
+ "./src/Kernel.php"
+ ]
+ },
+ "symfony/maker-bundle": {
+ "version": "1.48",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "1.0",
+ "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
+ }
+ },
+ "symfony/routing": {
+ "version": "6.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "6.2",
+ "ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6"
+ },
+ "files": [
+ "./config/packages/routing.yaml",
+ "./config/routes.yaml"
+ ]
+ },
+ "symfony/twig-bundle": {
+ "version": "6.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "5.4",
+ "ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
+ },
+ "files": [
+ "./config/packages/twig.yaml",
+ "./templates/base.html.twig"
+ ]
+ },
+ "twig/extra-bundle": {
+ "version": "v3.5.1"
+ }
+}
diff --git a/templates/about/index.html.twig b/templates/about/index.html.twig
new file mode 100644
index 0000000..d2d37d2
--- /dev/null
+++ b/templates/about/index.html.twig
@@ -0,0 +1,15 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}
+ About LeafOS
+{% endblock %}
+
+{% block body %}
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>About</h1>
+ </div>
+ </div>
+ </div>
+{% endblock %}
diff --git a/templates/base.html.twig b/templates/base.html.twig
new file mode 100644
index 0000000..c312687
--- /dev/null
+++ b/templates/base.html.twig
@@ -0,0 +1,21 @@
+{% set route = app.request.attributes.get('_route') %}
+{% set showSidenav = showSidenav|default(false) %}
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <title>{% block title %}Welcome!{% endblock %}</title>
+ {# Favicon same as navbar logo #}
+ <link rel="icon" href="data:image/svg+xml, %3Csvg id='vector' xmlns='http://www.w3.org/2000/svg' height='30px' viewBox='0 0 140.2 76.8'%3E%3Cpath fill='%2390ee90' d='M28.88 31.84C35.54 40 45.19 48.78 51 58.5c5.14 10.73 14.22 25.34 -3.33 13.65 -13.43 -6.58 -29.21 -10 -38.22 -22.22C0.3 42.26 -2.77 -3.82 2.74 0.25 24.46 11 48 9.35 60.23 23.48a40.75 40.75 0 0 1 8.15 14.85c2.81 7.88 5.2 -7.21 7.53 -9.22C79.66 22.69 85.58 18 92.06 14.8c14.06 -5.15 29.14 -7 42.88 -13.31 2.26 -1 4.25 -1.55 4.8 -0.43 1.28 18.32 0.77 39.76 -12.86 53.37C114.91 65.51 98 67.91 84.12 76.7c-3.83 1 -0.62 -5.45 0.17 -8 5.56 -16 17.39 -24.86 29.34 -37.27C85.69 39.75 77.73 81 73.41 67.29c-1.25 -2 -0.53 -7.12 -3.5 -7.3 -3.17 0.58 -2.27 13.27 -8.27 7.83C53.88 54 43.86 37.9 28.88 31.84Z' id='path_0'%3E%3C/path%3E%3C/svg%3E">
+ {# Site CSS #}
+ <link rel="stylesheet" href="{{ asset('assets/app.css') }}">
+ <link rel="stylesheet" href="{{ asset('assets/navbar.css') }}">
+ {% block page_css %}
+ {% endblock %}
+ </head>
+ <body>
+ {% include '@components/navbar.html.twig' %}
+ {% block body %}{% endblock %}
+ {% include '@components/footer.html.twig' %}
+ </body>
+</html>
diff --git a/templates/community/index.html.twig b/templates/community/index.html.twig
new file mode 100644
index 0000000..786ef23
--- /dev/null
+++ b/templates/community/index.html.twig
@@ -0,0 +1,42 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}
+ LeafOS Community
+{% endblock %}
+
+{% block body %}
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>Community</h1>
+ <p>Whether you're an experienced Android user or you're just getting started with open-source software, there are lots of ways to get involved with the LeafOS community.</p>
+ </div>
+ </div>
+
+ <div class="container">
+ <h2>Contribute</h2>
+ <div class="row">
+ <div class="col-sm-6">
+ <h3><a href="https://review.leafos.org" target="_blank" class="community">Gerrit</a></h3>
+ <p>Gerrit is a web based code review system, facilitating online code reviews for projects using the Git version control system.</p>
+ </div>
+ <div class="col-sm-6">
+ <h3><a href="{{ path('leaf_wiki') }}" target="_blank" class="community">Wiki</a></h3>
+ <p>Our wiki is always looking for editors. If you enjoy writing clear and concise guides, tutorials, or documentation we need you!</p>
+ </div>
+ <div class="col-sm-6">
+ <h3><a href="https://translate.leafos.org" target="_blank" class="community">Translate</a></h3>
+ <p>Help people enjoy LeafOS in their native language by localizing it. Anyone can easily contribute thanks to Weblate.</p>
+ </div>
+ </div>
+
+ <h2>Support</h2>
+ <div class="row">
+ <div class="col-sm-6">
+ <h3><a href="https://t.me/leafos" target="_blank" class="community">Telegram</a></h3>
+ <p>For discussions regarding devices, features, or just general Android talk.</p>
+ </div>
+ </div>
+ </div>
+ </div>
+{% endblock %}
diff --git a/templates/errors/404.html.twig b/templates/errors/404.html.twig
new file mode 100644
index 0000000..bd9badf
--- /dev/null
+++ b/templates/errors/404.html.twig
@@ -0,0 +1,16 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}
+ LeafOS 404 - {{ subject|capitalize }} not found.
+{% endblock %}
+
+{% block body %}
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>404 - {{ subject|capitalize }} not found!</h1>
+ <p>{{ message }}</p>
+ </div>
+ </div>
+ </div>
+{% endblock %}
diff --git a/templates/gallery/index.html.twig b/templates/gallery/index.html.twig
new file mode 100644
index 0000000..66ca665
--- /dev/null
+++ b/templates/gallery/index.html.twig
@@ -0,0 +1,24 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}
+ LeafOS Gallery
+{% endblock %}
+
+{% block page_css %}
+ <link rel="stylesheet" href="{{ asset('assets/gallery.css') }}" />
+{% endblock %}
+
+{% block body %}
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>ROM Gallery</h1>
+ </div>
+ </div>
+ <div class="grid">
+ {% for screenshot in screenshots %}
+ <img src="{{ asset('assets/images/screenshots/' ~ screenshot) }}" alt="Screenshot" />
+ {% endfor %}
+ </div>
+ </div>
+{% endblock %}
diff --git a/templates/home/index.html.twig b/templates/home/index.html.twig
new file mode 100644
index 0000000..c8656a6
--- /dev/null
+++ b/templates/home/index.html.twig
@@ -0,0 +1,17 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}
+ LeafOS ROM
+{% endblock %}
+
+{% block body %}
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>Welcome to the LeafOS!</h1>
+ <p>LeafOS is an AOSP-based ROM, focused on stability.</p>
+ <a href="{{ path('leaf_wiki')}}" class="get-leaf">Get LeafOS</a>
+ </div>
+ </div>
+ </div>
+{% endblock %}
diff --git a/templates/wiki/device.html.twig b/templates/wiki/device.html.twig
new file mode 100644
index 0000000..bd85fc2
--- /dev/null
+++ b/templates/wiki/device.html.twig
@@ -0,0 +1,170 @@
+{% extends 'base.html.twig' %}
+
+{% set currentDevice = app.request.attributes.get('_route_params').device %}
+
+{% block title %}
+ LeafOS Wiki
+{% endblock %}
+
+{% block page_css %}
+ <link rel="stylesheet" href="{{ asset('assets/wiki.css') }}" />
+{% endblock %}
+
+{% block body %}
+ <div class="sidenav">
+ <h2>Devices</h2>
+
+ {% for device in availableDevices %}
+ <a href="{{ path('leaf_device', { device: device.codename }) }}" class="{{ currentDevice == device.codename ? 'active' : '' }}">{{ device.codename }}</a>
+ {% endfor %}
+ </div>
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>LeafOS for {{ device.codename }}</h1>
+ </div>
+ </div>
+
+ <div class="container">
+ <div class="device-info">
+ <div class="instructions">
+ <h2>Downloads</h2>
+ {% for build in downloads.latestBuilds %}
+ <div class="build-card">
+ <div class="title">{{ build.filename }}</div>
+ <div class="build-info">
+ <table>
+ <tbody>
+ <tr>
+ <td>Build Date</td>
+ <td>{{ build.datetime|date('d/m/Y') }}</td>
+ <td>Flavor</td>
+ <td>{{ build.flavor }}</td>
+ </tr>
+ <tr>
+ <td>LeafOS Version</td>
+ <td>{{ build.version }}</td>
+ <td>File size</td>
+ <td>{{ build.size|human_readable_format }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+ <div class="specs">
+ <div class="heading">
+ <h2>{{ device.vendor }} {{ device.name }}</h2>
+ <p>Released {{ device.release|date('d/m/Y') }}</p>
+ </div>
+ <img src="{{ asset('assets/images/devices/' ~ device.image) }}" alt="{{ device.name }}" />
+ <table>
+ <tbody>
+ <tr>
+ <td>
+ <b>SoC</b>
+ </td>
+ <td>{{ device.soc }} ({{ device.architecture }})</td>
+ </tr>
+ <tr>
+ <td>
+ <b>CPU</b>
+ </td>
+ <td>
+ <p>{{ device.cpu_cores }} cores {{ device.cpu }}</p>
+ <p>{{ device.cpu_freq }}</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>GPU</b>
+ </td>
+ <td>{{ device.gpu }}</td>
+ </tr>
+ <tr>
+ <td>
+ <b>RAM</b>
+ </td>
+ <td>{{ device.ram }}</td>
+ </tr>
+ <tr>
+ <td>
+ <b>Storage</b>
+ </td>
+ <td>
+ <p>{{ device.storage }}</p>
+ {% if device.sdcard is defined %}
+ <p>SD card slot up to {{ device.sdcard.sizeMax }}</p>
+ {% endif %}
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Screen</b>
+ </td>
+ <td>
+ <ul>
+ <li>{{ device.screen.size }}</li>
+ <li>{{ device.screen.resolution }} ({{ device.screen.density }} PPI)</li>
+ <li>{{ device.screen.technology }}</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Battery</b>
+ </td>
+ <td colspan="2">{{ device.battery.removable ? 'Removable' : 'Non-removable' }}
+ {{ device.battery.tech }} {{ device.battery.capacity }} mAh</td>
+ </tr>
+ <tr>
+ <td>
+ <b>Cameras</b>
+ </td>
+ <td>
+ <ul>
+ {% for camera in device.cameras %}
+ <li>{{ camera.info }} {{ camera.flash != 'None' ? ', ' ~ camera.flash ~ ' flash' : '' }}</li>
+ {% endfor %}
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>Network</b>
+ </td>
+ <td>
+ <ul>
+ {% for network in device.network %}
+ <li>{{ network }}</li>
+ {% endfor %}
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <b>WiFi</b>
+ </td>
+ <td>{{ device.wifi }}</td>
+ </tr>
+ <tr>
+ <td>
+ <b>Bluetooth</b>
+ </td>
+ <td>
+ {{ device.bluetooth.spec }}
+ {% if device.bluetooth.profiles is defined and device.bluetooth.profiles is not empty %}
+ with{% for profile in device.bluetooth.profiles %}
+ {{ profile }}
+ {% endfor %}
+ {% endif %}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+{% endblock %}
diff --git a/templates/wiki/index.html.twig b/templates/wiki/index.html.twig
new file mode 100644
index 0000000..245a675
--- /dev/null
+++ b/templates/wiki/index.html.twig
@@ -0,0 +1,32 @@
+{% extends 'base.html.twig' %}
+
+{% block title %}
+ LeafOS Wiki
+{% endblock %}
+
+{% block page_css %}
+ <link rel="stylesheet" href="{{ asset('assets/wiki.css') }}" />
+{% endblock %}
+
+{% block body %}
+ <div class="sidenav">
+ <h2>Devices</h2>
+
+ <ul>
+ {% for device in availableDevices %}
+ <li>
+ <a href="{{ path('leaf_device', { device: device.codename }) }}">{{ device.codename }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+
+ <div class="content">
+ <div class="banner">
+ <div class="container">
+ <h1>Welcome to the LeafOS wiki!</h1>
+ <p>You can find various information, how-tos, build instructions and much more here in our wiki.</p>
+ </div>
+ </div>
+ </div>
+{% endblock %}