[
  {
    "path": ".gitattributes",
    "content": "/Tests export-ignore\n/phpunit.xml.dist export-ignore\n/.git* export-ignore\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Please do not submit any Pull Requests here. They will be closed.\n---\n\nPlease submit your PR here instead:\nhttps://github.com/symfony/symfony\n\nThis repository is what we call a \"subtree split\": a read-only subset of that main repository.\nWe're looking forward to your PR there!\n"
  },
  {
    "path": ".github/workflows/close-pull-request.yml",
    "content": "name: Close Pull Request\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  run:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: superbrothers/close-pull-request@v3\n      with:\n        comment: |\n          Thanks for your Pull Request! We love contributions.\n\n          However, you should instead open your PR on the main repository:\n          https://github.com/symfony/symfony\n\n          This repository is what we call a \"subtree split\": a read-only subset of that main repository.\n          We're looking forward to your PR there!\n"
  },
  {
    "path": ".gitignore",
    "content": "vendor/\ncomposer.lock\nphpunit.xml\n"
  },
  {
    "path": "Alias.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\n\nclass Alias\n{\n    private array $deprecation = [];\n\n    public function __construct(\n        private string $id,\n    ) {\n    }\n\n    public function withId(string $id): static\n    {\n        $new = clone $this;\n\n        $new->id = $id;\n\n        return $new;\n    }\n\n    /**\n     * Returns the target name of this alias.\n     *\n     * @return string The target name\n     */\n    public function getId(): string\n    {\n        return $this->id;\n    }\n\n    /**\n     * Whether this alias is deprecated, that means it should not be referenced anymore.\n     *\n     * @param string $package The name of the composer package that is triggering the deprecation\n     * @param string $version The version of the package that introduced the deprecation\n     * @param string $message The deprecation message to use\n     *\n     * @return $this\n     *\n     * @throws InvalidArgumentException when the message template is invalid\n     */\n    public function setDeprecated(string $package, string $version, string $message): static\n    {\n        if ('' !== $message) {\n            if (preg_match('#[\\r\\n]|\\*/#', $message)) {\n                throw new InvalidArgumentException('Invalid characters found in deprecation template.');\n            }\n\n            if (!str_contains($message, '%alias_id%')) {\n                throw new InvalidArgumentException('The deprecation template must contain the \"%alias_id%\" placeholder.');\n            }\n        }\n\n        $this->deprecation = [\n            'package' => $package,\n            'version' => $version,\n            'message' => $message ?: 'The \"%alias_id%\" route alias is deprecated. You should stop using it, as it will be removed in the future.',\n        ];\n\n        return $this;\n    }\n\n    public function isDeprecated(): bool\n    {\n        return (bool) $this->deprecation;\n    }\n\n    /**\n     * @param string $name Route name relying on this alias\n     */\n    public function getDeprecation(string $name): array\n    {\n        return [\n            'package' => $this->deprecation['package'],\n            'version' => $this->deprecation['version'],\n            'message' => str_replace('%alias_id%', $name, $this->deprecation['message']),\n        ];\n    }\n}\n"
  },
  {
    "path": "Attribute/DeprecatedAlias.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Attribute;\n\n/**\n * This class is meant to be used in {@see Route} to define an alias for a route.\n */\nclass DeprecatedAlias\n{\n    public function __construct(\n        public readonly string $aliasName,\n        public readonly string $package,\n        public readonly string $version,\n        public readonly string $message = '',\n    ) {\n    }\n}\n"
  },
  {
    "path": "Attribute/Route.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Attribute;\n\n/**\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Alexander M. Turek <me@derrabus.de>\n */\n#[\\Attribute(\\Attribute::IS_REPEATABLE | \\Attribute::TARGET_CLASS | \\Attribute::TARGET_METHOD)]\nclass Route\n{\n    /** @var string[] */\n    public array $methods;\n\n    /** @var string[] */\n    public array $envs;\n\n    /** @var string[] */\n    public array $schemes;\n\n    /** @var (string|DeprecatedAlias)[] */\n    public array $aliases = [];\n\n    /**\n     * @param string|array<string,string>|null                  $path         The route path (i.e. \"/user/login\")\n     * @param string|null                                       $name         The route name (i.e. \"app_user_login\")\n     * @param array<string|\\Stringable>                         $requirements Requirements for the route attributes, @see https://symfony.com/doc/current/routing.html#parameters-validation\n     * @param array<string, mixed>                              $options      Options for the route (i.e. ['prefix' => '/api'])\n     * @param array<string, mixed>                              $defaults     Default values for the route attributes and query parameters\n     * @param string|null                                       $host         The host for which this route should be active (i.e. \"localhost\")\n     * @param string|string[]                                   $methods      The list of HTTP methods allowed by this route\n     * @param string|string[]                                   $schemes      The list of schemes allowed by this route (i.e. \"https\")\n     * @param string|null                                       $condition    An expression that must evaluate to true for the route to be matched, @see https://symfony.com/doc/current/routing.html#matching-expressions\n     * @param int|null                                          $priority     The priority of the route if multiple ones are defined for the same path\n     * @param string|null                                       $locale       The locale accepted by the route\n     * @param string|null                                       $format       The format returned by the route (i.e. \"json\", \"xml\")\n     * @param bool|null                                         $utf8         Whether the route accepts UTF-8 in its parameters\n     * @param bool|null                                         $stateless    Whether the route is defined as stateless or stateful, @see https://symfony.com/doc/current/routing.html#stateless-routes\n     * @param string|string[]|null                              $env          The env(s) in which the route is defined (i.e. \"dev\", \"test\", \"prod\", [\"dev\", \"test\"])\n     * @param string|DeprecatedAlias|(string|DeprecatedAlias)[] $alias        The list of aliases for this route\n     */\n    public function __construct(\n        public string|array|null $path = null,\n        public ?string $name = null,\n        public array $requirements = [],\n        public array $options = [],\n        public array $defaults = [],\n        public ?string $host = null,\n        array|string $methods = [],\n        array|string $schemes = [],\n        public ?string $condition = null,\n        public ?int $priority = null,\n        ?string $locale = null,\n        ?string $format = null,\n        ?bool $utf8 = null,\n        ?bool $stateless = null,\n        string|array|null $env = null,\n        string|DeprecatedAlias|array $alias = [],\n    ) {\n        $this->path = $path;\n        $this->methods = (array) $methods;\n        $this->schemes = (array) $schemes;\n        $this->envs = (array) $env;\n        $this->aliases = \\is_array($alias) ? $alias : [$alias];\n\n        if (null !== $locale) {\n            $this->defaults['_locale'] = $locale;\n        }\n\n        if (null !== $format) {\n            $this->defaults['_format'] = $format;\n        }\n\n        if (null !== $utf8) {\n            $this->options['utf8'] = $utf8;\n        }\n\n        if (null !== $stateless) {\n            $this->defaults['_stateless'] = $stateless;\n        }\n    }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "CHANGELOG\n=========\n\n8.0\n---\n\n * Remove support for accessing the internal scope of the loader in PHP config files, use only its public API instead\n * Providing a non-array `_query` parameter to `UrlGenerator` causes an `InvalidParameterException`\n * Remove the protected `AttributeClassLoader::$routeAnnotationClass` property and the `setRouteAnnotationClass()` method, use `AttributeClassLoader::setRouteAttributeClass()` instead\n * Remove class aliases in the `Annotation` namespace, use attributes instead\n * Remove getters and setters in attribute classes in favor of public properties\n * Remove support for the XML configuration format\n\n7.4\n---\n\n * Add `AttributeServicesLoader` and `RoutingControllerPass` to auto-register routes from attributes on services\n * Allow query-specific parameters in `UrlGenerator` using `_query`\n * Add support of multiple env names in the  `Symfony\\Component\\Routing\\Attribute\\Route` attribute\n * Add argument `$parameters` to `RequestContext`'s constructor\n * Handle declaring routes using PHP arrays that follow the same shape as corresponding yaml files\n * Add `RoutesReference` to help writing PHP configs using yaml-like array-shapes\n * Deprecate class aliases in the `Annotation` namespace, use attributes instead\n * Deprecate getters and setters in attribute classes in favor of public properties\n * Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead\n * Deprecate XML configuration format, use YAML, PHP or attributes instead\n\n7.3\n---\n\n * Allow aliases and deprecations in `#[Route]` attribute\n * Add the `Requirement::MONGODB_ID` constant to validate MongoDB ObjectIDs in hexadecimal format\n\n7.2\n---\n\n * Add the `Requirement::UID_RFC9562` constant to validate UUIDs in the RFC 9562 format\n * Deprecate the `AttributeClassLoader::$routeAnnotationClass` property\n\n7.1\n---\n\n * Add `{foo:bar}` syntax to define a mapping between a route parameter and its corresponding request attribute\n\n7.0\n---\n\n * Add argument `$routeParameters` to `UrlMatcher::handleRouteRequirements()`\n * Remove Doctrine annotations support in favor of native attributes\n * Remove `AnnotationClassLoader`, use `AttributeClassLoader` instead\n * Remove `AnnotationDirectoryLoader`, use `AttributeDirectoryLoader` instead\n * Remove `AnnotationFileLoader`, use `AttributeFileLoader` instead\n\n6.4\n---\n\n * Add FQCN and FQCN::method aliases for routes loaded from attributes/annotations when applicable\n * Add native return type to `AnnotationClassLoader::setResolver()`\n * Deprecate Doctrine annotations support in favor of native attributes\n * Change the constructor signature of `AnnotationClassLoader` to `__construct(?string $env = null)`, passing an annotation reader as first argument is deprecated\n * Deprecate `AnnotationClassLoader`, use `AttributeClassLoader` instead\n * Deprecate `AnnotationDirectoryLoader`, use `AttributeDirectoryLoader` instead\n * Deprecate `AnnotationFileLoader`, use `AttributeFileLoader` instead\n * Add `AddExpressionLanguageProvidersPass` (moved from `FrameworkBundle`)\n * Add aliases for all classes in the `Annotation` namespace to `Attribute`\n\n6.2\n---\n\n * Add `Requirement::POSITIVE_INT` for common ids and pagination\n\n6.1\n---\n\n * Add `getMissingParameters` and `getRouteName` methods on `MissingMandatoryParametersException`\n * Allow using UTF-8 parameter names\n * Support the `attribute` type (alias of `annotation`) in annotation loaders\n * Already encoded slashes are not decoded nor double-encoded anymore when generating URLs (query parameters)\n * Add `EnumRequirement` to help generate route requirements from a `\\BackedEnum`\n * Add `Requirement`, a collection of universal regular-expression constants to use as route parameter requirements\n * Add `params` variable to condition expression\n * Deprecate not passing route parameters as the fourth argument to `UrlMatcher::handleRouteRequirements()`\n\n5.3\n---\n\n * Already encoded slashes are not decoded nor double-encoded anymore when generating URLs\n * Add support for per-env configuration in XML and Yaml loaders\n * Deprecate creating instances of the `Route` annotation class by passing an array of parameters\n * Add `RoutingConfigurator::env()` to get the current environment\n\n5.2.0\n-----\n\n * Added support for inline definition of requirements and defaults for host\n * Added support for `\\A` and `\\z` as regex start and end for route requirement\n * Added support for `#[Route]` attributes\n\n5.1.0\n-----\n\n * added the protected method `PhpFileLoader::callConfigurator()` as extension point to ease custom routing configuration\n * deprecated `RouteCollectionBuilder` in favor of `RoutingConfigurator`.\n * added \"priority\" option to annotated routes\n * added argument `$priority` to `RouteCollection::add()`\n * deprecated the `RouteCompiler::REGEX_DELIMITER` constant\n * added `ExpressionLanguageProvider` to expose extra functions to route conditions\n * added support for a `stateless` keyword for configuring route stateless in PHP, YAML and XML configurations.\n * added the \"hosts\" option to be able to configure the host per locale.\n * added `RequestContext::fromUri()` to ease building the default context\n\n5.0.0\n-----\n\n * removed `PhpGeneratorDumper` and `PhpMatcherDumper`\n * removed `generator_base_class`, `generator_cache_class`, `matcher_base_class` and `matcher_cache_class` router options\n * `Serializable` implementing methods for `Route` and `CompiledRoute` are final\n * removed referencing service route loaders with a single colon\n * Removed `ServiceRouterLoader` and `ObjectRouteLoader`.\n\n4.4.0\n-----\n\n * Deprecated `ServiceRouterLoader` in favor of `ContainerLoader`.\n * Deprecated `ObjectRouteLoader` in favor of `ObjectLoader`.\n * Added a way to exclude patterns of resources from being imported by the `import()` method\n\n4.3.0\n-----\n\n * added `CompiledUrlMatcher` and `CompiledUrlMatcherDumper`\n * added `CompiledUrlGenerator` and `CompiledUrlGeneratorDumper`\n * deprecated `PhpGeneratorDumper` and `PhpMatcherDumper`\n * deprecated `generator_base_class`, `generator_cache_class`, `matcher_base_class` and `matcher_cache_class` router options\n * `Serializable` implementing methods for `Route` and `CompiledRoute` are marked as `@internal` and `@final`.\n   Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible\n   with the new serialization methods in PHP 7.4.\n * exposed `utf8` Route option, defaults \"locale\" and \"format\" in configuration loaders and configurators\n * added support for invokable service route loaders\n\n4.2.0\n-----\n\n * added fallback to cultureless locale for internationalized routes\n\n4.0.0\n-----\n\n * dropped support for using UTF-8 route patterns without using the `utf8` option\n * dropped support for using UTF-8 route requirements without using the `utf8` option\n\n3.4.0\n-----\n\n * Added `NoConfigurationException`.\n * Added the possibility to define a prefix for all routes of a controller via @Route(name=\"prefix_\")\n * Added support for prioritized routing loaders.\n * Add matched and default parameters to redirect responses\n * Added support for a `controller` keyword for configuring route controllers in YAML and XML configurations.\n\n3.3.0\n-----\n\n * [DEPRECATION] Class parameters have been deprecated and will be removed in 4.0.\n   * router.options.generator_class\n   * router.options.generator_base_class\n   * router.options.generator_dumper_class\n   * router.options.matcher_class\n   * router.options.matcher_base_class\n   * router.options.matcher_dumper_class\n   * router.options.matcher.cache_class\n   * router.options.generator.cache_class\n\n3.2.0\n-----\n\n * Added support for `bool`, `int`, `float`, `string`, `list` and `map` defaults in XML configurations.\n * Added support for UTF-8 requirements\n\n2.8.0\n-----\n\n * allowed specifying a directory to recursively load all routing configuration files it contains\n * Added ObjectRouteLoader and ServiceRouteLoader that allow routes to be loaded\n   by calling a method on an object/service.\n * [DEPRECATION] Deprecated the hardcoded value for the `$referenceType` argument of the `UrlGeneratorInterface::generate` method.\n   Use the constants defined in the `UrlGeneratorInterface` instead.\n\n   Before:\n\n   ```php\n   $router->generate('blog_show', ['slug' => 'my-blog-post'], true);\n   ```\n\n   After:\n\n   ```php\n   use Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\n\n   $router->generate('blog_show', ['slug' => 'my-blog-post'], UrlGeneratorInterface::ABSOLUTE_URL);\n   ```\n\n2.5.0\n-----\n\n * [DEPRECATION] The `ApacheMatcherDumper` and `ApacheUrlMatcher` were deprecated and\n   will be removed in Symfony 3.0, since the performance gains were minimal and\n   it's hard to replicate the behavior of PHP implementation.\n\n2.3.0\n-----\n\n * added RequestContext::getQueryString()\n\n2.2.0\n-----\n\n * [DEPRECATION] Several route settings have been renamed (the old ones will be removed in 3.0):\n\n    * The `pattern` setting for a route has been deprecated in favor of `path`\n    * The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings\n\n   Before:\n\n   ```yaml\n   article_edit:\n       pattern: /article/{id}\n       requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\\d+' }\n   ```\n\n   ```xml\n   <route id=\"article_edit\" pattern=\"/article/{id}\">\n       <requirement key=\"_method\">POST|PUT</requirement>\n       <requirement key=\"_scheme\">https</requirement>\n       <requirement key=\"id\">\\d+</requirement>\n   </route>\n   ```\n\n   ```php\n   $route = new Route();\n   $route->setPattern('/article/{id}');\n   $route->setRequirement('_method', 'POST|PUT');\n   $route->setRequirement('_scheme', 'https');\n   ```\n\n   After:\n\n   ```yaml\n   article_edit:\n       path: /article/{id}\n       methods: [POST, PUT]\n       schemes: https\n       requirements: { 'id': '\\d+' }\n   ```\n\n   ```xml\n   <route id=\"article_edit\" pattern=\"/article/{id}\" methods=\"POST PUT\" schemes=\"https\">\n       <requirement key=\"id\">\\d+</requirement>\n   </route>\n   ```\n\n   ```php\n   $route = new Route();\n   $route->setPath('/article/{id}');\n   $route->setMethods(['POST', 'PUT']);\n   $route->setSchemes('https');\n   ```\n\n * [BC BREAK] RouteCollection does not behave like a tree structure anymore but as\n   a flat array of Routes. So when using PHP to build the RouteCollection, you must\n   make sure to add routes to the sub-collection before adding it to the parent\n   collection (this is not relevant when using YAML or XML for Route definitions).\n\n   Before:\n\n   ```php\n   $rootCollection = new RouteCollection();\n   $subCollection = new RouteCollection();\n   $rootCollection->addCollection($subCollection);\n   $subCollection->add('foo', new Route('/foo'));\n   ```\n\n   After:\n\n   ```php\n   $rootCollection = new RouteCollection();\n   $subCollection = new RouteCollection();\n   $subCollection->add('foo', new Route('/foo'));\n   $rootCollection->addCollection($subCollection);\n   ```\n\n   Also one must call `addCollection` from the bottom to the top hierarchy.\n   So the correct sequence is the following (and not the reverse):\n\n   ```php\n   $childCollection->addCollection($grandchildCollection);\n   $rootCollection->addCollection($childCollection);\n   ```\n\n * [DEPRECATION] The methods `RouteCollection::getParent()` and `RouteCollection::getRoot()`\n   have been deprecated and will be removed in Symfony 2.3.\n * [BC BREAK] Misusing the `RouteCollection::addPrefix` method to add defaults, requirements\n   or options without adding a prefix is not supported anymore. So if you called `addPrefix`\n   with an empty prefix or `/` only (both have no relevance), like\n   `addPrefix('', $defaultsArray, $requirementsArray, $optionsArray)`\n   you need to use the new dedicated methods `addDefaults($defaultsArray)`,\n   `addRequirements($requirementsArray)` or `addOptions($optionsArray)` instead.\n * [DEPRECATION] The `$options` parameter to `RouteCollection::addPrefix()` has been deprecated\n   because adding options has nothing to do with adding a path prefix. If you want to add options\n   to all child routes of a RouteCollection, you can use `addOptions()`.\n * [DEPRECATION] The method `RouteCollection::getPrefix()` has been deprecated\n   because it suggested that all routes in the collection would have this prefix, which is\n   not necessarily true. On top of that, since there is no tree structure anymore, this method\n   is also useless. Don't worry about performance, prefix optimization for matching is still done\n   in the dumper, which was also improved in 2.2.0 to find even more grouping possibilities.\n * [DEPRECATION] `RouteCollection::addCollection(RouteCollection $collection)` should now only be\n   used with a single parameter. The other params `$prefix`, `$default`, `$requirements` and `$options`\n   will still work, but have been deprecated. The `addPrefix` method should be used for this\n   use-case instead.\n   Before: `$parentCollection->addCollection($collection, '/prefix', [...], [...])`\n   After:\n   ```php\n   $collection->addPrefix('/prefix', [...], [...]);\n   $parentCollection->addCollection($collection);\n   ```\n * added support for the method default argument values when defining a @Route\n * Adjacent placeholders without separator work now, e.g. `/{x}{y}{z}.{_format}`.\n * Characters that function as separator between placeholders are now whitelisted\n   to fix routes with normal text around a variable, e.g. `/prefix{var}suffix`.\n * [BC BREAK] The default requirement of a variable has been changed slightly.\n   Previously it disallowed the previous and the next char around a variable. Now\n   it disallows the slash (`/`) and the next char. Using the previous char added\n   no value and was problematic because the route `/index.{_format}` would be\n   matched by `/index.ht/ml`.\n * The default requirement now uses possessive quantifiers when possible which\n   improves matching performance by up to 20% because it prevents backtracking\n   when it's not needed.\n * The ConfigurableRequirementsInterface can now also be used to disable the requirements\n   check on URL generation completely by calling `setStrictRequirements(null)`. It\n   improves performance in production environment as you should know that params always\n   pass the requirements (otherwise it would break your link anyway).\n * There is no restriction on the route name anymore. So non-alphanumeric characters\n   are now also allowed.\n * [BC BREAK] `RouteCompilerInterface::compile(Route $route)` was made static\n   (only relevant if you implemented your own RouteCompiler).\n * Added possibility to generate relative paths and network paths in the UrlGenerator, e.g.\n   \"../parent-file\" and \"//example.com/dir/file\". The third parameter in\n   `UrlGeneratorInterface::generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)`\n   now accepts more values and you should use the constants defined in `UrlGeneratorInterface` for\n   claritiy. The old method calls with a Boolean parameter will continue to work because they\n   equal the signature using the constants.\n\n2.1.0\n-----\n\n * added RequestMatcherInterface\n * added RequestContext::fromRequest()\n * the UrlMatcher does not throw a \\LogicException anymore when the required\n   scheme is not the current one\n * added TraceableUrlMatcher\n * added the possibility to define options, default values and requirements\n   for placeholders in prefix, including imported routes\n * added RouterInterface::getRouteCollection\n * [BC BREAK] the UrlMatcher urldecodes the route parameters only once, they\n   were decoded twice before. Note that the `urldecode()` calls have been\n   changed for a single `rawurldecode()` in order to support `+` for input\n   paths.\n * added RouteCollection::getRoot method to retrieve the root of a\n   RouteCollection tree\n * [BC BREAK] made RouteCollection::setParent private which could not have\n   been used anyway without creating inconsistencies\n * [BC BREAK] RouteCollection::remove also removes a route from parent\n   collections (not only from its children)\n * added ConfigurableRequirementsInterface that allows to disable exceptions\n   (and generate empty URLs instead) when generating a route with an invalid\n   parameter value\n"
  },
  {
    "path": "CompiledRoute.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\n/**\n * CompiledRoutes are returned by the RouteCompiler class.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass CompiledRoute implements \\Serializable\n{\n    /**\n     * @param string      $staticPrefix  The static prefix of the compiled route\n     * @param string      $regex         The regular expression to use to match this route\n     * @param array       $tokens        An array of tokens to use to generate URL for this route\n     * @param array       $pathVariables An array of path variables\n     * @param string|null $hostRegex     Host regex\n     * @param array       $hostTokens    Host tokens\n     * @param array       $hostVariables An array of host variables\n     * @param array       $variables     An array of variables (variables defined in the path and in the host patterns)\n     */\n    public function __construct(\n        private string $staticPrefix,\n        private string $regex,\n        private array $tokens,\n        private array $pathVariables,\n        private ?string $hostRegex = null,\n        private array $hostTokens = [],\n        private array $hostVariables = [],\n        private array $variables = [],\n    ) {\n    }\n\n    public function __serialize(): array\n    {\n        return [\n            'vars' => $this->variables,\n            'path_prefix' => $this->staticPrefix,\n            'path_regex' => $this->regex,\n            'path_tokens' => $this->tokens,\n            'path_vars' => $this->pathVariables,\n            'host_regex' => $this->hostRegex,\n            'host_tokens' => $this->hostTokens,\n            'host_vars' => $this->hostVariables,\n        ];\n    }\n\n    /**\n     * @internal\n     */\n    final public function serialize(): string\n    {\n        throw new \\BadMethodCallException('Cannot serialize '.__CLASS__);\n    }\n\n    public function __unserialize(array $data): void\n    {\n        $this->variables = $data['vars'];\n        $this->staticPrefix = $data['path_prefix'];\n        $this->regex = $data['path_regex'];\n        $this->tokens = $data['path_tokens'];\n        $this->pathVariables = $data['path_vars'];\n        $this->hostRegex = $data['host_regex'];\n        $this->hostTokens = $data['host_tokens'];\n        $this->hostVariables = $data['host_vars'];\n    }\n\n    /**\n     * @internal\n     */\n    final public function unserialize(string $serialized): void\n    {\n        $this->__unserialize(unserialize($serialized, ['allowed_classes' => false]));\n    }\n\n    /**\n     * Returns the static prefix.\n     */\n    public function getStaticPrefix(): string\n    {\n        return $this->staticPrefix;\n    }\n\n    /**\n     * Returns the regex.\n     */\n    public function getRegex(): string\n    {\n        return $this->regex;\n    }\n\n    /**\n     * Returns the host regex.\n     */\n    public function getHostRegex(): ?string\n    {\n        return $this->hostRegex;\n    }\n\n    /**\n     * Returns the tokens.\n     */\n    public function getTokens(): array\n    {\n        return $this->tokens;\n    }\n\n    /**\n     * Returns the host tokens.\n     */\n    public function getHostTokens(): array\n    {\n        return $this->hostTokens;\n    }\n\n    /**\n     * Returns the variables.\n     */\n    public function getVariables(): array\n    {\n        return $this->variables;\n    }\n\n    /**\n     * Returns the path variables.\n     */\n    public function getPathVariables(): array\n    {\n        return $this->pathVariables;\n    }\n\n    /**\n     * Returns the host variables.\n     */\n    public function getHostVariables(): array\n    {\n        return $this->hostVariables;\n    }\n}\n"
  },
  {
    "path": "DependencyInjection/AddExpressionLanguageProvidersPass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\DependencyInjection;\n\nuse Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Reference;\n\n/**\n * Registers the expression language providers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass AddExpressionLanguageProvidersPass implements CompilerPassInterface\n{\n    public function process(ContainerBuilder $container): void\n    {\n        if (!$container->has('router.default')) {\n            return;\n        }\n\n        $definition = $container->findDefinition('router.default');\n        foreach ($container->findTaggedServiceIds('routing.expression_language_provider', true) as $id => $attributes) {\n            $definition->addMethodCall('addExpressionLanguageProvider', [new Reference($id)]);\n        }\n    }\n}\n"
  },
  {
    "path": "DependencyInjection/RoutingControllerPass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\DependencyInjection;\n\nuse Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface;\nuse Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n */\nfinal class RoutingControllerPass implements CompilerPassInterface\n{\n    use PriorityTaggedServiceTrait;\n\n    public function process(ContainerBuilder $container): void\n    {\n        if (!$container->hasDefinition('routing.loader.attribute.services')) {\n            return;\n        }\n\n        $resolve = $container->getParameterBag()->resolveValue(...);\n        $taggedClasses = [];\n        foreach ($this->findAndSortTaggedServices('routing.controller', $container) as $id) {\n            $taggedClasses[$resolve($container->getDefinition($id)->getClass())] = true;\n        }\n\n        $container->getDefinition('routing.loader.attribute.services')\n            ->replaceArgument(0, array_keys($taggedClasses));\n    }\n}\n"
  },
  {
    "path": "DependencyInjection/RoutingResolverPass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\DependencyInjection;\n\nuse Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface;\nuse Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Reference;\n\n/**\n * Adds tagged routing.loader services to routing.resolver service.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass RoutingResolverPass implements CompilerPassInterface\n{\n    use PriorityTaggedServiceTrait;\n\n    public function process(ContainerBuilder $container): void\n    {\n        if (false === $container->hasDefinition('routing.resolver')) {\n            return;\n        }\n\n        $definition = $container->getDefinition('routing.resolver');\n\n        foreach ($this->findAndSortTaggedServices('routing.loader', $container) as $id) {\n            $definition->addMethodCall('addLoader', [new Reference($id)]);\n        }\n    }\n}\n"
  },
  {
    "path": "Exception/ExceptionInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * ExceptionInterface.\n *\n * @author Alexandre Salomé <alexandre.salome@gmail.com>\n */\ninterface ExceptionInterface extends \\Throwable\n{\n}\n"
  },
  {
    "path": "Exception/InvalidArgumentException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\nclass InvalidArgumentException extends \\InvalidArgumentException implements ExceptionInterface\n{\n}\n"
  },
  {
    "path": "Exception/InvalidParameterException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * Exception thrown when a parameter is not valid.\n *\n * @author Alexandre Salomé <alexandre.salome@gmail.com>\n */\nclass InvalidParameterException extends \\InvalidArgumentException implements ExceptionInterface\n{\n}\n"
  },
  {
    "path": "Exception/LogicException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\nclass LogicException extends \\LogicException\n{\n}\n"
  },
  {
    "path": "Exception/MethodNotAllowedException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * The resource was found but the request method is not allowed.\n *\n * This exception should trigger an HTTP 405 response in your application code.\n *\n * @author Kris Wallsmith <kris@symfony.com>\n */\nclass MethodNotAllowedException extends \\RuntimeException implements ExceptionInterface\n{\n    protected array $allowedMethods = [];\n\n    /**\n     * @param string[] $allowedMethods\n     */\n    public function __construct(array $allowedMethods, string $message = '', int $code = 0, ?\\Throwable $previous = null)\n    {\n        $this->allowedMethods = array_map('strtoupper', $allowedMethods);\n\n        parent::__construct($message, $code, $previous);\n    }\n\n    /**\n     * Gets the allowed HTTP methods.\n     *\n     * @return string[]\n     */\n    public function getAllowedMethods(): array\n    {\n        return $this->allowedMethods;\n    }\n}\n"
  },
  {
    "path": "Exception/MissingMandatoryParametersException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * Exception thrown when a route cannot be generated because of missing\n * mandatory parameters.\n *\n * @author Alexandre Salomé <alexandre.salome@gmail.com>\n */\nclass MissingMandatoryParametersException extends \\InvalidArgumentException implements ExceptionInterface\n{\n    private string $routeName = '';\n    private array $missingParameters = [];\n\n    /**\n     * @param string[] $missingParameters\n     */\n    public function __construct(string $routeName = '', array $missingParameters = [], int $code = 0, ?\\Throwable $previous = null)\n    {\n        $this->routeName = $routeName;\n        $this->missingParameters = $missingParameters;\n        $message = \\sprintf('Some mandatory parameters are missing (\"%s\") to generate a URL for route \"%s\".', implode('\", \"', $missingParameters), $routeName);\n\n        parent::__construct($message, $code, $previous);\n    }\n\n    /**\n     * @return string[]\n     */\n    public function getMissingParameters(): array\n    {\n        return $this->missingParameters;\n    }\n\n    public function getRouteName(): string\n    {\n        return $this->routeName;\n    }\n}\n"
  },
  {
    "path": "Exception/NoConfigurationException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * Exception thrown when no routes are configured.\n *\n * @author Yonel Ceruto <yonelceruto@gmail.com>\n */\nclass NoConfigurationException extends ResourceNotFoundException\n{\n}\n"
  },
  {
    "path": "Exception/ResourceNotFoundException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * The resource was not found.\n *\n * This exception should trigger an HTTP 404 response in your application code.\n *\n * @author Kris Wallsmith <kris@symfony.com>\n */\nclass ResourceNotFoundException extends \\RuntimeException implements ExceptionInterface\n{\n}\n"
  },
  {
    "path": "Exception/RouteCircularReferenceException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\nclass RouteCircularReferenceException extends RuntimeException\n{\n    public function __construct(string $routeId, array $path)\n    {\n        parent::__construct(\\sprintf('Circular reference detected for route \"%s\", path: \"%s\".', $routeId, implode(' -> ', $path)));\n    }\n}\n"
  },
  {
    "path": "Exception/RouteNotFoundException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\n/**\n * Exception thrown when a route does not exist.\n *\n * @author Alexandre Salomé <alexandre.salome@gmail.com>\n */\nclass RouteNotFoundException extends \\InvalidArgumentException implements ExceptionInterface\n{\n}\n"
  },
  {
    "path": "Exception/RuntimeException.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Exception;\n\nclass RuntimeException extends \\RuntimeException implements ExceptionInterface\n{\n}\n"
  },
  {
    "path": "Generator/CompiledUrlGenerator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator;\n\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\nuse Symfony\\Component\\Routing\\RequestContext;\n\n/**\n * Generates URLs based on rules dumped by CompiledUrlGeneratorDumper.\n */\nclass CompiledUrlGenerator extends UrlGenerator\n{\n    private array $compiledRoutes = [];\n\n    public function __construct(\n        array $compiledRoutes,\n        RequestContext $context,\n        ?LoggerInterface $logger = null,\n        private ?string $defaultLocale = null,\n    ) {\n        $this->compiledRoutes = $compiledRoutes;\n        $this->context = $context;\n        $this->logger = $logger;\n    }\n\n    public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string\n    {\n        $locale = $parameters['_locale']\n            ?? $this->context->getParameter('_locale')\n            ?: $this->defaultLocale;\n\n        if (null !== $locale) {\n            do {\n                if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {\n                    $name .= '.'.$locale;\n                    break;\n                }\n            } while (false !== $locale = strstr($locale, '_', true));\n        }\n\n        if (!isset($this->compiledRoutes[$name])) {\n            throw new RouteNotFoundException(\\sprintf('Unable to generate a URL for the named route \"%s\" as such route does not exist.', $name));\n        }\n\n        [$variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes, $deprecations] = $this->compiledRoutes[$name] + [6 => []];\n\n        foreach ($deprecations as $deprecation) {\n            trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);\n        }\n\n        if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {\n            if (!\\in_array('_locale', $variables, true)) {\n                unset($parameters['_locale']);\n            } elseif (!isset($parameters['_locale'])) {\n                $parameters['_locale'] = $defaults['_locale'];\n            }\n        }\n\n        return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);\n    }\n}\n"
  },
  {
    "path": "Generator/ConfigurableRequirementsInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator;\n\n/**\n * ConfigurableRequirementsInterface must be implemented by URL generators that\n * can be configured whether an exception should be generated when the parameters\n * do not match the requirements. It is also possible to disable the requirements\n * check for URL generation completely.\n *\n * The possible configurations and use-cases:\n * - setStrictRequirements(true): Throw an exception for mismatching requirements. This\n *   is mostly useful in development environment.\n * - setStrictRequirements(false): Don't throw an exception but return an empty string as URL for\n *   mismatching requirements and log the problem. Useful when you cannot control all\n *   params because they come from third party libs but don't want to have a 404 in\n *   production environment. It should log the mismatch so one can review it.\n * - setStrictRequirements(null): Return the URL with the given parameters without\n *   checking the requirements at all. When generating a URL you should either trust\n *   your params or you validated them beforehand because otherwise it would break your\n *   link anyway. So in production environment you should know that params always pass\n *   the requirements. Thus this option allows to disable the check on URL generation for\n *   performance reasons (saving a preg_match for each requirement every time a URL is\n *   generated).\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\ninterface ConfigurableRequirementsInterface\n{\n    /**\n     * Enables or disables the exception on incorrect parameters.\n     * Passing null will deactivate the requirements check completely.\n     */\n    public function setStrictRequirements(?bool $enabled): void;\n\n    /**\n     * Returns whether to throw an exception on incorrect parameters.\n     * Null means the requirements check is deactivated completely.\n     */\n    public function isStrictRequirements(): ?bool;\n}\n"
  },
  {
    "path": "Generator/Dumper/CompiledUrlGeneratorDumper.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator\\Dumper;\n\nuse Symfony\\Component\\Routing\\Exception\\RouteCircularReferenceException;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper;\n\n/**\n * CompiledUrlGeneratorDumper creates a PHP array to be used with CompiledUrlGenerator.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass CompiledUrlGeneratorDumper extends GeneratorDumper\n{\n    public function getCompiledRoutes(): array\n    {\n        $compiledRoutes = [];\n        foreach ($this->getRoutes()->all() as $name => $route) {\n            $compiledRoute = $route->compile();\n\n            $compiledRoutes[$name] = [\n                $compiledRoute->getVariables(),\n                $route->getDefaults(),\n                $route->getRequirements(),\n                $compiledRoute->getTokens(),\n                $compiledRoute->getHostTokens(),\n                $route->getSchemes(),\n                [],\n            ];\n        }\n\n        return $compiledRoutes;\n    }\n\n    public function getCompiledAliases(): array\n    {\n        $routes = $this->getRoutes();\n        $compiledAliases = [];\n        foreach ($routes->getAliases() as $name => $alias) {\n            $deprecations = $alias->isDeprecated() ? [$alias->getDeprecation($name)] : [];\n            $currentId = $alias->getId();\n            $visited = [];\n            while (null !== $alias = $routes->getAlias($currentId) ?? null) {\n                if (false !== $searchKey = array_search($currentId, $visited)) {\n                    $visited[] = $currentId;\n\n                    throw new RouteCircularReferenceException($currentId, \\array_slice($visited, $searchKey));\n                }\n\n                if ($alias->isDeprecated()) {\n                    $deprecations[] = $deprecation = $alias->getDeprecation($currentId);\n                    trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);\n                }\n\n                $visited[] = $currentId;\n                $currentId = $alias->getId();\n            }\n\n            if (null === $target = $routes->get($currentId)) {\n                throw new RouteNotFoundException(\\sprintf('Target route \"%s\" for alias \"%s\" does not exist.', $currentId, $name));\n            }\n\n            $compiledTarget = $target->compile();\n            $defaults = $target->getDefaults();\n\n            if (isset($defaults['_locale']) && str_ends_with($name, '.'.$defaults['_locale'])) {\n                $defaults['_canonical_route'] = substr($name, 0, -\\strlen($defaults['_locale']) - 1);\n            }\n\n            $compiledAliases[$name] = [\n                $compiledTarget->getVariables(),\n                $defaults,\n                $target->getRequirements(),\n                $compiledTarget->getTokens(),\n                $compiledTarget->getHostTokens(),\n                $target->getSchemes(),\n                $deprecations,\n            ];\n        }\n\n        return $compiledAliases;\n    }\n\n    public function dump(array $options = []): string\n    {\n        return <<<EOF\n            <?php\n\n            // This file has been auto-generated by the Symfony Routing Component.\n\n            return [{$this->generateDeclaredRoutes()}\n            ];\n\n            EOF;\n    }\n\n    /**\n     * Generates PHP code representing an array of defined routes\n     * together with the routes properties (e.g. requirements).\n     */\n    private function generateDeclaredRoutes(): string\n    {\n        $routes = '';\n        foreach ($this->getCompiledRoutes() as $name => $properties) {\n            $routes .= \\sprintf(\"\\n    '%s' => %s,\", $name, CompiledUrlMatcherDumper::export($properties));\n        }\n\n        foreach ($this->getCompiledAliases() as $alias => $properties) {\n            $routes .= \\sprintf(\"\\n    '%s' => %s,\", $alias, CompiledUrlMatcherDumper::export($properties));\n        }\n\n        return $routes;\n    }\n}\n"
  },
  {
    "path": "Generator/Dumper/GeneratorDumper.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator\\Dumper;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * GeneratorDumper is the base class for all built-in generator dumpers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nabstract class GeneratorDumper implements GeneratorDumperInterface\n{\n    public function __construct(\n        private RouteCollection $routes,\n    ) {\n    }\n\n    public function getRoutes(): RouteCollection\n    {\n        return $this->routes;\n    }\n}\n"
  },
  {
    "path": "Generator/Dumper/GeneratorDumperInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator\\Dumper;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * GeneratorDumperInterface is the interface that all generator dumper classes must implement.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface GeneratorDumperInterface\n{\n    /**\n     * Dumps a set of routes to a string representation of executable code\n     * that can then be used to generate a URL of such a route.\n     */\n    public function dump(array $options = []): string;\n\n    /**\n     * Gets the routes to dump.\n     */\n    public function getRoutes(): RouteCollection;\n}\n"
  },
  {
    "path": "Generator/UrlGenerator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator;\n\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\Routing\\Exception\\InvalidParameterException;\nuse Symfony\\Component\\Routing\\Exception\\MissingMandatoryParametersException;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * UrlGenerator can generate a URL or a path for any route in the RouteCollection\n * based on the passed parameters.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\nclass UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInterface\n{\n    private const QUERY_FRAGMENT_DECODED = [\n        // RFC 3986 explicitly allows those in the query/fragment to reference other URIs unencoded\n        '%2F' => '/',\n        '%252F' => '%2F',\n        '%3F' => '?',\n        // reserved chars that have no special meaning for HTTP URIs in a query or fragment\n        // this excludes esp. \"&\", \"=\" and also \"+\" because PHP would treat it as a space (form-encoded)\n        '%40' => '@',\n        '%3A' => ':',\n        '%21' => '!',\n        '%3B' => ';',\n        '%2C' => ',',\n        '%2A' => '*',\n    ];\n\n    protected ?bool $strictRequirements = true;\n\n    /**\n     * This array defines the characters (besides alphanumeric ones) that will not be percent-encoded in the path segment of the generated URL.\n     *\n     * PHP's rawurlencode() encodes all chars except \"a-zA-Z0-9-._~\" according to RFC 3986. But we want to allow some chars\n     * to be used in their literal form (reasons below). Other chars inside the path must of course be encoded, e.g.\n     * \"?\" and \"#\" (would be interpreted wrongly as query and fragment identifier),\n     * \"'\" and \"\"\" (are used as delimiters in HTML).\n     */\n    protected array $decodedChars = [\n        // the slash can be used to designate a hierarchical structure and we want allow using it with this meaning\n        // some webservers don't allow the slash in encoded form in the path for security reasons anyway\n        // see http://stackoverflow.com/questions/4069002/http-400-if-2f-part-of-get-url-in-jboss\n        '%2F' => '/',\n        '%252F' => '%2F',\n        // the following chars are general delimiters in the URI specification but have only special meaning in the authority component\n        // so they can safely be used in the path in unencoded form\n        '%40' => '@',\n        '%3A' => ':',\n        // these chars are only sub-delimiters that have no predefined meaning and can therefore be used literally\n        // so URI producing applications can use these chars to delimit subcomponents in a path segment without being encoded for better readability\n        '%3B' => ';',\n        '%2C' => ',',\n        '%3D' => '=',\n        '%2B' => '+',\n        '%21' => '!',\n        '%2A' => '*',\n        '%7C' => '|',\n    ];\n\n    public function __construct(\n        protected RouteCollection $routes,\n        protected RequestContext $context,\n        protected ?LoggerInterface $logger = null,\n        private ?string $defaultLocale = null,\n    ) {\n    }\n\n    public function setContext(RequestContext $context): void\n    {\n        $this->context = $context;\n    }\n\n    public function getContext(): RequestContext\n    {\n        return $this->context;\n    }\n\n    public function setStrictRequirements(?bool $enabled): void\n    {\n        $this->strictRequirements = $enabled;\n    }\n\n    public function isStrictRequirements(): ?bool\n    {\n        return $this->strictRequirements;\n    }\n\n    public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string\n    {\n        $route = null;\n        $locale = $parameters['_locale'] ?? $this->context->getParameter('_locale') ?: $this->defaultLocale;\n\n        if (null !== $locale) {\n            do {\n                $route = $this->routes->get($name.'.'.$locale);\n                if ($route && ($route->getDefault('_canonical_route') === $name || $this->routes->getAlias($name.'.'.$locale))) {\n                    break;\n                }\n            } while (false !== $locale = strstr($locale, '_', true));\n        }\n\n        if (null === $route ??= $this->routes->get($name)) {\n            throw new RouteNotFoundException(\\sprintf('Unable to generate a URL for the named route \"%s\" as such route does not exist.', $name));\n        }\n\n        // the Route has a cache of its own and is not recompiled as long as it does not get modified\n        $compiledRoute = $route->compile();\n\n        $defaults = $route->getDefaults();\n        $variables = $compiledRoute->getVariables();\n\n        if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {\n            if (!\\in_array('_locale', $variables, true)) {\n                unset($parameters['_locale']);\n            } elseif (!isset($parameters['_locale'])) {\n                $parameters['_locale'] = $defaults['_locale'];\n            }\n        }\n\n        return $this->doGenerate($variables, $defaults, $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());\n    }\n\n    /**\n     * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route\n     * @throws InvalidParameterException           When a parameter value for a placeholder is not correct because\n     *                                             it does not match the requirement\n     */\n    protected function doGenerate(array $variables, array $defaults, array $requirements, array $tokens, array $parameters, string $name, int $referenceType, array $hostTokens, array $requiredSchemes = []): string\n    {\n        $queryParameters = [];\n\n        if (isset($parameters['_query'])) {\n            if (\\is_array($parameters['_query'])) {\n                $queryParameters = $parameters['_query'];\n                unset($parameters['_query']);\n            } else {\n                throw new InvalidParameterException('Parameter \"_query\" must be an array of query parameters.');\n            }\n        }\n\n        $variables = array_flip($variables);\n        $mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters);\n\n        // all params must be given\n        if ($diff = array_diff_key($variables, $mergedParams)) {\n            throw new MissingMandatoryParametersException($name, array_keys($diff));\n        }\n\n        $url = '';\n        $optional = true;\n        $message = 'Parameter \"{parameter}\" for route \"{route}\" must match \"{expected}\" (\"{given}\" given) to generate a corresponding URL.';\n        foreach ($tokens as $token) {\n            if ('variable' === $token[0]) {\n                $varName = $token[3];\n                // variable is not important by default\n                $important = $token[5] ?? false;\n\n                if (!$optional || $important || !\\array_key_exists($varName, $defaults) || (null !== $mergedParams[$varName] && (string) $mergedParams[$varName] !== (string) $defaults[$varName])) {\n                    // check requirement (while ignoring look-around patterns)\n                    if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\\(\\?(?:=|<=|!|<!)((?:[^()\\\\\\\\]+|\\\\\\\\.|\\((?1)\\))*)\\)/', '', $token[2]).'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]] ?? '')) {\n                        if ($this->strictRequirements) {\n                            throw new InvalidParameterException(strtr($message, ['{parameter}' => $varName, '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$varName]]));\n                        }\n\n                        $this->logger?->error($message, ['parameter' => $varName, 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$varName]]);\n\n                        return '';\n                    }\n\n                    $url = $token[1].$mergedParams[$varName].$url;\n                    $optional = false;\n                }\n            } else {\n                // static text\n                $url = $token[1].$url;\n                $optional = false;\n            }\n        }\n\n        if ('' === $url) {\n            $url = '/';\n        }\n\n        // the contexts base URL is already encoded (see Symfony\\Component\\HttpFoundation\\Request)\n        $url = strtr(rawurlencode($url), $this->decodedChars);\n\n        // the path segments \".\" and \"..\" are interpreted as relative reference when resolving a URI; see http://tools.ietf.org/html/rfc3986#section-3.3\n        // so we need to encode them as they are not used for this purpose here\n        // otherwise we would generate a URI that, when followed by a user agent (e.g. browser), does not match this route\n        $url = strtr($url, ['/../' => '/%2E%2E/', '/./' => '/%2E/']);\n        if (str_ends_with($url, '/..')) {\n            $url = substr($url, 0, -2).'%2E%2E';\n        } elseif (str_ends_with($url, '/.')) {\n            $url = substr($url, 0, -1).'%2E';\n        }\n\n        $schemeAuthority = '';\n        $host = $this->context->getHost();\n        $scheme = $this->context->getScheme();\n\n        if ($requiredSchemes) {\n            if (!\\in_array($scheme, $requiredSchemes, true)) {\n                $referenceType = self::ABSOLUTE_URL;\n                $scheme = current($requiredSchemes);\n            }\n        }\n\n        if ($hostTokens) {\n            $routeHost = '';\n            foreach ($hostTokens as $token) {\n                if ('variable' === $token[0]) {\n                    // check requirement (while ignoring look-around patterns)\n                    if (null !== $this->strictRequirements && !preg_match('#^'.preg_replace('/\\(\\?(?:=|<=|!|<!)((?:[^()\\\\\\\\]+|\\\\\\\\.|\\((?1)\\))*)\\)/', '', $token[2]).'$#i'.(empty($token[4]) ? '' : 'u'), $mergedParams[$token[3]])) {\n                        if ($this->strictRequirements) {\n                            throw new InvalidParameterException(strtr($message, ['{parameter}' => $token[3], '{route}' => $name, '{expected}' => $token[2], '{given}' => $mergedParams[$token[3]]]));\n                        }\n\n                        $this->logger?->error($message, ['parameter' => $token[3], 'route' => $name, 'expected' => $token[2], 'given' => $mergedParams[$token[3]]]);\n\n                        return '';\n                    }\n\n                    $routeHost = $token[1].$mergedParams[$token[3]].$routeHost;\n                } else {\n                    $routeHost = $token[1].$routeHost;\n                }\n            }\n\n            if ($routeHost !== $host) {\n                $host = $routeHost;\n                if (self::ABSOLUTE_URL !== $referenceType) {\n                    $referenceType = self::NETWORK_PATH;\n                }\n            }\n        }\n\n        if (self::ABSOLUTE_URL === $referenceType || self::NETWORK_PATH === $referenceType) {\n            if ('' !== $host || ('' !== $scheme && 'http' !== $scheme && 'https' !== $scheme)) {\n                $port = '';\n                if ('http' === $scheme && 80 !== $this->context->getHttpPort()) {\n                    $port = ':'.$this->context->getHttpPort();\n                } elseif ('https' === $scheme && 443 !== $this->context->getHttpsPort()) {\n                    $port = ':'.$this->context->getHttpsPort();\n                }\n\n                $schemeAuthority = self::NETWORK_PATH === $referenceType || '' === $scheme ? '//' : \"$scheme://\";\n                $schemeAuthority .= $host.$port;\n            }\n        }\n\n        if (self::RELATIVE_PATH === $referenceType) {\n            $url = self::getRelativePath($this->context->getPathInfo(), $url);\n        } else {\n            $url = $schemeAuthority.$this->context->getBaseUrl().$url;\n        }\n\n        // add a query string if needed\n        $extra = array_udiff_assoc(array_diff_key($parameters, $variables), $defaults, static fn ($a, $b) => $a == $b ? 0 : 1);\n        $extra = array_replace($extra, $queryParameters);\n\n        array_walk_recursive($extra, $caster = static function (&$v) use (&$caster) {\n            if (\\is_object($v)) {\n                if ($vars = get_object_vars($v)) {\n                    array_walk_recursive($vars, $caster);\n                    $v = $vars;\n                } elseif ($v instanceof \\Stringable) {\n                    $v = (string) $v;\n                }\n            }\n        });\n\n        // extract fragment\n        $fragment = $defaults['_fragment'] ?? '';\n\n        if (isset($extra['_fragment'])) {\n            $fragment = $extra['_fragment'];\n            unset($extra['_fragment']);\n        }\n\n        if ($extra && $query = http_build_query($extra, '', '&', \\PHP_QUERY_RFC3986)) {\n            $url .= '?'.strtr($query, self::QUERY_FRAGMENT_DECODED);\n        }\n\n        if ('' !== $fragment) {\n            $url .= '#'.strtr(rawurlencode($fragment), self::QUERY_FRAGMENT_DECODED);\n        }\n\n        return $url;\n    }\n\n    /**\n     * Returns the target path as relative reference from the base path.\n     *\n     * Only the URIs path component (no schema, host etc.) is relevant and must be given, starting with a slash.\n     * Both paths must be absolute and not contain relative parts.\n     * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.\n     * Furthermore, they can be used to reduce the link size in documents.\n     *\n     * Example target paths, given a base path of \"/a/b/c/d\":\n     * - \"/a/b/c/d\"     -> \"\"\n     * - \"/a/b/c/\"      -> \"./\"\n     * - \"/a/b/\"        -> \"../\"\n     * - \"/a/b/c/other\" -> \"other\"\n     * - \"/a/x/y\"       -> \"../../x/y\"\n     *\n     * @param string $basePath   The base path\n     * @param string $targetPath The target path\n     */\n    public static function getRelativePath(string $basePath, string $targetPath): string\n    {\n        if ($basePath === $targetPath) {\n            return '';\n        }\n\n        $sourceDirs = explode('/', isset($basePath[0]) && '/' === $basePath[0] ? substr($basePath, 1) : $basePath);\n        $targetDirs = explode('/', isset($targetPath[0]) && '/' === $targetPath[0] ? substr($targetPath, 1) : $targetPath);\n        array_pop($sourceDirs);\n        $targetFile = array_pop($targetDirs);\n\n        foreach ($sourceDirs as $i => $dir) {\n            if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {\n                unset($sourceDirs[$i], $targetDirs[$i]);\n            } else {\n                break;\n            }\n        }\n\n        $targetDirs[] = $targetFile;\n        $path = str_repeat('../', \\count($sourceDirs)).implode('/', $targetDirs);\n\n        // A reference to the same base directory or an empty subdirectory must be prefixed with \"./\".\n        // This also applies to a segment with a colon character (e.g., \"file:colon\") that cannot be used\n        // as the first segment of a relative-path reference, as it would be mistaken for a scheme name\n        // (see http://tools.ietf.org/html/rfc3986#section-4.2).\n        return '' === $path || '/' === $path[0]\n            || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos)\n            ? \"./$path\" : $path;\n    }\n}\n"
  },
  {
    "path": "Generator/UrlGeneratorInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Generator;\n\nuse Symfony\\Component\\Routing\\Exception\\InvalidParameterException;\nuse Symfony\\Component\\Routing\\Exception\\MissingMandatoryParametersException;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\nuse Symfony\\Component\\Routing\\RequestContextAwareInterface;\n\n/**\n * UrlGeneratorInterface is the interface that all URL generator classes must implement.\n *\n * The constants in this interface define the different types of resource references that\n * are declared in RFC 3986: http://tools.ietf.org/html/rfc3986\n * We are using the term \"URL\" instead of \"URI\" as this is more common in web applications\n * and we do not need to distinguish them as the difference is mostly semantical and\n * less technical. Generating URIs, i.e. representation-independent resource identifiers,\n * is also possible.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\ninterface UrlGeneratorInterface extends RequestContextAwareInterface\n{\n    /**\n     * Generates an absolute URL, e.g. \"http://example.com/dir/file\".\n     */\n    public const ABSOLUTE_URL = 0;\n\n    /**\n     * Generates an absolute path, e.g. \"/dir/file\".\n     */\n    public const ABSOLUTE_PATH = 1;\n\n    /**\n     * Generates a relative path based on the current request path, e.g. \"../parent-file\".\n     *\n     * @see UrlGenerator::getRelativePath()\n     */\n    public const RELATIVE_PATH = 2;\n\n    /**\n     * Generates a network path, e.g. \"//example.com/dir/file\".\n     * Such reference reuses the current scheme but specifies the host.\n     */\n    public const NETWORK_PATH = 3;\n\n    /**\n     * Generates a URL or path for a specific route based on the given parameters.\n     *\n     * Parameters that reference placeholders in the route pattern will substitute them in the\n     * path or host. Extra params are added as query string to the URL.\n     *\n     * When the passed reference type cannot be generated for the route because it requires a different\n     * host or scheme than the current one, the method will return a more comprehensive reference\n     * that includes the required params. For example, when you call this method with $referenceType = ABSOLUTE_PATH\n     * but the route requires the https scheme whereas the current scheme is http, it will instead return an\n     * ABSOLUTE_URL with the https scheme and the current host. This makes sure the generated URL matches\n     * the route in any case.\n     *\n     * If there is no route with the given name, the generator must throw the RouteNotFoundException.\n     *\n     * The special parameter _fragment will be used as the document fragment suffixed to the final URL.\n     *\n     * @throws RouteNotFoundException              If the named route doesn't exist\n     * @throws MissingMandatoryParametersException When some parameters are missing that are mandatory for the route\n     * @throws InvalidParameterException           When a parameter value for a placeholder is not correct because\n     *                                             it does not match the requirement\n     */\n    public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string;\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2004-present Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "Loader/AttributeClassLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\LoaderInterface;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolverInterface;\nuse Symfony\\Component\\Config\\Resource\\ReflectionClassResource;\nuse Symfony\\Component\\Routing\\Attribute\\DeprecatedAlias;\nuse Symfony\\Component\\Routing\\Attribute\\Route as RouteAttribute;\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Exception\\LogicException;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * AttributeClassLoader loads routing information from a PHP class and its methods.\n *\n * You need to define an implementation for the configureRoute() method. Most of the\n * time, this method should define some PHP callable to be called for the route\n * (a controller in MVC speak).\n *\n * The #[Route] attribute can be set on the class (for global parameters),\n * and on each method.\n *\n * The #[Route] attribute main value is the route path. The attribute also\n * recognizes several parameters: requirements, options, defaults, schemes,\n * methods, host, and name. The name parameter is mandatory.\n * Here is an example of how you should be able to use it:\n *\n *     #[Route('/Blog')]\n *     class Blog\n *     {\n *         #[Route('/', name: 'blog_index')]\n *         public function index()\n *         {\n *         }\n *         #[Route('/{id}', name: 'blog_post', requirements: [\"id\" => '\\d+'])]\n *         public function show()\n *         {\n *         }\n *     }\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Alexander M. Turek <me@derrabus.de>\n * @author Alexandre Daubois <alex.daubois@gmail.com>\n */\nabstract class AttributeClassLoader implements LoaderInterface\n{\n    private string $routeAttributeClass = RouteAttribute::class;\n    protected int $defaultRouteIndex = 0;\n\n    public function __construct(\n        protected readonly ?string $env = null,\n    ) {\n    }\n\n    /**\n     * Sets the attribute class to read route properties from.\n     */\n    public function setRouteAttributeClass(string $class): void\n    {\n        $this->routeAttributeClass = $class;\n    }\n\n    /**\n     * @throws \\InvalidArgumentException When route can't be parsed\n     */\n    public function load(mixed $class, ?string $type = null): RouteCollection\n    {\n        if (!class_exists($class)) {\n            throw new \\InvalidArgumentException(\\sprintf('Class \"%s\" does not exist.', $class));\n        }\n\n        $class = new \\ReflectionClass($class);\n        if ($class->isAbstract()) {\n            throw new \\InvalidArgumentException(\\sprintf('Attributes from class \"%s\" cannot be read as it is abstract.', $class->getName()));\n        }\n\n        $globals = $this->getGlobals($class);\n        $collection = new RouteCollection();\n        $collection->addResource(new ReflectionClassResource($class));\n        if ($globals['env'] && !\\in_array($this->env, $globals['env'], true)) {\n            return $collection;\n        }\n        $fqcnAlias = false;\n\n        if (!$class->hasMethod('__invoke')) {\n            foreach ($this->getAttributes($class) as $attr) {\n                if ($attr->aliases) {\n                    throw new InvalidArgumentException(\\sprintf('Route aliases cannot be used on non-invokable class \"%s\".', $class->getName()));\n                }\n            }\n        }\n\n        foreach ($class->getMethods() as $method) {\n            $this->defaultRouteIndex = 0;\n            $routeNamesBefore = array_keys($collection->all());\n            foreach ($this->getAttributes($method) as $attr) {\n                $this->addRoute($collection, $attr, $globals, $class, $method);\n                if ('__invoke' === $method->name) {\n                    $fqcnAlias = true;\n                }\n            }\n\n            if (1 === $collection->count() - \\count($routeNamesBefore)) {\n                $newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore));\n                if ($newRouteName !== $aliasName = \\sprintf('%s::%s', $class->name, $method->name)) {\n                    $collection->addAlias($aliasName, $newRouteName);\n                }\n            }\n        }\n        if (0 === $collection->count() && $class->hasMethod('__invoke')) {\n            $globals = $this->resetGlobals();\n            foreach ($this->getAttributes($class) as $attr) {\n                $this->addRoute($collection, $attr, $globals, $class, $class->getMethod('__invoke'));\n                $fqcnAlias = true;\n            }\n        }\n        if ($fqcnAlias && 1 === $collection->count()) {\n            $invokeRouteName = key($collection->all());\n            if ($invokeRouteName !== $class->name) {\n                $collection->addAlias($class->name, $invokeRouteName);\n            }\n\n            if ($invokeRouteName !== $aliasName = \\sprintf('%s::__invoke', $class->name)) {\n                $collection->addAlias($aliasName, $invokeRouteName);\n            }\n        }\n\n        return $collection;\n    }\n\n    /**\n     * @param RouteAttribute $attr or an object that exposes a similar interface\n     */\n    protected function addRoute(RouteCollection $collection, object $attr, array $globals, \\ReflectionClass $class, \\ReflectionMethod $method): void\n    {\n        if ($attr->envs && !\\in_array($this->env, $attr->envs, true)) {\n            return;\n        }\n\n        $name = $attr->name ?? $this->getDefaultRouteName($class, $method);\n        $name = $globals['name'].$name;\n\n        $requirements = $attr->requirements;\n\n        foreach ($requirements as $placeholder => $requirement) {\n            if (\\is_int($placeholder)) {\n                throw new \\InvalidArgumentException(\\sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement \"%s\" of route \"%s\" in \"%s::%s()\"?', $placeholder, $requirement, $name, $class->getName(), $method->getName()));\n            }\n        }\n\n        $defaults = array_replace($globals['defaults'], $attr->defaults);\n        $requirements = array_replace($globals['requirements'], $requirements);\n        $options = array_replace($globals['options'], $attr->options);\n        $schemes = array_unique(array_merge($globals['schemes'], $attr->schemes));\n        $methods = array_unique(array_merge($globals['methods'], $attr->methods));\n\n        $host = $attr->host ?? $globals['host'];\n        $condition = $attr->condition ?? $globals['condition'];\n        $priority = $attr->priority ?? $globals['priority'];\n\n        $path = $attr->path;\n        $prefix = $globals['localized_paths'] ?: $globals['path'];\n        $paths = [];\n\n        if (\\is_array($path)) {\n            if (!\\is_array($prefix)) {\n                foreach ($path as $locale => $localePath) {\n                    $paths[$locale] = $prefix.$localePath;\n                }\n            } elseif ($missing = array_diff_key($prefix, $path)) {\n                throw new \\LogicException(\\sprintf('Route to \"%s\" is missing paths for locale(s) \"%s\".', $class->name.'::'.$method->name, implode('\", \"', array_keys($missing))));\n            } else {\n                foreach ($path as $locale => $localePath) {\n                    if (!isset($prefix[$locale])) {\n                        throw new \\LogicException(\\sprintf('Route to \"%s\" with locale \"%s\" is missing a corresponding prefix in class \"%s\".', $method->name, $locale, $class->name));\n                    }\n\n                    $paths[$locale] = $prefix[$locale].$localePath;\n                }\n            }\n        } elseif (\\is_array($prefix)) {\n            foreach ($prefix as $locale => $localePrefix) {\n                $paths[$locale] = $localePrefix.$path;\n            }\n        } else {\n            $paths[] = $prefix.$path;\n        }\n\n        foreach ($method->getParameters() as $param) {\n            if (isset($defaults[$param->name]) || !$param->isDefaultValueAvailable()) {\n                continue;\n            }\n            foreach ($paths as $locale => $path) {\n                if (preg_match(\\sprintf('/\\{(?|([^\\}:<]++):%s(?:\\.[^\\}<]++)?|(%1$s))(?:<.*?>)?\\}/', preg_quote($param->name)), $path, $matches)) {\n                    if (\\is_scalar($defaultValue = $param->getDefaultValue()) || null === $defaultValue) {\n                        $defaults[$matches[1]] = $defaultValue;\n                    } elseif ($defaultValue instanceof \\BackedEnum) {\n                        $defaults[$matches[1]] = $defaultValue->value;\n                    }\n                    break;\n                }\n            }\n        }\n\n        foreach ($paths as $locale => $path) {\n            $route = $this->createRoute($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);\n            $this->configureRoute($route, $class, $method, $attr);\n            if (0 !== $locale) {\n                $route->setDefault('_locale', $locale);\n                $route->setRequirement('_locale', preg_quote($locale));\n                $route->setDefault('_canonical_route', $name);\n                $collection->add($name.'.'.$locale, $route, $priority);\n            } else {\n                $collection->add($name, $route, $priority);\n            }\n        }\n\n        foreach ($attr->aliases as $aliasAttribute) {\n            $aliasName = $aliasAttribute instanceof DeprecatedAlias ? $aliasAttribute->aliasName : $aliasAttribute;\n\n            foreach (array_keys($paths) as $locale) {\n                $suffix = 0 !== $locale ? '.'.$locale : '';\n                $alias = $collection->addAlias($aliasName.$suffix, $name.$suffix);\n\n                if ($aliasAttribute instanceof DeprecatedAlias) {\n                    $alias->setDeprecated(\n                        $aliasAttribute->package,\n                        $aliasAttribute->version,\n                        $aliasAttribute->message\n                    );\n                }\n            }\n        }\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return \\is_string($resource) && preg_match('/^(?:\\\\\\\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)+$/', $resource) && (!$type || 'attribute' === $type);\n    }\n\n    public function setResolver(LoaderResolverInterface $resolver): void\n    {\n    }\n\n    public function getResolver(): LoaderResolverInterface\n    {\n        throw new LogicException(\\sprintf('The \"%s()\" method must not be called.', __METHOD__));\n    }\n\n    /**\n     * Gets the default route name for a class method.\n     */\n    protected function getDefaultRouteName(\\ReflectionClass $class, \\ReflectionMethod $method): string\n    {\n        $name = str_replace('\\\\', '_', $class->name).'_'.$method->name;\n        $name = \\function_exists('mb_strtolower') && preg_match('//u', $name) ? mb_strtolower($name, 'UTF-8') : strtolower($name);\n        if ($this->defaultRouteIndex > 0) {\n            $name .= '_'.$this->defaultRouteIndex;\n        }\n        ++$this->defaultRouteIndex;\n\n        return $name;\n    }\n\n    /**\n     * @return array<string, mixed>\n     */\n    protected function getGlobals(\\ReflectionClass $class): array\n    {\n        $globals = $this->resetGlobals();\n\n        if ($attribute = $class->getAttributes($this->routeAttributeClass, \\ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {\n            $attr = $attribute->newInstance();\n\n            if (null !== $attr->name) {\n                $globals['name'] = $attr->name;\n            }\n\n            if (\\is_string($attr->path)) {\n                $globals['path'] = $attr->path;\n                $globals['localized_paths'] = [];\n            } else {\n                $globals['localized_paths'] = $attr->path ?? [];\n            }\n\n            if (null !== $attr->requirements) {\n                $globals['requirements'] = $attr->requirements;\n            }\n\n            if (null !== $attr->options) {\n                $globals['options'] = $attr->options;\n            }\n\n            if (null !== $attr->defaults) {\n                $globals['defaults'] = $attr->defaults;\n            }\n\n            if (null !== $attr->schemes) {\n                $globals['schemes'] = $attr->schemes;\n            }\n\n            if (null !== $attr->methods) {\n                $globals['methods'] = $attr->methods;\n            }\n\n            if (null !== $attr->host) {\n                $globals['host'] = $attr->host;\n            }\n\n            if (null !== $attr->condition) {\n                $globals['condition'] = $attr->condition;\n            }\n\n            $globals['priority'] = $attr->priority ?? 0;\n            $globals['env'] = $attr->envs;\n\n            foreach ($globals['requirements'] as $placeholder => $requirement) {\n                if (\\is_int($placeholder)) {\n                    throw new \\InvalidArgumentException(\\sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement \"%s\" in \"%s\"?', $placeholder, $requirement, $class->getName()));\n                }\n            }\n        }\n\n        return $globals;\n    }\n\n    private function resetGlobals(): array\n    {\n        return [\n            'path' => null,\n            'localized_paths' => [],\n            'requirements' => [],\n            'options' => [],\n            'defaults' => [],\n            'schemes' => [],\n            'methods' => [],\n            'host' => '',\n            'condition' => '',\n            'name' => '',\n            'priority' => 0,\n            'env' => null,\n        ];\n    }\n\n    protected function createRoute(string $path, array $defaults, array $requirements, array $options, ?string $host, array $schemes, array $methods, ?string $condition): Route\n    {\n        return new Route($path, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);\n    }\n\n    /**\n     * @param RouteAttribute $attr or an object that exposes a similar interface\n     */\n    abstract protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void;\n\n    /**\n     * @return iterable<int, RouteAttribute>\n     */\n    private function getAttributes(\\ReflectionClass|\\ReflectionMethod $reflection): iterable\n    {\n        foreach ($reflection->getAttributes($this->routeAttributeClass, \\ReflectionAttribute::IS_INSTANCEOF) as $attribute) {\n            yield $attribute->newInstance();\n        }\n    }\n}\n"
  },
  {
    "path": "Loader/AttributeDirectoryLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Resource\\GlobResource;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * AttributeDirectoryLoader loads routing information from attributes set\n * on PHP classes and methods.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Alexandre Daubois <alex.daubois@gmail.com>\n */\nclass AttributeDirectoryLoader extends AttributeFileLoader\n{\n    /**\n     * @throws \\InvalidArgumentException When the directory does not exist or its routes cannot be parsed\n     */\n    public function load(mixed $path, ?string $type = null): ?RouteCollection\n    {\n        if (!is_dir($dir = $this->locator->locate($path))) {\n            return parent::supports($path, $type) ? parent::load($path, $type) : new RouteCollection();\n        }\n\n        $collection = new RouteCollection();\n        $collection->addResource(new GlobResource($dir, '/*.php', true));\n        $files = iterator_to_array(new \\RecursiveIteratorIterator(\n            new \\RecursiveCallbackFilterIterator(\n                new \\RecursiveDirectoryIterator($dir, \\FilesystemIterator::SKIP_DOTS | \\FilesystemIterator::FOLLOW_SYMLINKS),\n                static fn (\\SplFileInfo $current) => !str_starts_with($current->getBasename(), '.')\n            ),\n            \\RecursiveIteratorIterator::LEAVES_ONLY\n        ));\n        usort($files, static fn (\\SplFileInfo $a, \\SplFileInfo $b) => (string) $a > (string) $b ? 1 : -1);\n\n        foreach ($files as $file) {\n            if (!$file->isFile() || !str_ends_with($file->getFilename(), '.php')) {\n                continue;\n            }\n\n            if ($class = $this->findClass($file)) {\n                $refl = new \\ReflectionClass($class);\n                if ($refl->isAbstract()) {\n                    continue;\n                }\n\n                $collection->addCollection($this->loader->load($class, $type));\n            }\n        }\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        if (!\\is_string($resource)) {\n            return false;\n        }\n\n        if ('attribute' === $type) {\n            return true;\n        }\n\n        if ($type) {\n            return false;\n        }\n\n        try {\n            return is_dir($this->locator->locate($resource));\n        } catch (\\Exception) {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "Loader/AttributeFileLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\FileLocatorInterface;\nuse Symfony\\Component\\Config\\Loader\\FileLoader;\nuse Symfony\\Component\\Config\\Resource\\ReflectionClassResource;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * AttributeFileLoader loads routing information from attributes set\n * on a PHP class and its methods.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Alexandre Daubois <alex.daubois@gmail.com>\n */\nclass AttributeFileLoader extends FileLoader\n{\n    public function __construct(\n        FileLocatorInterface $locator,\n        protected AttributeClassLoader $loader,\n    ) {\n        if (!\\function_exists('token_get_all')) {\n            throw new \\LogicException('The Tokenizer extension is required for the routing attribute loader.');\n        }\n\n        parent::__construct($locator);\n    }\n\n    /**\n     * Loads from attributes from a file.\n     *\n     * @throws \\InvalidArgumentException When the file does not exist or its routes cannot be parsed\n     */\n    public function load(mixed $file, ?string $type = null): ?RouteCollection\n    {\n        $path = $this->locator->locate($file);\n\n        $collection = new RouteCollection();\n        if ($class = $this->findClass($path)) {\n            $refl = new \\ReflectionClass($class);\n            if ($refl->isAbstract()) {\n                return null;\n            }\n\n            $collection->addResource(new ReflectionClassResource($refl));\n            $collection->addCollection($this->loader->load($class, $type));\n        }\n\n        gc_mem_caches();\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return \\is_string($resource) && 'php' === pathinfo($resource, \\PATHINFO_EXTENSION) && (!$type || 'attribute' === $type);\n    }\n\n    /**\n     * Returns the full class name for the first class in the file.\n     */\n    protected function findClass(string $file): string|false\n    {\n        $class = false;\n        $namespace = false;\n        $tokens = token_get_all(file_get_contents($file));\n\n        if (1 === \\count($tokens) && \\T_INLINE_HTML === $tokens[0][0]) {\n            throw new \\InvalidArgumentException(\\sprintf('The file \"%s\" does not contain PHP code. Did you forget to add the \"<?php\" start tag at the beginning of the file?', $file));\n        }\n\n        $nsTokens = [\\T_NS_SEPARATOR => true, \\T_STRING => true, \\T_NAME_QUALIFIED => true];\n        for ($i = 0; isset($tokens[$i]); ++$i) {\n            $token = $tokens[$i];\n            if (!isset($token[1])) {\n                continue;\n            }\n\n            if (true === $class && \\T_STRING === $token[0]) {\n                return $namespace.'\\\\'.$token[1];\n            }\n\n            if (true === $namespace && isset($nsTokens[$token[0]])) {\n                $namespace = $token[1];\n                while (isset($tokens[++$i][1], $nsTokens[$tokens[$i][0]])) {\n                    $namespace .= $tokens[$i][1];\n                }\n                $token = $tokens[$i];\n            }\n\n            if (\\T_CLASS === $token[0]) {\n                // Skip usage of ::class constant and anonymous classes\n                $skipClassToken = false;\n                for ($j = $i - 1; $j > 0; --$j) {\n                    if (!isset($tokens[$j][1])) {\n                        if ('(' === $tokens[$j] || ',' === $tokens[$j]) {\n                            $skipClassToken = true;\n                        }\n                        break;\n                    }\n\n                    if (\\T_DOUBLE_COLON === $tokens[$j][0] || \\T_NEW === $tokens[$j][0]) {\n                        $skipClassToken = true;\n                        break;\n                    } elseif (!\\in_array($tokens[$j][0], [\\T_WHITESPACE, \\T_DOC_COMMENT, \\T_COMMENT], true)) {\n                        break;\n                    }\n                }\n\n                if (!$skipClassToken) {\n                    $class = true;\n                }\n            }\n\n            if (\\T_NAMESPACE === $token[0]) {\n                $namespace = true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "Loader/AttributeServicesLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\Loader;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * Loads routes from a list of tagged classes by delegating to the attribute class loader.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n */\nfinal class AttributeServicesLoader extends Loader\n{\n    /**\n     * @param class-string[] $taggedClasses\n     */\n    public function __construct(\n        private array $taggedClasses = [],\n    ) {\n    }\n\n    public function load(mixed $resource, ?string $type = null): RouteCollection\n    {\n        $collection = new RouteCollection();\n\n        foreach ($this->taggedClasses as $class) {\n            $collection->addCollection($this->import($class, 'attribute'));\n        }\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return 'routing.controllers' === $resource;\n    }\n}\n"
  },
  {
    "path": "Loader/ClosureLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\Loader;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * ClosureLoader loads routes from a PHP closure.\n *\n * The Closure must return a RouteCollection instance.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass ClosureLoader extends Loader\n{\n    /**\n     * Loads a Closure.\n     */\n    public function load(mixed $closure, ?string $type = null): RouteCollection\n    {\n        return $closure($this->env);\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return $resource instanceof \\Closure && (!$type || 'closure' === $type);\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/AliasConfigurator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Alias;\n\nclass AliasConfigurator\n{\n    public function __construct(\n        private Alias $alias,\n    ) {\n    }\n\n    /**\n     * Whether this alias is deprecated, that means it should not be called anymore.\n     *\n     * @param string $package The name of the composer package that is triggering the deprecation\n     * @param string $version The version of the package that introduced the deprecation\n     * @param string $message The deprecation message to use\n     *\n     * @return $this\n     *\n     * @throws InvalidArgumentException when the message template is invalid\n     */\n    public function deprecate(string $package, string $version, string $message): static\n    {\n        $this->alias->setDeprecated($package, $version, $message);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/CollectionConfigurator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass CollectionConfigurator\n{\n    use Traits\\AddTrait;\n    use Traits\\HostTrait;\n    use Traits\\RouteTrait;\n\n    private string|array|null $host = null;\n\n    public function __construct(\n        private RouteCollection $parent,\n        string $name,\n        private ?self $parentConfigurator = null, // for GC control\n        private ?array $parentPrefixes = null,\n    ) {\n        $this->name = $name;\n        $this->collection = new RouteCollection();\n        $this->route = new Route('');\n    }\n\n    public function __serialize(): array\n    {\n        throw new \\BadMethodCallException('Cannot serialize '.__CLASS__);\n    }\n\n    public function __unserialize(array $data): void\n    {\n        throw new \\BadMethodCallException('Cannot unserialize '.__CLASS__);\n    }\n\n    public function __destruct()\n    {\n        if (null === $this->prefixes) {\n            $this->collection->addPrefix($this->route->getPath());\n        }\n        if (null !== $this->host) {\n            $this->addHost($this->collection, $this->host);\n        }\n\n        $this->parent->addCollection($this->collection);\n    }\n\n    /**\n     * Creates a sub-collection.\n     */\n    final public function collection(string $name = ''): self\n    {\n        return new self($this->collection, $this->name.$name, $this, $this->prefixes);\n    }\n\n    /**\n     * Sets the prefix to add to the path of all child routes.\n     *\n     * @param string|array $prefix the prefix, or the localized prefixes\n     *\n     * @return $this\n     */\n    final public function prefix(string|array $prefix): static\n    {\n        if (\\is_array($prefix)) {\n            if (null === $this->parentPrefixes) {\n                // no-op\n            } elseif ($missing = array_diff_key($this->parentPrefixes, $prefix)) {\n                throw new \\LogicException(\\sprintf('Collection \"%s\" is missing prefixes for locale(s) \"%s\".', $this->name, implode('\", \"', array_keys($missing))));\n            } else {\n                foreach ($prefix as $locale => $localePrefix) {\n                    if (!isset($this->parentPrefixes[$locale])) {\n                        throw new \\LogicException(\\sprintf('Collection \"%s\" with locale \"%s\" is missing a corresponding prefix in its parent collection.', $this->name, $locale));\n                    }\n\n                    $prefix[$locale] = $this->parentPrefixes[$locale].$localePrefix;\n                }\n            }\n            $this->prefixes = $prefix;\n            $this->route->setPath('/');\n        } else {\n            $this->prefixes = null;\n            $this->route->setPath($prefix);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Sets the host to use for all child routes.\n     *\n     * @param string|array $host the host, or the localized hosts\n     *\n     * @return $this\n     */\n    final public function host(string|array $host): static\n    {\n        $this->host = $host;\n\n        return $this;\n    }\n\n    /**\n     * This method overrides the one from LocalizedRouteTrait.\n     */\n    private function createRoute(string $path): Route\n    {\n        return (clone $this->route)->setPath($path);\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/ImportConfigurator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass ImportConfigurator\n{\n    use Traits\\HostTrait;\n    use Traits\\PrefixTrait;\n    use Traits\\RouteTrait;\n\n    public function __construct(\n        private RouteCollection $parent,\n        RouteCollection $route,\n    ) {\n        $this->route = $route;\n    }\n\n    public function __serialize(): array\n    {\n        throw new \\BadMethodCallException('Cannot serialize '.__CLASS__);\n    }\n\n    public function __unserialize(array $data): void\n    {\n        throw new \\BadMethodCallException('Cannot unserialize '.__CLASS__);\n    }\n\n    public function __destruct()\n    {\n        $this->parent->addCollection($this->route);\n    }\n\n    /**\n     * Sets the prefix to add to the path of all child routes.\n     *\n     * @param string|array $prefix the prefix, or the localized prefixes\n     *\n     * @return $this\n     */\n    final public function prefix(string|array $prefix, bool $trailingSlashOnRoot = true): static\n    {\n        $this->addPrefix($this->route, $prefix, $trailingSlashOnRoot);\n\n        return $this;\n    }\n\n    /**\n     * Sets the prefix to add to the name of all child routes.\n     *\n     * @return $this\n     */\n    final public function namePrefix(string $namePrefix): static\n    {\n        $this->route->addNamePrefix($namePrefix);\n\n        return $this;\n    }\n\n    /**\n     * Sets the host to use for all child routes.\n     *\n     * @param string|array $host the host, or the localized hosts\n     *\n     * @return $this\n     */\n    final public function host(string|array $host): static\n    {\n        $this->addHost($this->route, $host);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/RouteConfigurator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass RouteConfigurator\n{\n    use Traits\\AddTrait;\n    use Traits\\HostTrait;\n    use Traits\\RouteTrait;\n\n    public function __construct(\n        RouteCollection $collection,\n        RouteCollection $route,\n        string $name = '',\n        protected ?CollectionConfigurator $parentConfigurator = null, // for GC control\n        ?array $prefixes = null,\n    ) {\n        $this->collection = $collection;\n        $this->route = $route;\n        $this->name = $name;\n        $this->prefixes = $prefixes;\n    }\n\n    /**\n     * Sets the host to use for all child routes.\n     *\n     * @param string|array $host the host, or the localized hosts\n     *\n     * @return $this\n     */\n    final public function host(string|array $host): static\n    {\n        $previousRoutes = clone $this->route;\n        $this->addHost($this->route, $host);\n        foreach ($previousRoutes as $name => $route) {\n            if (!$this->route->get($name)) {\n                $this->collection->remove($name);\n            }\n        }\n        $this->collection->addCollection($this->route);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/RoutesReference.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\n// For the phpdoc to remain compatible with the generation of per-app Routes class,\n// this file should have no \"use\" statements: all symbols referenced by\n// the phpdoc need to be in the current namespace or be root-scoped.\n\n/**\n * This class provides array-shapes for configuring the routes of an application.\n *\n * Example:\n *\n *     ```php\n *     // config/routes.php\n *     namespace Symfony\\Component\\Routing\\Loader\\Configurator;\n *\n *     return Routes::config([\n *         'controllers' => [\n *             'resource' => 'routing.controllers',\n *         ],\n *     ]);\n *     ```\n *\n * @psalm-type RouteConfig = array{\n *     path: string|array<string,string>,\n *     controller?: string,\n *     methods?: string|list<string>,\n *     requirements?: array<string,string>,\n *     defaults?: array<string,mixed>,\n *     options?: array<string,mixed>,\n *     host?: string|array<string,string>,\n *     schemes?: string|list<string>,\n *     condition?: string,\n *     locale?: string,\n *     format?: string,\n *     utf8?: bool,\n *     stateless?: bool,\n * }\n * @psalm-type ImportConfig = array{\n *     resource: string,\n *     type?: string,\n *     exclude?: string|list<string>,\n *     prefix?: string|array<string,string>,\n *     name_prefix?: string,\n *     trailing_slash_on_root?: bool,\n *     controller?: string,\n *     methods?: string|list<string>,\n *     requirements?: array<string,string>,\n *     defaults?: array<string,mixed>,\n *     options?: array<string,mixed>,\n *     host?: string|array<string,string>,\n *     schemes?: string|list<string>,\n *     condition?: string,\n *     locale?: string,\n *     format?: string,\n *     utf8?: bool,\n *     stateless?: bool,\n * }\n * @psalm-type AliasConfig = array{\n *     alias: string,\n *     deprecated?: array{package:string, version:string, message?:string},\n * }\n * @psalm-type RoutesConfig = array<string, RouteConfig|ImportConfig|AliasConfig|array<string, RouteConfig|ImportConfig|AliasConfig>>\n */\nclass RoutesReference\n{\n    /**\n     * @param RoutesConfig $config\n     *\n     * @psalm-return RoutesConfig\n     */\n    public static function config(array $config): array\n    {\n        return $config;\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/RoutingConfigurator.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\Routing\\Loader\\PhpFileLoader;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass RoutingConfigurator\n{\n    use Traits\\AddTrait;\n\n    public function __construct(\n        RouteCollection $collection,\n        private PhpFileLoader $loader,\n        private string $path,\n        private string $file,\n        private ?string $env = null,\n    ) {\n        $this->collection = $collection;\n    }\n\n    /**\n     * @param string|string[]|null $exclude Glob patterns to exclude from the import\n     */\n    final public function import(string|array $resource, ?string $type = null, bool $ignoreErrors = false, string|array|null $exclude = null): ImportConfigurator\n    {\n        $this->loader->setCurrentDir(\\dirname($this->path));\n\n        $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file, $exclude) ?: [];\n        if (!\\is_array($imported)) {\n            return new ImportConfigurator($this->collection, $imported);\n        }\n\n        $mergedCollection = new RouteCollection();\n        foreach ($imported as $subCollection) {\n            $mergedCollection->addCollection($subCollection);\n        }\n\n        return new ImportConfigurator($this->collection, $mergedCollection);\n    }\n\n    final public function collection(string $name = ''): CollectionConfigurator\n    {\n        return new CollectionConfigurator($this->collection, $name);\n    }\n\n    /**\n     * Get the current environment to be able to write conditional configuration.\n     */\n    final public function env(): ?string\n    {\n        return $this->env;\n    }\n\n    final public function withPath(string $path): static\n    {\n        $clone = clone $this;\n        $clone->path = $clone->file = $path;\n\n        return $clone;\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/Traits/AddTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator\\Traits;\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\AliasConfigurator;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\CollectionConfigurator;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RouteConfigurator;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n */\ntrait AddTrait\n{\n    use LocalizedRouteTrait;\n\n    protected RouteCollection $collection;\n    protected string $name = '';\n    protected ?array $prefixes = null;\n\n    /**\n     * Adds a route.\n     *\n     * @param string|array $path the path, or the localized paths of the route\n     */\n    public function add(string $name, string|array $path): RouteConfigurator\n    {\n        $parentConfigurator = $this instanceof CollectionConfigurator ? $this : ($this instanceof RouteConfigurator ? $this->parentConfigurator : null);\n        $route = $this->createLocalizedRoute($this->collection, $name, $path, $this->name, $this->prefixes);\n\n        return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes);\n    }\n\n    public function alias(string $name, string $alias): AliasConfigurator\n    {\n        return new AliasConfigurator($this->collection->addAlias($name, $alias));\n    }\n\n    /**\n     * Adds a route.\n     *\n     * @param string|array $path the path, or the localized paths of the route\n     */\n    public function __invoke(string $name, string|array $path): RouteConfigurator\n    {\n        return $this->add($name, $path);\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/Traits/HostTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator\\Traits;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @internal\n */\ntrait HostTrait\n{\n    final protected function addHost(RouteCollection $routes, string|array $hosts): void\n    {\n        if (!$hosts || !\\is_array($hosts)) {\n            $routes->setHost($hosts ?: '');\n\n            return;\n        }\n\n        foreach ($routes->all() as $name => $route) {\n            if (null === $locale = $route->getDefault('_locale')) {\n                $priority = $routes->getPriority($name) ?? 0;\n                $routes->remove($name);\n                foreach ($hosts as $locale => $host) {\n                    $localizedRoute = clone $route;\n                    $localizedRoute->setDefault('_locale', $locale);\n                    $localizedRoute->setRequirement('_locale', preg_quote($locale));\n                    $localizedRoute->setDefault('_canonical_route', $name);\n                    $localizedRoute->setHost($host);\n                    $routes->add($name.'.'.$locale, $localizedRoute, $priority);\n                }\n            } elseif (!isset($hosts[$locale])) {\n                throw new \\InvalidArgumentException(\\sprintf('Route \"%s\" with locale \"%s\" is missing a corresponding host in its parent collection.', $name, $locale));\n            } else {\n                $route->setHost($hosts[$locale]);\n                $route->setRequirement('_locale', preg_quote($locale));\n                $routes->add($name, $route, $routes->getPriority($name) ?? 0);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/Traits/LocalizedRouteTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator\\Traits;\n\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @internal\n *\n * @author Nicolas Grekas <p@tchwork.com>\n * @author Jules Pietri <jules@heahprod.com>\n */\ntrait LocalizedRouteTrait\n{\n    /**\n     * Creates one or many routes.\n     *\n     * @param string|array $path the path, or the localized paths of the route\n     */\n    final protected function createLocalizedRoute(RouteCollection $collection, string $name, string|array $path, string $namePrefix = '', ?array $prefixes = null): RouteCollection\n    {\n        $paths = [];\n\n        $routes = new RouteCollection();\n\n        if (\\is_array($path)) {\n            if (null === $prefixes) {\n                $paths = $path;\n            } elseif ($missing = array_diff_key($prefixes, $path)) {\n                throw new \\LogicException(\\sprintf('Route \"%s\" is missing routes for locale(s) \"%s\".', $name, implode('\", \"', array_keys($missing))));\n            } else {\n                foreach ($path as $locale => $localePath) {\n                    if (!isset($prefixes[$locale])) {\n                        throw new \\LogicException(\\sprintf('Route \"%s\" with locale \"%s\" is missing a corresponding prefix in its parent collection.', $name, $locale));\n                    }\n\n                    $paths[$locale] = $prefixes[$locale].$localePath;\n                }\n            }\n        } elseif (null !== $prefixes) {\n            foreach ($prefixes as $locale => $prefix) {\n                $paths[$locale] = $prefix.$path;\n            }\n        } else {\n            $routes->add($namePrefix.$name, $route = $this->createRoute($path));\n            $collection->add($namePrefix.$name, $route);\n\n            return $routes;\n        }\n\n        foreach ($paths as $locale => $path) {\n            $routes->add($name.'.'.$locale, $route = $this->createRoute($path));\n            $collection->add($namePrefix.$name.'.'.$locale, $route);\n            $route->setDefault('_locale', $locale);\n            $route->setRequirement('_locale', preg_quote($locale));\n            $route->setDefault('_canonical_route', $namePrefix.$name);\n        }\n\n        return $routes;\n    }\n\n    private function createRoute(string $path): Route\n    {\n        return new Route($path);\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/Traits/PrefixTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator\\Traits;\n\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @internal\n *\n * @author Nicolas Grekas <p@tchwork.com>\n */\ntrait PrefixTrait\n{\n    final protected function addPrefix(RouteCollection $routes, string|array $prefix, bool $trailingSlashOnRoot): void\n    {\n        if (\\is_array($prefix)) {\n            foreach ($prefix as $locale => $localePrefix) {\n                $prefix[$locale] = trim(trim($localePrefix), '/');\n            }\n            $aliases = [];\n            foreach ($routes->getAliases() as $name => $alias) {\n                $aliases[$alias->getId()][] = $name;\n            }\n            foreach ($routes->all() as $name => $route) {\n                if (null === $locale = $route->getDefault('_locale')) {\n                    $priority = $routes->getPriority($name) ?? 0;\n                    $routes->remove($name);\n                    foreach ($aliases[$name] ?? [] as $aliasName) {\n                        $routes->remove($aliasName);\n                    }\n                    foreach ($prefix as $locale => $localePrefix) {\n                        $localizedRoute = clone $route;\n                        $localizedRoute->setDefault('_locale', $locale);\n                        $localizedRoute->setRequirement('_locale', preg_quote($locale));\n                        $localizedRoute->setDefault('_canonical_route', $name);\n                        $localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));\n                        $routes->add($name.'.'.$locale, $localizedRoute, $priority);\n                        foreach ($aliases[$name] ?? [] as $aliasName) {\n                            $routes->addAlias($aliasName.'.'.$locale, $name.'.'.$locale);\n                        }\n                    }\n                } elseif (!isset($prefix[$locale])) {\n                    throw new \\InvalidArgumentException(\\sprintf('Route \"%s\" with locale \"%s\" is missing a corresponding prefix in its parent collection.', $name, $locale));\n                } else {\n                    $route->setPath($prefix[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));\n                    $routes->add($name, $route, $routes->getPriority($name) ?? 0);\n                }\n            }\n\n            return;\n        }\n\n        $routes->addPrefix($prefix);\n        if (!$trailingSlashOnRoot) {\n            $rootPath = (new Route(trim(trim($prefix), '/').'/'))->getPath();\n            foreach ($routes->all() as $route) {\n                if ($route->getPath() === $rootPath) {\n                    $route->setPath(rtrim($rootPath, '/'));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Loader/Configurator/Traits/RouteTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator\\Traits;\n\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\ntrait RouteTrait\n{\n    protected RouteCollection|Route $route;\n\n    /**\n     * Adds defaults.\n     *\n     * @return $this\n     */\n    final public function defaults(array $defaults): static\n    {\n        $this->route->addDefaults($defaults);\n\n        return $this;\n    }\n\n    /**\n     * Adds requirements.\n     *\n     * @return $this\n     */\n    final public function requirements(array $requirements): static\n    {\n        $this->route->addRequirements($requirements);\n\n        return $this;\n    }\n\n    /**\n     * Adds options.\n     *\n     * @return $this\n     */\n    final public function options(array $options): static\n    {\n        $this->route->addOptions($options);\n\n        return $this;\n    }\n\n    /**\n     * Whether paths should accept utf8 encoding.\n     *\n     * @return $this\n     */\n    final public function utf8(bool $utf8 = true): static\n    {\n        $this->route->addOptions(['utf8' => $utf8]);\n\n        return $this;\n    }\n\n    /**\n     * Sets the condition.\n     *\n     * @return $this\n     */\n    final public function condition(string $condition): static\n    {\n        $this->route->setCondition($condition);\n\n        return $this;\n    }\n\n    /**\n     * Sets the pattern for the host.\n     *\n     * @return $this\n     */\n    final public function host(string $pattern): static\n    {\n        $this->route->setHost($pattern);\n\n        return $this;\n    }\n\n    /**\n     * Sets the schemes (e.g. 'https') this route is restricted to.\n     * So an empty array means that any scheme is allowed.\n     *\n     * @param string[] $schemes\n     *\n     * @return $this\n     */\n    final public function schemes(array $schemes): static\n    {\n        $this->route->setSchemes($schemes);\n\n        return $this;\n    }\n\n    /**\n     * Sets the HTTP methods (e.g. 'POST') this route is restricted to.\n     * So an empty array means that any method is allowed.\n     *\n     * @param string[] $methods\n     *\n     * @return $this\n     */\n    final public function methods(array $methods): static\n    {\n        $this->route->setMethods($methods);\n\n        return $this;\n    }\n\n    /**\n     * Adds the \"_controller\" entry to defaults.\n     *\n     * @param callable|string|array $controller a callable or parseable pseudo-callable\n     *\n     * @return $this\n     */\n    final public function controller(callable|string|array $controller): static\n    {\n        $this->route->addDefaults(['_controller' => $controller]);\n\n        return $this;\n    }\n\n    /**\n     * Adds the \"_locale\" entry to defaults.\n     *\n     * @return $this\n     */\n    final public function locale(string $locale): static\n    {\n        $this->route->addDefaults(['_locale' => $locale]);\n\n        return $this;\n    }\n\n    /**\n     * Adds the \"_format\" entry to defaults.\n     *\n     * @return $this\n     */\n    final public function format(string $format): static\n    {\n        $this->route->addDefaults(['_format' => $format]);\n\n        return $this;\n    }\n\n    /**\n     * Adds the \"_stateless\" entry to defaults.\n     *\n     * @return $this\n     */\n    final public function stateless(bool $stateless = true): static\n    {\n        $this->route->addDefaults(['_stateless' => $stateless]);\n\n        return $this;\n    }\n}\n"
  },
  {
    "path": "Loader/ContainerLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Psr\\Container\\ContainerInterface;\n\n/**\n * A route loader that executes a service from a PSR-11 container to load the routes.\n *\n * @author Ryan Weaver <ryan@knpuniversity.com>\n */\nclass ContainerLoader extends ObjectLoader\n{\n    public function __construct(\n        private ContainerInterface $container,\n        ?string $env = null,\n    ) {\n        parent::__construct($env);\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return 'service' === $type && \\is_string($resource);\n    }\n\n    protected function getObject(string $id): object\n    {\n        return $this->container->get($id);\n    }\n}\n"
  },
  {
    "path": "Loader/ContentLoaderTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Traits\\LocalizedRouteTrait;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Traits\\PrefixTrait;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * @internal\n */\ntrait ContentLoaderTrait\n{\n    use LocalizedRouteTrait;\n    use PrefixTrait;\n\n    private const AVAILABLE_KEYS = [\n        'resource', 'type', 'prefix', 'path', 'host', 'schemes', 'methods', 'defaults', 'requirements', 'options', 'condition', 'controller', 'name_prefix', 'trailing_slash_on_root', 'locale', 'format', 'utf8', 'exclude', 'stateless',\n    ];\n\n    private function loadContent(RouteCollection $collection, array $config, string $path, string $file): void\n    {\n        foreach ($config as $name => $config) {\n            if (!str_starts_with($when = $name, 'when@')) {\n                $config = [$name => $config];\n            } elseif (!$this->env || 'when@'.$this->env !== $name) {\n                continue;\n            } else {\n                $when .= '\" when \"@'.$this->env;\n            }\n\n            foreach ($config as $name => $config) {\n                $this->validate($config, $when, $path);\n\n                if (isset($config['resource'])) {\n                    $this->parseImport($collection, $config, $path, $file);\n                } else {\n                    $this->parseRoute($collection, $name, $config, $path);\n                }\n            }\n        }\n    }\n\n    /**\n     * Parses a route and adds it to the RouteCollection.\n     */\n    private function parseRoute(RouteCollection $collection, string $name, array $config, string $path): void\n    {\n        if (isset($config['alias'])) {\n            $alias = $collection->addAlias($name, $config['alias']);\n            $deprecation = $config['deprecated'] ?? null;\n            if (null !== $deprecation) {\n                $alias->setDeprecated(\n                    $deprecation['package'],\n                    $deprecation['version'],\n                    $deprecation['message'] ?? ''\n                );\n            }\n\n            return;\n        }\n\n        $defaults = $config['defaults'] ?? [];\n        $requirements = $config['requirements'] ?? [];\n        $options = $config['options'] ?? [];\n\n        foreach ($requirements as $placeholder => $requirement) {\n            if (\\is_int($placeholder)) {\n                throw new \\InvalidArgumentException(\\sprintf('A placeholder name must be a string (%d given). Did you forget to specify the placeholder key for the requirement \"%s\" of route \"%s\" in \"%s\"?', $placeholder, $requirement, $name, $path));\n            }\n        }\n\n        if (isset($config['controller'])) {\n            $defaults['_controller'] = $config['controller'];\n        }\n        if (isset($config['locale'])) {\n            $defaults['_locale'] = $config['locale'];\n        }\n        if (isset($config['format'])) {\n            $defaults['_format'] = $config['format'];\n        }\n        if (isset($config['utf8'])) {\n            $options['utf8'] = $config['utf8'];\n        }\n        if (isset($config['stateless'])) {\n            $defaults['_stateless'] = $config['stateless'];\n        }\n\n        $routes = $this->createLocalizedRoute(new RouteCollection(), $name, $config['path']);\n        $routes->addDefaults($defaults);\n        $routes->addRequirements($requirements);\n        $routes->addOptions($options);\n        $routes->setSchemes($config['schemes'] ?? []);\n        $routes->setMethods($config['methods'] ?? []);\n        $routes->setCondition($config['condition'] ?? null);\n\n        if (isset($config['host'])) {\n            $this->addHost($routes, $config['host']);\n        }\n\n        $collection->addCollection($routes);\n    }\n\n    /**\n     * Parses an import and adds the routes in the resource to the RouteCollection.\n     */\n    private function parseImport(RouteCollection $collection, array $config, string $path, string $file): void\n    {\n        $type = $config['type'] ?? null;\n        $prefix = $config['prefix'] ?? '';\n        $defaults = $config['defaults'] ?? [];\n        $requirements = $config['requirements'] ?? [];\n        $options = $config['options'] ?? [];\n        $host = $config['host'] ?? null;\n        $condition = $config['condition'] ?? null;\n        $schemes = $config['schemes'] ?? null;\n        $methods = $config['methods'] ?? null;\n        $trailingSlashOnRoot = $config['trailing_slash_on_root'] ?? true;\n        $namePrefix = $config['name_prefix'] ?? null;\n        $exclude = $config['exclude'] ?? null;\n\n        if (isset($config['controller'])) {\n            $defaults['_controller'] = $config['controller'];\n        }\n        if (isset($config['locale'])) {\n            $defaults['_locale'] = $config['locale'];\n        }\n        if (isset($config['format'])) {\n            $defaults['_format'] = $config['format'];\n        }\n        if (isset($config['utf8'])) {\n            $options['utf8'] = $config['utf8'];\n        }\n        if (isset($config['stateless'])) {\n            $defaults['_stateless'] = $config['stateless'];\n        }\n\n        $this->setCurrentDir(\\dirname($path));\n\n        /** @var RouteCollection[] $imported */\n        $imported = $this->import($config['resource'], $type, false, $file, $exclude) ?: [];\n\n        if (!\\is_array($imported)) {\n            $imported = [$imported];\n        }\n\n        foreach ($imported as $subCollection) {\n            $this->addPrefix($subCollection, $prefix, $trailingSlashOnRoot);\n\n            if (null !== $host) {\n                $this->addHost($subCollection, $host);\n            }\n            if (null !== $condition) {\n                $subCollection->setCondition($condition);\n            }\n            if (null !== $schemes) {\n                $subCollection->setSchemes($schemes);\n            }\n            if (null !== $methods) {\n                $subCollection->setMethods($methods);\n            }\n            if (null !== $namePrefix) {\n                $subCollection->addNamePrefix($namePrefix);\n            }\n            $subCollection->addDefaults($defaults);\n            $subCollection->addRequirements($requirements);\n            $subCollection->addOptions($options);\n\n            $collection->addCollection($subCollection);\n        }\n    }\n\n    /**\n     * @throws \\InvalidArgumentException If one of the provided config keys is not supported,\n     *                                   something is missing or the combination is nonsense\n     */\n    private function validate(mixed $config, string $name, string $path): void\n    {\n        if (!\\is_array($config)) {\n            throw new \\InvalidArgumentException(\\sprintf('The definition of \"%s\" in \"%s\" must be an array.', $name, $path));\n        }\n        if (isset($config['alias'])) {\n            $this->validateAlias($config, $name, $path);\n\n            return;\n        }\n        if ($extraKeys = array_diff(array_keys($config), self::AVAILABLE_KEYS)) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" contains unsupported keys for \"%s\": \"%s\". Expected one of: \"%s\".', $path, $name, implode('\", \"', $extraKeys), implode('\", \"', self::AVAILABLE_KEYS)));\n        }\n        if (isset($config['resource']) && isset($config['path'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"resource\" key and the \"path\" key for \"%s\". Choose between an import and a route definition.', $path, $name));\n        }\n        if (!isset($config['resource']) && isset($config['type'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The \"type\" key for the route definition \"%s\" in \"%s\" is unsupported. It is only available for imports in combination with the \"resource\" key.', $name, $path));\n        }\n        if (!isset($config['resource']) && !isset($config['path'])) {\n            throw new \\InvalidArgumentException(\\sprintf('You must define a \"path\" for the route \"%s\" in file \"%s\".', $name, $path));\n        }\n        if (isset($config['controller']) && isset($config['defaults']['_controller'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"controller\" key and the defaults key \"_controller\" for \"%s\".', $path, $name));\n        }\n        if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"stateless\" key and the defaults key \"_stateless\" for \"%s\".', $path, $name));\n        }\n    }\n\n    /**\n     * @throws \\InvalidArgumentException If one of the provided config keys is not supported,\n     *                                   something is missing or the combination is nonsense\n     */\n    private function validateAlias(array $config, string $name, string $path): void\n    {\n        foreach ($config as $key => $value) {\n            if (!\\in_array($key, ['alias', 'deprecated'], true)) {\n                throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify other keys than \"alias\" and \"deprecated\" for \"%s\".', $path, $name));\n            }\n\n            if ('deprecated' === $key) {\n                if (!isset($value['package'])) {\n                    throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must specify the attribute \"package\" of the \"deprecated\" option for \"%s\".', $path, $name));\n                }\n\n                if (!isset($value['version'])) {\n                    throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must specify the attribute \"version\" of the \"deprecated\" option for \"%s\".', $path, $name));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Loader/DirectoryLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\FileLoader;\nuse Symfony\\Component\\Config\\Resource\\DirectoryResource;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass DirectoryLoader extends FileLoader\n{\n    public function load(mixed $file, ?string $type = null): mixed\n    {\n        $path = $this->locator->locate($file);\n\n        $collection = new RouteCollection();\n        $collection->addResource(new DirectoryResource($path));\n\n        foreach (scandir($path) as $dir) {\n            if ('.' !== $dir[0]) {\n                $this->setCurrentDir($path);\n                $subPath = $path.'/'.$dir;\n                $subType = null;\n\n                if (is_dir($subPath)) {\n                    $subPath .= '/';\n                    $subType = 'directory';\n                }\n\n                $subCollection = $this->import($subPath, $subType, false, $path);\n                $collection->addCollection($subCollection);\n            }\n        }\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        // only when type is forced to directory, not to conflict with AttributeLoader\n\n        return 'directory' === $type;\n    }\n}\n"
  },
  {
    "path": "Loader/GlobFileLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\FileLoader;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * GlobFileLoader loads files from a glob pattern.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass GlobFileLoader extends FileLoader\n{\n    public function load(mixed $resource, ?string $type = null): mixed\n    {\n        $collection = new RouteCollection();\n\n        foreach ($this->glob($resource, false, $globResource) as $path => $info) {\n            $collection->addCollection($this->import($path));\n        }\n\n        $collection->addResource($globResource);\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return 'glob' === $type;\n    }\n}\n"
  },
  {
    "path": "Loader/ObjectLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\Loader;\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * A route loader that calls a method on an object to load the routes.\n *\n * @author Ryan Weaver <ryan@knpuniversity.com>\n */\nabstract class ObjectLoader extends Loader\n{\n    /**\n     * Returns the object that the method will be called on to load routes.\n     *\n     * For example, if your application uses a service container,\n     * the $id may be a service id.\n     */\n    abstract protected function getObject(string $id): object;\n\n    /**\n     * Calls the object method that will load the routes.\n     */\n    public function load(mixed $resource, ?string $type = null): RouteCollection\n    {\n        if (!preg_match('/^[^\\:]+(?:::(?:[^\\:]+))?$/', $resource)) {\n            throw new \\InvalidArgumentException(\\sprintf('Invalid resource \"%s\" passed to the %s route loader: use the format \"object_id::method\" or \"object_id\" if your object class has an \"__invoke\" method.', $resource, \\is_string($type) ? '\"'.$type.'\"' : 'object'));\n        }\n\n        $parts = explode('::', $resource);\n        $method = $parts[1] ?? '__invoke';\n\n        $loaderObject = $this->getObject($parts[0]);\n\n        if (!\\is_callable([$loaderObject, $method])) {\n            throw new \\BadMethodCallException(\\sprintf('Method \"%s\" not found on \"%s\" when importing routing resource \"%s\".', $method, get_debug_type($loaderObject), $resource));\n        }\n\n        $routeCollection = $loaderObject->$method($this, $this->env);\n\n        if (!$routeCollection instanceof RouteCollection) {\n            $type = get_debug_type($routeCollection);\n\n            throw new \\LogicException(\\sprintf('The \"%s::%s()\" method must return a RouteCollection: \"%s\" returned.', get_debug_type($loaderObject), $method, $type));\n        }\n\n        // make the object file tracked so that if it changes, the cache rebuilds\n        $this->addClassResource(new \\ReflectionClass($loaderObject), $routeCollection);\n\n        return $routeCollection;\n    }\n\n    private function addClassResource(\\ReflectionClass $class, RouteCollection $collection): void\n    {\n        do {\n            if (is_file($class->getFileName())) {\n                $collection->addResource(new FileResource($class->getFileName()));\n            }\n        } while ($class = $class->getParentClass());\n    }\n}\n"
  },
  {
    "path": "Loader/PhpFileLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\FileLoader;\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Routes;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RoutesReference;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RoutingConfigurator;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * PhpFileLoader loads routes from a PHP file.\n *\n * The file must return a RouteCollection instance.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Nicolas grekas <p@tchwork.com>\n * @author Jules Pietri <jules@heahprod.com>\n */\nclass PhpFileLoader extends FileLoader\n{\n    use ContentLoaderTrait;\n\n    /**\n     * Loads a PHP file.\n     */\n    public function load(mixed $file, ?string $type = null): RouteCollection\n    {\n        $path = $this->locator->locate($file);\n        $this->setCurrentDir(\\dirname($path));\n\n        // Expose RoutesReference::config() as Routes::config()\n        if (!class_exists(Routes::class)) {\n            class_alias(RoutesReference::class, Routes::class);\n        }\n\n        // the closure forbids access to the private scope in the included file\n        $loader = $this;\n        $load = \\Closure::bind(static function ($file) use ($loader) {\n            return include $file;\n        }, null, null);\n\n        if (1 === $result = $load($path)) {\n            $result = null;\n        }\n\n        if (\\is_object($result) && \\is_callable($result)) {\n            $collection = $this->callConfigurator($result, $path, $file);\n        } elseif (\\is_array($result)) {\n            $collection = new RouteCollection();\n            $this->loadContent($collection, $result, $path, $file);\n        } elseif (!($collection = $result) instanceof RouteCollection) {\n            throw new InvalidArgumentException(\\sprintf('The return value in config file \"%s\" is expected to be a RouteCollection, an array or a configurator callable, but got \"%s\".', $path, get_debug_type($result)));\n        }\n\n        $collection->addResource(new FileResource($path));\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return \\is_string($resource) && 'php' === pathinfo($resource, \\PATHINFO_EXTENSION) && (!$type || 'php' === $type);\n    }\n\n    protected function callConfigurator(callable $callback, string $path, string $file): RouteCollection\n    {\n        $collection = new RouteCollection();\n\n        $callback(new RoutingConfigurator($collection, $this, $path, $file, $this->env));\n\n        return $collection;\n    }\n}\n"
  },
  {
    "path": "Loader/Psr4DirectoryLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\FileLocatorInterface;\nuse Symfony\\Component\\Config\\Loader\\DirectoryAwareLoaderInterface;\nuse Symfony\\Component\\Config\\Loader\\Loader;\nuse Symfony\\Component\\Config\\Resource\\DirectoryResource;\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * A loader that discovers controller classes in a directory that follows PSR-4.\n *\n * @author Alexander M. Turek <me@derrabus.de>\n */\nfinal class Psr4DirectoryLoader extends Loader implements DirectoryAwareLoaderInterface\n{\n    private ?string $currentDirectory = null;\n\n    public function __construct(\n        private readonly FileLocatorInterface $locator,\n    ) {\n        // PSR-4 directory loader has no env-aware logic, so we drop the $env constructor parameter.\n        parent::__construct();\n    }\n\n    /**\n     * @param array{path: string, namespace: string} $resource\n     */\n    public function load(mixed $resource, ?string $type = null): ?RouteCollection\n    {\n        $excluded = $resource['_excluded'] ?? [];\n        $path = $this->locator->locate($resource['path'], $this->currentDirectory);\n        if (!is_dir($path)) {\n            return new RouteCollection();\n        }\n\n        if (!preg_match('/^(?:[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+\\\\\\)++$/', trim($resource['namespace'], '\\\\').'\\\\')) {\n            throw new InvalidArgumentException(\\sprintf('Namespace \"%s\" is not a valid PSR-4 prefix.', $resource['namespace']));\n        }\n\n        return $this->loadFromDirectory($path, trim($resource['namespace'], '\\\\'), $excluded);\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return 'attribute' === $type && \\is_array($resource) && isset($resource['path'], $resource['namespace']);\n    }\n\n    public function forDirectory(string $currentDirectory): static\n    {\n        $loader = clone $this;\n        $loader->currentDirectory = $currentDirectory;\n\n        return $loader;\n    }\n\n    private function loadFromDirectory(string $directory, string $psr4Prefix, array $excluded = []): RouteCollection\n    {\n        $collection = new RouteCollection();\n        $collection->addResource(new DirectoryResource($directory, '/\\.php$/'));\n        $files = iterator_to_array(new \\RecursiveIteratorIterator(\n            new \\RecursiveCallbackFilterIterator(\n                new \\RecursiveDirectoryIterator($directory, \\FilesystemIterator::SKIP_DOTS | \\FilesystemIterator::FOLLOW_SYMLINKS),\n                static fn (\\SplFileInfo $current) => !str_starts_with($current->getBasename(), '.')\n            ),\n            \\RecursiveIteratorIterator::SELF_FIRST\n        ));\n        usort($files, static fn (\\SplFileInfo $a, \\SplFileInfo $b) => (string) $a > (string) $b ? 1 : -1);\n\n        /** @var \\SplFileInfo $file */\n        foreach ($files as $file) {\n            $normalizedPath = rtrim(str_replace('\\\\', '/', $file->getPathname()), '/');\n            if (isset($excluded[$normalizedPath])) {\n                continue;\n            }\n\n            if ($file->isDir()) {\n                $collection->addCollection($this->loadFromDirectory($file->getPathname(), $psr4Prefix.'\\\\'.$file->getFilename(), $excluded));\n\n                continue;\n            }\n            if ('php' !== $file->getExtension() || !class_exists($className = $psr4Prefix.'\\\\'.$file->getBasename('.php')) || (new \\ReflectionClass($className))->isAbstract()) {\n                continue;\n            }\n\n            $collection->addCollection($this->import($className, 'attribute'));\n        }\n\n        return $collection;\n    }\n}\n"
  },
  {
    "path": "Loader/YamlFileLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Loader;\n\nuse Symfony\\Component\\Config\\Loader\\FileLoader;\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Traits\\HostTrait;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Yaml\\Exception\\ParseException;\nuse Symfony\\Component\\Yaml\\Parser as YamlParser;\nuse Symfony\\Component\\Yaml\\Yaml;\n\n/**\n * YamlFileLoader loads Yaml routing files.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\nclass YamlFileLoader extends FileLoader\n{\n    use ContentLoaderTrait {\n        parseImport as doParseImport;\n        parseRoute as doParseRoute;\n        validate as doValidate;\n    }\n    use HostTrait;\n\n    private YamlParser $yamlParser;\n\n    /**\n     * @throws \\InvalidArgumentException When a route can't be parsed because YAML is invalid\n     */\n    public function load(mixed $file, ?string $type = null): RouteCollection\n    {\n        $path = $this->locator->locate($file);\n\n        if (!stream_is_local($path)) {\n            throw new \\InvalidArgumentException(\\sprintf('This is not a local file \"%s\".', $path));\n        }\n\n        if (!file_exists($path)) {\n            throw new \\InvalidArgumentException(\\sprintf('File \"%s\" not found.', $path));\n        }\n\n        $this->yamlParser ??= new YamlParser();\n\n        try {\n            $parsedConfig = $this->yamlParser->parseFile($path, Yaml::PARSE_CONSTANT);\n        } catch (ParseException $e) {\n            throw new \\InvalidArgumentException(\\sprintf('The file \"%s\" does not contain valid YAML: ', $path).$e->getMessage(), 0, $e);\n        }\n\n        $collection = new RouteCollection();\n        $collection->addResource(new FileResource($path));\n\n        // empty file\n        if (null === $parsedConfig) {\n            return $collection;\n        }\n\n        // not an array\n        if (!\\is_array($parsedConfig)) {\n            throw new \\InvalidArgumentException(\\sprintf('The file \"%s\" must contain a YAML array.', $path));\n        }\n\n        $this->loadContent($collection, $parsedConfig, $path, $file);\n\n        return $collection;\n    }\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return \\is_string($resource) && \\in_array(pathinfo($resource, \\PATHINFO_EXTENSION), ['yml', 'yaml'], true) && (!$type || 'yaml' === $type);\n    }\n\n    /**\n     * Parses a route and adds it to the RouteCollection.\n     */\n    protected function parseRoute(RouteCollection $collection, string $name, array $config, string $path): void\n    {\n        $this->doParseRoute($collection, $name, $config, $path);\n    }\n\n    /**\n     * Parses an import and adds the routes in the resource to the RouteCollection.\n     */\n    protected function parseImport(RouteCollection $collection, array $config, string $path, string $file): void\n    {\n        $this->doParseImport($collection, $config, $path, $file);\n    }\n\n    /**\n     * @throws \\InvalidArgumentException If one of the provided config keys is not supported,\n     *                                   something is missing or the combination is nonsense\n     */\n    protected function validate(mixed $config, string $name, string $path): void\n    {\n        $this->doValidate($config, $name, $path);\n    }\n}\n"
  },
  {
    "path": "Loader/schema/routing/routing-1.0.xsd",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n<xsd:schema xmlns=\"http://symfony.com/schema/routing\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    targetNamespace=\"http://symfony.com/schema/routing\"\n    elementFormDefault=\"qualified\">\n\n  <xsd:annotation>\n    <xsd:documentation><![CDATA[\n      Symfony XML Routing Schema, version 1.0\n      Authors: Fabien Potencier, Tobias Schultze\n\n      This scheme defines the elements and attributes that can be used to define\n      routes. A route maps an HTTP request to a set of configuration variables.\n    ]]></xsd:documentation>\n  </xsd:annotation>\n\n  <xsd:element name=\"routes\" type=\"routes\" />\n\n  <xsd:complexType name=\"routes\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"import\" type=\"import\" />\n      <xsd:element name=\"route\" type=\"route\" />\n      <xsd:element name=\"when\" type=\"when\" />\n    </xsd:choice>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"when\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"import\" type=\"import\" />\n      <xsd:element name=\"route\" type=\"route\" />\n    </xsd:choice>\n    <xsd:attribute name=\"env\" type=\"xsd:string\" use=\"required\" />\n  </xsd:complexType>\n\n  <xsd:complexType name=\"localized-path\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"locale\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:group name=\"configs\">\n    <xsd:choice>\n      <xsd:element name=\"default\" nillable=\"true\" type=\"default\" />\n      <xsd:element name=\"requirement\" type=\"element\" />\n      <xsd:element name=\"option\" type=\"element\" />\n      <xsd:element name=\"condition\" type=\"xsd:string\" />\n    </xsd:choice>\n  </xsd:group>\n\n  <xsd:complexType name=\"route\">\n    <xsd:sequence>\n      <xsd:group ref=\"configs\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"path\" type=\"localized-path\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"host\" type=\"localized-path\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"deprecated\" type=\"deprecated\" minOccurs=\"0\" maxOccurs=\"1\" />\n    </xsd:sequence>\n    <xsd:attribute name=\"id\" type=\"xsd:string\" use=\"required\" />\n    <xsd:attribute name=\"path\" type=\"xsd:string\" />\n    <xsd:attribute name=\"host\" type=\"xsd:string\" />\n    <xsd:attribute name=\"schemes\" type=\"xsd:string\" />\n    <xsd:attribute name=\"methods\" type=\"xsd:string\" />\n    <xsd:attribute name=\"controller\" type=\"xsd:string\" />\n    <xsd:attribute name=\"locale\" type=\"xsd:string\" />\n    <xsd:attribute name=\"format\" type=\"xsd:string\" />\n    <xsd:attribute name=\"utf8\" type=\"xsd:boolean\" />\n    <xsd:attribute name=\"stateless\" type=\"xsd:boolean\" />\n    <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n  </xsd:complexType>\n\n  <xsd:complexType name=\"import\">\n    <xsd:sequence maxOccurs=\"unbounded\" minOccurs=\"0\">\n      <xsd:group ref=\"configs\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"prefix\" type=\"localized-path\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"exclude\" type=\"xsd:string\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"host\" type=\"localized-path\" minOccurs=\"0\" maxOccurs=\"unbounded\" />\n      <xsd:element name=\"resource\" type=\"resource\" minOccurs=\"0\" maxOccurs=\"1\" />\n    </xsd:sequence>\n    <xsd:attribute name=\"resource\" type=\"xsd:string\" />\n    <xsd:attribute name=\"type\" type=\"xsd:string\" />\n    <xsd:attribute name=\"exclude\" type=\"xsd:string\" />\n    <xsd:attribute name=\"prefix\" type=\"xsd:string\" />\n    <xsd:attribute name=\"name-prefix\" type=\"xsd:string\" />\n    <xsd:attribute name=\"host\" type=\"xsd:string\" />\n    <xsd:attribute name=\"schemes\" type=\"xsd:string\" />\n    <xsd:attribute name=\"methods\" type=\"xsd:string\" />\n    <xsd:attribute name=\"controller\" type=\"xsd:string\" />\n    <xsd:attribute name=\"locale\" type=\"xsd:string\" />\n    <xsd:attribute name=\"format\" type=\"xsd:string\" />\n    <xsd:attribute name=\"trailing-slash-on-root\" type=\"xsd:boolean\" />\n    <xsd:attribute name=\"utf8\" type=\"xsd:boolean\" />\n    <xsd:attribute name=\"stateless\" type=\"xsd:boolean\" />\n  </xsd:complexType>\n\n  <xsd:complexType name=\"resource\">\n    <xsd:attribute name=\"path\" type=\"xsd:string\" />\n    <xsd:attribute name=\"namespace\" type=\"xsd:string\" />\n    <xsd:anyAttribute />\n  </xsd:complexType>\n\n  <xsd:complexType name=\"default\" mixed=\"true\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"1\">\n      <xsd:element name=\"bool\" type=\"xsd:boolean\" />\n      <xsd:element name=\"int\" type=\"xsd:integer\" />\n      <xsd:element name=\"float\" type=\"xsd:float\" />\n      <xsd:element name=\"string\" type=\"xsd:string\" />\n      <xsd:element name=\"list\" type=\"list\" />\n      <xsd:element name=\"map\" type=\"map\" />\n    </xsd:choice>\n    <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n  </xsd:complexType>\n\n  <xsd:complexType name=\"element\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"list\">\n    <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n      <xsd:element name=\"bool\" nillable=\"true\" type=\"xsd:boolean\" />\n      <xsd:element name=\"int\" nillable=\"true\" type=\"xsd:integer\" />\n      <xsd:element name=\"float\" nillable=\"true\" type=\"xsd:float\" />\n      <xsd:element name=\"string\" nillable=\"true\" type=\"xsd:string\" />\n      <xsd:element name=\"list\" nillable=\"true\" type=\"list\" />\n      <xsd:element name=\"map\" nillable=\"true\" type=\"map\" />\n    </xsd:choice>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map\">\n      <xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n          <xsd:element name=\"bool\" nillable=\"true\" type=\"map-bool-entry\" />\n          <xsd:element name=\"int\" nillable=\"true\" type=\"map-int-entry\" />\n          <xsd:element name=\"float\" nillable=\"true\" type=\"map-float-entry\" />\n          <xsd:element name=\"string\" nillable=\"true\" type=\"map-string-entry\" />\n          <xsd:element name=\"list\" nillable=\"true\" type=\"map-list-entry\" />\n          <xsd:element name=\"map\" nillable=\"true\" type=\"map-map-entry\" />\n      </xsd:choice>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map-bool-entry\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:boolean\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map-int-entry\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:integer\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map-float-entry\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:float\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map-string-entry\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map-list-entry\">\n    <xsd:complexContent>\n      <xsd:extension base=\"list\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"map-map-entry\">\n    <xsd:complexContent>\n      <xsd:extension base=\"map\">\n        <xsd:attribute name=\"key\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:complexContent>\n  </xsd:complexType>\n\n  <xsd:complexType name=\"deprecated\">\n    <xsd:simpleContent>\n      <xsd:extension base=\"xsd:string\">\n        <xsd:attribute name=\"package\" type=\"xsd:string\" use=\"required\" />\n        <xsd:attribute name=\"version\" type=\"xsd:string\" use=\"required\" />\n      </xsd:extension>\n    </xsd:simpleContent>\n  </xsd:complexType>\n</xsd:schema>\n"
  },
  {
    "path": "Loader/schema/routing.schema.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\": \"Symfony Routing Configuration\",\n  \"description\": \"Defines the application's URL routes, including imports and environment-specific conditionals.\",\n  \"type\": \"object\",\n  \"patternProperties\": {\n    \"^[a-zA-Z0-9_.-]+$\": {\n      \"oneOf\": [\n        { \"$ref\": \"#/$defs/routeDefinition\" },\n        { \"$ref\": \"#/$defs/routeImport\" },\n        { \"$ref\": \"#/$defs/routeAlias\" }\n      ]\n    },\n    \"^when@.+$\": {\n      \"$ref\": \"#\",\n      \"description\": \"A container for routes that are only loaded in a specific environment (e.g., 'when@dev').\"\n    }\n  },\n  \"additionalProperties\": false,\n  \"$defs\": {\n    \"routeDefinition\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"path\": {\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"object\", \"patternProperties\": { \"^.+$\": { \"type\": \"string\" } }, \"additionalProperties\": false }\n          ],\n          \"description\": \"The URL path or a map of locale=>path for localized routes.\"\n        },\n        \"controller\": {\n          \"type\": \"string\",\n          \"description\": \"The controller that handles the request, e.g., 'App\\\\Controller\\\\BlogController::show'.\"\n        },\n        \"methods\": {\n          \"description\": \"The HTTP method(s) this route matches.\",\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"array\", \"items\": { \"type\": \"string\" } }\n          ]\n        },\n        \"requirements\": {\n          \"type\": \"object\",\n          \"description\": \"Regular expression constraints for path parameters.\",\n          \"additionalProperties\": { \"type\": \"string\" }\n        },\n        \"defaults\": { \"type\": \"object\" },\n        \"options\": { \"type\": \"object\" },\n        \"host\": {\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"object\", \"patternProperties\": { \"^.+$\": { \"type\": \"string\" } }, \"additionalProperties\": false }\n          ]\n        },\n        \"schemes\": {\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"array\", \"items\": { \"type\": \"string\" } }\n          ]\n        },\n        \"condition\": { \"type\": \"string\" },\n        \"locale\": { \"type\": \"string\" },\n        \"format\": { \"type\": \"string\" },\n        \"utf8\": { \"type\": \"boolean\" },\n        \"stateless\": { \"type\": \"boolean\" },\n        \"deprecated\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"package\": { \"type\": \"string\" },\n            \"version\": { \"type\": \"string\" },\n            \"message\": { \"type\": \"string\" }\n          },\n          \"required\": [\"package\", \"version\"],\n          \"additionalProperties\": false\n        }\n      },\n      \"required\": [\"path\"],\n      \"additionalProperties\": false\n    },\n    \"routeImport\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"resource\": {\n          \"description\": \"Path to the resource to import (commonly a string or {path, namespace}), array of paths, or custom value for loaders (additional properties allowed for extensions).\",\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"array\", \"items\": { \"type\": \"string\" } },\n            {\n              \"type\": \"object\",\n              \"properties\": {\n                \"path\": { \"type\": \"string\", \"description\": \"The directory path to the resource.\" },\n                \"namespace\": { \"type\": \"string\", \"description\": \"The namespace of the controllers in the imported resource (e.g., 'App\\\\Availability\\\\UserInterface\\\\Api').\" }\n              },\n              \"required\": [\"path\"],\n              \"additionalProperties\": true\n            }\n          ]\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"description\": \"The type of the resource (e.g., 'attribute', 'annotation', 'yaml').\"\n        },\n        \"prefix\": {\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"object\", \"patternProperties\": { \"^.+$\": { \"type\": \"string\" } }, \"additionalProperties\": false }\n          ],\n          \"description\": \"A URL prefix to apply to all routes from the imported resource.\"\n        },\n        \"name_prefix\": {\n          \"type\": \"string\",\n          \"description\": \"A name prefix to apply to all routes from the imported resource.\"\n        },\n        \"requirements\": { \"type\": \"object\", \"additionalProperties\": { \"type\": \"string\" } },\n        \"defaults\": { \"type\": \"object\" },\n        \"options\": { \"type\": \"object\" },\n        \"host\": {\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"object\", \"patternProperties\": { \"^.+$\": { \"type\": \"string\" } }, \"additionalProperties\": false }\n          ]\n        },\n        \"schemes\": {\n          \"oneOf\": [\n            { \"type\": \"string\" },\n            { \"type\": \"array\", \"items\": { \"type\": \"string\" } }\n          ]\n        },\n        \"condition\": { \"type\": \"string\" },\n        \"trailing_slash_on_root\": { \"type\": \"boolean\" },\n        \"methods\": { \"oneOf\": [ { \"type\": \"string\" }, { \"type\": \"array\", \"items\": { \"type\": \"string\" } } ] },\n        \"locale\": { \"type\": \"string\" },\n        \"format\": { \"type\": \"string\" },\n        \"utf8\": { \"type\": \"boolean\" },\n        \"exclude\": { \"oneOf\": [ { \"type\": \"string\" }, { \"type\": \"array\", \"items\": { \"type\": \"string\" } } ] },\n        \"stateless\": { \"type\": \"boolean\" },\n        \"controller\": { \"type\": \"string\" }\n      },\n      \"required\": [\"resource\"],\n      \"additionalProperties\": false\n    },\n    \"routeAlias\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"alias\": { \"type\": \"string\" },\n        \"deprecated\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"package\": { \"type\": \"string\" },\n            \"version\": { \"type\": \"string\" },\n            \"message\": { \"type\": \"string\" }\n          },\n          \"required\": [\"package\", \"version\"],\n          \"additionalProperties\": false\n        }\n      },\n      \"required\": [\"alias\"],\n      \"additionalProperties\": false\n    }\n  }\n}\n"
  },
  {
    "path": "Matcher/CompiledUrlMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherTrait;\nuse Symfony\\Component\\Routing\\RequestContext;\n\n/**\n * Matches URLs based on rules dumped by CompiledUrlMatcherDumper.\n *\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass CompiledUrlMatcher extends UrlMatcher\n{\n    use CompiledUrlMatcherTrait;\n\n    public function __construct(array $compiledRoutes, RequestContext $context)\n    {\n        $this->context = $context;\n        [$this->matchHost, $this->staticRoutes, $this->regexpList, $this->dynamicRoutes, $this->checkCondition] = $compiledRoutes;\n    }\n}\n"
  },
  {
    "path": "Matcher/Dumper/CompiledUrlMatcherDumper.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher\\Dumper;\n\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface;\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * CompiledUrlMatcherDumper creates PHP arrays to be used with CompiledUrlMatcher.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n * @author Arnaud Le Blanc <arnaud.lb@gmail.com>\n * @author Nicolas Grekas <p@tchwork.com>\n */\nclass CompiledUrlMatcherDumper extends MatcherDumper\n{\n    private ExpressionLanguage $expressionLanguage;\n    private ?\\Exception $signalingException = null;\n\n    /**\n     * @var ExpressionFunctionProviderInterface[]\n     */\n    private array $expressionLanguageProviders = [];\n\n    public function dump(array $options = []): string\n    {\n        return <<<EOF\n            <?php\n\n            /**\n             * This file has been auto-generated\n             * by the Symfony Routing Component.\n             */\n\n            return [\n            {$this->generateCompiledRoutes()}];\n\n            EOF;\n    }\n\n    public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider): void\n    {\n        $this->expressionLanguageProviders[] = $provider;\n    }\n\n    /**\n     * Generates the arrays for CompiledUrlMatcher's constructor.\n     */\n    public function getCompiledRoutes(bool $forDump = false): array\n    {\n        // Group hosts by same-suffix, re-order when possible\n        $matchHost = false;\n        $routes = new StaticPrefixCollection();\n        foreach ($this->getRoutes()->all() as $name => $route) {\n            if ($host = $route->getHost()) {\n                $matchHost = true;\n                $host = '/'.strtr(strrev($host), '}.{', '(/)');\n            }\n\n            $routes->addRoute($host ?: '/(.*)', [$name, $route]);\n        }\n\n        if ($matchHost) {\n            $compiledRoutes = [true];\n            $routes = $routes->populateCollection(new RouteCollection());\n        } else {\n            $compiledRoutes = [false];\n            $routes = $this->getRoutes();\n        }\n\n        [$staticRoutes, $dynamicRoutes] = $this->groupStaticRoutes($routes);\n\n        $conditions = [null];\n        $compiledRoutes[] = $this->compileStaticRoutes($staticRoutes, $conditions);\n        $chunkLimit = \\count($dynamicRoutes);\n\n        while (true) {\n            try {\n                $this->signalingException = new \\RuntimeException('Compilation failed: regular expression is too large');\n                $compiledRoutes = array_merge($compiledRoutes, $this->compileDynamicRoutes($dynamicRoutes, $matchHost, $chunkLimit, $conditions));\n\n                break;\n            } catch (\\Exception $e) {\n                if (1 < $chunkLimit && $this->signalingException === $e) {\n                    $chunkLimit = 1 + ($chunkLimit >> 1);\n                    continue;\n                }\n                throw $e;\n            }\n        }\n\n        if ($forDump) {\n            $compiledRoutes[2] = $compiledRoutes[4];\n        }\n        unset($conditions[0]);\n\n        if ($conditions) {\n            foreach ($conditions as $expression => $condition) {\n                $conditions[$expression] = \"case {$condition}: return {$expression};\";\n            }\n\n            $checkConditionCode = <<<EOF\n                    static function (\\$condition, \\$context, \\$request, \\$params) { // \\$checkCondition\n                        switch (\\$condition) {\n                {$this->indent(implode(\"\\n\", $conditions), 3)}\n                        }\n                    }\n                EOF;\n            $compiledRoutes[4] = $forDump ? $checkConditionCode.\",\\n\" : eval('return '.$checkConditionCode.';');\n        } else {\n            $compiledRoutes[4] = $forDump ? \"    null, // \\$checkCondition\\n\" : null;\n        }\n\n        return $compiledRoutes;\n    }\n\n    private function generateCompiledRoutes(): string\n    {\n        [$matchHost, $staticRoutes, $regexpCode, $dynamicRoutes, $checkConditionCode] = $this->getCompiledRoutes(true);\n\n        $code = self::export($matchHost).', // $matchHost'.\"\\n\";\n\n        $code .= '[ // $staticRoutes'.\"\\n\";\n        foreach ($staticRoutes as $path => $routes) {\n            $code .= \\sprintf(\"    %s => [\\n\", self::export($path));\n            foreach ($routes as $route) {\n                $code .= vsprintf(\"        [%s, %s, %s, %s, %s, %s, %s],\\n\", array_map([__CLASS__, 'export'], $route));\n            }\n            $code .= \"    ],\\n\";\n        }\n        $code .= \"],\\n\";\n\n        $code .= \\sprintf(\"[ // \\$regexpList%s\\n],\\n\", $regexpCode);\n\n        $code .= '[ // $dynamicRoutes'.\"\\n\";\n        foreach ($dynamicRoutes as $path => $routes) {\n            $code .= \\sprintf(\"    %s => [\\n\", self::export($path));\n            foreach ($routes as $route) {\n                $code .= vsprintf(\"        [%s, %s, %s, %s, %s, %s, %s],\\n\", array_map([__CLASS__, 'export'], $route));\n            }\n            $code .= \"    ],\\n\";\n        }\n        $code .= \"],\\n\";\n        $code = preg_replace('/ => \\[\\n        (\\[.+?),\\n    \\],/', ' => [$1],', $code);\n\n        return $this->indent($code, 1).$checkConditionCode;\n    }\n\n    /**\n     * Splits static routes from dynamic routes, so that they can be matched first, using a simple switch.\n     */\n    private function groupStaticRoutes(RouteCollection $collection): array\n    {\n        $staticRoutes = $dynamicRegex = [];\n        $dynamicRoutes = new RouteCollection();\n\n        foreach ($collection->all() as $name => $route) {\n            $compiledRoute = $route->compile();\n            $staticPrefix = rtrim($compiledRoute->getStaticPrefix(), '/');\n            $hostRegex = $compiledRoute->getHostRegex();\n            $regex = $compiledRoute->getRegex();\n            if ($hasTrailingSlash = '/' !== $route->getPath()) {\n                $pos = strrpos($regex, '$');\n                $hasTrailingSlash = '/' === $regex[$pos - 1];\n                $regex = substr_replace($regex, '/?$', $pos - $hasTrailingSlash, 1 + $hasTrailingSlash);\n            }\n\n            if (!$compiledRoute->getPathVariables()) {\n                $host = !$compiledRoute->getHostVariables() ? $route->getHost() : '';\n                $url = $route->getPath();\n                if ($hasTrailingSlash) {\n                    $url = substr($url, 0, -1);\n                }\n                foreach ($dynamicRegex as [$hostRx, $rx, $prefix]) {\n                    if (('' === $prefix || str_starts_with($url, $prefix)) && (preg_match($rx, $url) || preg_match($rx, $url.'/')) && (!$host || !$hostRx || preg_match($hostRx, $host))) {\n                        $dynamicRegex[] = [$hostRegex, $regex, $staticPrefix];\n                        $dynamicRoutes->add($name, $route);\n                        continue 2;\n                    }\n                }\n\n                $staticRoutes[$url][$name] = [$route, $hasTrailingSlash];\n            } else {\n                $dynamicRegex[] = [$hostRegex, $regex, $staticPrefix];\n                $dynamicRoutes->add($name, $route);\n            }\n        }\n\n        return [$staticRoutes, $dynamicRoutes];\n    }\n\n    /**\n     * Compiles static routes in a switch statement.\n     *\n     * Condition-less paths are put in a static array in the switch's default, with generic matching logic.\n     * Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.\n     *\n     * @throws \\LogicException\n     */\n    private function compileStaticRoutes(array $staticRoutes, array &$conditions): array\n    {\n        if (!$staticRoutes) {\n            return [];\n        }\n        $compiledRoutes = [];\n\n        foreach ($staticRoutes as $url => $routes) {\n            $compiledRoutes[$url] = [];\n            foreach ($routes as $name => [$route, $hasTrailingSlash]) {\n                if ($route->compile()->getHostVariables()) {\n                    $host = $route->compile()->getHostRegex();\n                } elseif ($host = $route->getHost()) {\n                    $host = strtolower($host);\n                }\n                $compiledRoutes[$url][] = $this->compileRoute($route, $name, $host ?: null, $hasTrailingSlash, false, $conditions);\n            }\n        }\n\n        return $compiledRoutes;\n    }\n\n    /**\n     * Compiles a regular expression followed by a switch statement to match dynamic routes.\n     *\n     * The regular expression matches both the host and the pathinfo at the same time. For stellar performance,\n     * it is built as a tree of patterns, with re-ordering logic to group same-prefix routes together when possible.\n     *\n     * Patterns are named so that we know which one matched (https://pcre.org/current/doc/html/pcre2syntax.html#SEC23).\n     * This name is used to \"switch\" to the additional logic required to match the final route.\n     *\n     * Condition-less paths are put in a static array in the switch's default, with generic matching logic.\n     * Paths that can match two or more routes, or have user-specified conditions are put in separate switch's cases.\n     *\n     * Last but not least:\n     *  - Because it is not possible to mix unicode/non-unicode patterns in a single regexp, several of them can be generated.\n     *  - The same regexp can be used several times when the logic in the switch rejects the match. When this happens, the\n     *    matching-but-failing subpattern is excluded by replacing its name by \"(*F)\", which forces a failure-to-match.\n     *    To ease this backlisting operation, the name of subpatterns is also the string offset where the replacement should occur.\n     */\n    private function compileDynamicRoutes(RouteCollection $collection, bool $matchHost, int $chunkLimit, array &$conditions): array\n    {\n        if (!$collection->all()) {\n            return [[], [], ''];\n        }\n        $regexpList = [];\n        $code = '';\n        $state = (object) [\n            'regexMark' => 0,\n            'regex' => [],\n            'routes' => [],\n            'mark' => 0,\n            'markTail' => 0,\n            'hostVars' => [],\n            'vars' => [],\n        ];\n        $state->getVars = static function ($m) use ($state) {\n            if ('_route' === $m[1]) {\n                return '?:';\n            }\n\n            $state->vars[] = $m[1];\n\n            return '';\n        };\n\n        $chunkSize = 0;\n        $prev = null;\n        $perModifiers = [];\n        foreach ($collection->all() as $name => $route) {\n            preg_match('#[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);\n            if ($chunkLimit < ++$chunkSize || $prev !== $rx[0] && $route->compile()->getPathVariables()) {\n                $chunkSize = 1;\n                $routes = new RouteCollection();\n                $perModifiers[] = [$rx[0], $routes];\n                $prev = $rx[0];\n            }\n            $routes->add($name, $route);\n        }\n\n        foreach ($perModifiers as [$modifiers, $routes]) {\n            $prev = false;\n            $perHost = [];\n            foreach ($routes->all() as $name => $route) {\n                $regex = $route->compile()->getHostRegex();\n                if ($prev !== $regex) {\n                    $routes = new RouteCollection();\n                    $perHost[] = [$regex, $routes];\n                    $prev = $regex;\n                }\n                $routes->add($name, $route);\n            }\n            $prev = false;\n            $rx = '{^(?';\n            $code .= \"\\n    {$state->mark} => \".self::export($rx);\n            $startingMark = $state->mark;\n            $state->mark += \\strlen($rx);\n            $state->regex = $rx;\n\n            foreach ($perHost as [$hostRegex, $routes]) {\n                if ($matchHost) {\n                    if ($hostRegex) {\n                        preg_match('#^.\\^(.*)\\$.[a-zA-Z]*$#', $hostRegex, $rx);\n                        $state->vars = [];\n                        $hostRegex = '(?i:'.preg_replace_callback('#\\?P<([^>]++)>#', $state->getVars, $rx[1]).')\\.';\n                        $state->hostVars = $state->vars;\n                    } else {\n                        $hostRegex = '(?:(?:[^./]*+\\.)++)';\n                        $state->hostVars = [];\n                    }\n                    $state->mark += \\strlen($rx = ($prev ? ')' : '').\"|{$hostRegex}(?\");\n                    $code .= \"\\n        .\".self::export($rx);\n                    $state->regex .= $rx;\n                    $prev = true;\n                }\n\n                $tree = new StaticPrefixCollection();\n                foreach ($routes->all() as $name => $route) {\n                    preg_match('#^.\\^(.*)\\$.[a-zA-Z]*$#', $route->compile()->getRegex(), $rx);\n\n                    $state->vars = [];\n                    $regex = preg_replace_callback('#\\?P<([^>]++)>#', $state->getVars, $rx[1]);\n                    if ($hasTrailingSlash = '/' !== $regex && '/' === $regex[-1]) {\n                        $regex = substr($regex, 0, -1);\n                    }\n                    $hasTrailingVar = (bool) preg_match('#\\{[\\w\\x80-\\xFF]+\\}/?$#', $route->getPath());\n\n                    $tree->addRoute($regex, [$name, $regex, $state->vars, $route, $hasTrailingSlash, $hasTrailingVar]);\n                }\n\n                $code .= $this->compileStaticPrefixCollection($tree, $state, 0, $conditions);\n            }\n            if ($matchHost) {\n                $code .= \"\\n        .')'\";\n                $state->regex .= ')';\n            }\n            $rx = \")/?$}{$modifiers}\";\n            $code .= \"\\n        .'{$rx}',\";\n            $state->regex .= $rx;\n            $state->markTail = 0;\n\n            // if the regex is too large, throw a signaling exception to recompute with smaller chunk size\n            set_error_handler(fn ($type, $message) => throw str_contains($message, $this->signalingException->getMessage()) ? $this->signalingException : new \\ErrorException($message));\n            try {\n                preg_match($state->regex, '');\n            } finally {\n                restore_error_handler();\n            }\n\n            $regexpList[$startingMark] = $state->regex;\n        }\n\n        $state->routes[$state->mark][] = [null, null, null, null, false, false, 0];\n        unset($state->getVars);\n\n        return [$regexpList, $state->routes, $code];\n    }\n\n    /**\n     * Compiles a regexp tree of subpatterns that matches nested same-prefix routes.\n     *\n     * @param \\stdClass $state A simple state object that keeps track of the progress of the compilation,\n     *                         and gathers the generated switch's \"case\" and \"default\" statements\n     */\n    private function compileStaticPrefixCollection(StaticPrefixCollection $tree, \\stdClass $state, int $prefixLen, array &$conditions): string\n    {\n        $code = '';\n        $prevRegex = null;\n        $routes = $tree->getRoutes();\n\n        foreach ($routes as $i => $route) {\n            if ($route instanceof StaticPrefixCollection) {\n                $prevRegex = null;\n                $prefix = substr($route->getPrefix(), $prefixLen);\n                $state->mark += \\strlen($rx = \"|{$prefix}(?\");\n                $code .= \"\\n            .\".self::export($rx);\n                $state->regex .= $rx;\n                $code .= $this->indent($this->compileStaticPrefixCollection($route, $state, $prefixLen + \\strlen($prefix), $conditions));\n                $code .= \"\\n            .')'\";\n                $state->regex .= ')';\n                ++$state->markTail;\n                continue;\n            }\n\n            [$name, $regex, $vars, $route, $hasTrailingSlash, $hasTrailingVar] = $route;\n            $compiledRoute = $route->compile();\n            $vars = array_merge($state->hostVars, $vars);\n\n            if ($compiledRoute->getRegex() === $prevRegex) {\n                $state->routes[$state->mark][] = $this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions);\n                continue;\n            }\n\n            $state->mark += 3 + $state->markTail + \\strlen($regex) - $prefixLen;\n            $state->markTail = 2 + \\strlen($state->mark);\n            $rx = \\sprintf('|%s(*:%s)', substr($regex, $prefixLen), $state->mark);\n            $code .= \"\\n            .\".self::export($rx);\n            $state->regex .= $rx;\n\n            $prevRegex = $compiledRoute->getRegex();\n            $state->routes[$state->mark] = [$this->compileRoute($route, $name, $vars, $hasTrailingSlash, $hasTrailingVar, $conditions)];\n        }\n\n        return $code;\n    }\n\n    /**\n     * Compiles a single Route to PHP code used to match it against the path info.\n     */\n    private function compileRoute(Route $route, string $name, string|array|null $vars, bool $hasTrailingSlash, bool $hasTrailingVar, array &$conditions): array\n    {\n        $defaults = $route->getDefaults();\n\n        if (isset($defaults['_canonical_route'])) {\n            $name = $defaults['_canonical_route'];\n            unset($defaults['_canonical_route']);\n        }\n\n        if ($condition = $route->getCondition()) {\n            $condition = $this->getExpressionLanguage()->compile($condition, ['context', 'request', 'params']);\n            $condition = $conditions[$condition] ??= (str_contains($condition, '$request') ? 1 : -1) * \\count($conditions);\n        } else {\n            $condition = null;\n        }\n\n        return [\n            ['_route' => $name] + $defaults,\n            $vars,\n            array_flip($route->getMethods()) ?: null,\n            array_flip($route->getSchemes()) ?: null,\n            $hasTrailingSlash,\n            $hasTrailingVar,\n            $condition,\n        ];\n    }\n\n    private function getExpressionLanguage(): ExpressionLanguage\n    {\n        if (!isset($this->expressionLanguage)) {\n            if (!class_exists(ExpressionLanguage::class)) {\n                throw new \\LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running \"composer require symfony/expression-language\".');\n            }\n            $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);\n        }\n\n        return $this->expressionLanguage;\n    }\n\n    private function indent(string $code, int $level = 1): string\n    {\n        return preg_replace('/^./m', str_repeat('    ', $level).'$0', $code);\n    }\n\n    /**\n     * @internal\n     */\n    public static function export(mixed $value): string\n    {\n        if (null === $value) {\n            return 'null';\n        }\n        if (\\is_object($value)) {\n            throw new \\InvalidArgumentException(\\sprintf('Symfony\\Component\\Routing\\Route cannot contain objects, but \"%s\" given.', get_debug_type($value)));\n        }\n        if (!\\is_array($value)) {\n            return str_replace(\"\\n\", '\\'.\"\\n\".\\'', var_export($value, true));\n        }\n        if (!$value) {\n            return '[]';\n        }\n\n        $i = 0;\n        $export = '[';\n\n        foreach ($value as $k => $v) {\n            if ($i === $k) {\n                ++$i;\n            } else {\n                $export .= self::export($k).' => ';\n\n                if (\\is_int($k) && $i < $k) {\n                    $i = 1 + $k;\n                }\n            }\n\n            $export .= self::export($v).', ';\n        }\n\n        return substr_replace($export, ']', -2);\n    }\n}\n"
  },
  {
    "path": "Matcher/Dumper/CompiledUrlMatcherTrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher\\Dumper;\n\nuse Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException;\nuse Symfony\\Component\\Routing\\Exception\\NoConfigurationException;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\nuse Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface;\nuse Symfony\\Component\\Routing\\RequestContext;\n\n/**\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @internal\n *\n * @property RequestContext $context\n */\ntrait CompiledUrlMatcherTrait\n{\n    private bool $matchHost = false;\n    private array $staticRoutes = [];\n    private array $regexpList = [];\n    private array $dynamicRoutes = [];\n    private ?\\Closure $checkCondition;\n\n    public function match(string $pathinfo): array\n    {\n        $allow = $allowSchemes = [];\n        if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {\n            return $ret;\n        }\n        if ($allow) {\n            throw new MethodNotAllowedException(array_keys($allow));\n        }\n        if (!$this instanceof RedirectableUrlMatcherInterface) {\n            throw new ResourceNotFoundException(\\sprintf('No routes found for \"%s\".', $pathinfo));\n        }\n        if (!\\in_array($this->context->getMethod(), ['HEAD', 'GET'], true)) {\n            // no-op\n        } elseif ($allowSchemes) {\n            redirect_scheme:\n            $scheme = $this->context->getScheme();\n            $this->context->setScheme(key($allowSchemes));\n            try {\n                if ($ret = $this->doMatch($pathinfo)) {\n                    return $this->redirect($pathinfo, $ret['_route'], $this->context->getScheme()) + $ret;\n                }\n            } finally {\n                $this->context->setScheme($scheme);\n            }\n        } elseif ('' !== $trimmedPathinfo = rtrim($pathinfo, '/')) {\n            $pathinfo = $trimmedPathinfo === $pathinfo ? $pathinfo.'/' : $trimmedPathinfo;\n            if ($ret = $this->doMatch($pathinfo, $allow, $allowSchemes)) {\n                return $this->redirect($pathinfo, $ret['_route']) + $ret;\n            }\n            if ($allowSchemes) {\n                goto redirect_scheme;\n            }\n        }\n\n        throw new ResourceNotFoundException(\\sprintf('No routes found for \"%s\".', $pathinfo));\n    }\n\n    private function doMatch(string $pathinfo, array &$allow = [], array &$allowSchemes = []): array\n    {\n        $allow = $allowSchemes = [];\n        $pathinfo = '' === ($pathinfo = rawurldecode($pathinfo)) ? '/' : $pathinfo;\n        $trimmedPathinfo = '' === ($trimmedPathinfo = rtrim($pathinfo, '/')) ? '/' : $trimmedPathinfo;\n        $context = $this->context;\n        $requestMethod = $canonicalMethod = $context->getMethod();\n\n        if ($this->matchHost) {\n            $host = strtolower($context->getHost());\n        }\n\n        if ('HEAD' === $requestMethod) {\n            $canonicalMethod = 'GET';\n        }\n        $supportsRedirections = 'GET' === $canonicalMethod && $this instanceof RedirectableUrlMatcherInterface;\n\n        foreach ($this->staticRoutes[$trimmedPathinfo] ?? [] as [$ret, $requiredHost, $requiredMethods, $requiredSchemes, $hasTrailingSlash, , $condition]) {\n            if ($requiredHost) {\n                if ('{' !== $requiredHost[0] ? $requiredHost !== $host : !preg_match($requiredHost, $host, $hostMatches)) {\n                    continue;\n                }\n                if ('{' === $requiredHost[0] && $hostMatches) {\n                    $hostMatches['_route'] = $ret['_route'];\n                    $ret = $this->mergeDefaults($hostMatches, $ret);\n                }\n            }\n\n            if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ??= $this->request ?: $this->createRequest($pathinfo) : null, $ret)) {\n                continue;\n            }\n\n            if ('/' !== $pathinfo && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {\n                if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {\n                    return $allow = $allowSchemes = [];\n                }\n                continue;\n            }\n\n            $hasRequiredScheme = !$requiredSchemes || isset($requiredSchemes[$context->getScheme()]);\n            if ($hasRequiredScheme && $requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {\n                $allow += $requiredMethods;\n                continue;\n            }\n\n            if (!$hasRequiredScheme) {\n                $allowSchemes += $requiredSchemes;\n                continue;\n            }\n\n            return $ret;\n        }\n\n        $matchedPathinfo = $this->matchHost ? $host.'.'.$pathinfo : $pathinfo;\n\n        foreach ($this->regexpList as $offset => $regex) {\n            while (preg_match($regex, $matchedPathinfo, $matches)) {\n                foreach ($this->dynamicRoutes[$m = (int) $matches['MARK']] as [$ret, $vars, $requiredMethods, $requiredSchemes, $hasTrailingSlash, $hasTrailingVar, $condition]) {\n                    if (0 === $condition) { // marks the last route in the regexp\n                        continue 3;\n                    }\n\n                    $hasTrailingVar = $trimmedPathinfo !== $pathinfo && $hasTrailingVar;\n\n                    if ($hasTrailingVar && ($hasTrailingSlash || (null === $n = $matches[\\count($vars)] ?? null) || '/' !== ($n[-1] ?? '/')) && preg_match($regex, $this->matchHost ? $host.'.'.$trimmedPathinfo : $trimmedPathinfo, $n) && $m === (int) $n['MARK']) {\n                        if ($hasTrailingSlash) {\n                            $matches = $n;\n                        } else {\n                            $hasTrailingVar = false;\n                        }\n                    }\n\n                    foreach ($vars as $i => $v) {\n                        if (isset($matches[1 + $i])) {\n                            $ret[$v] = $matches[1 + $i];\n                        }\n                    }\n\n                    if ($condition && !($this->checkCondition)($condition, $context, 0 < $condition ? $request ??= $this->request ?: $this->createRequest($pathinfo) : null, $ret)) {\n                        continue;\n                    }\n\n                    if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {\n                        if ($supportsRedirections && (!$requiredMethods || isset($requiredMethods['GET']))) {\n                            return $allow = $allowSchemes = [];\n                        }\n                        continue;\n                    }\n\n                    if ($requiredSchemes && !isset($requiredSchemes[$context->getScheme()])) {\n                        $allowSchemes += $requiredSchemes;\n                        continue;\n                    }\n\n                    if ($requiredMethods && !isset($requiredMethods[$canonicalMethod]) && !isset($requiredMethods[$requestMethod])) {\n                        $allow += $requiredMethods;\n                        continue;\n                    }\n\n                    return $ret;\n                }\n\n                $regex = substr_replace($regex, 'F', $m - $offset, 1 + \\strlen($m));\n                $offset += \\strlen($m);\n            }\n        }\n\n        if ('/' === $pathinfo && !$allow && !$allowSchemes) {\n            throw new NoConfigurationException();\n        }\n\n        return [];\n    }\n}\n"
  },
  {
    "path": "Matcher/Dumper/MatcherDumper.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher\\Dumper;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * MatcherDumper is the abstract class for all built-in matcher dumpers.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nabstract class MatcherDumper implements MatcherDumperInterface\n{\n    public function __construct(\n        private RouteCollection $routes,\n    ) {\n    }\n\n    public function getRoutes(): RouteCollection\n    {\n        return $this->routes;\n    }\n}\n"
  },
  {
    "path": "Matcher/Dumper/MatcherDumperInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher\\Dumper;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * MatcherDumperInterface is the interface that all matcher dumper classes must implement.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface MatcherDumperInterface\n{\n    /**\n     * Dumps a set of routes to a string representation of executable code\n     * that can then be used to match a request against these routes.\n     */\n    public function dump(array $options = []): string;\n\n    /**\n     * Gets the routes to dump.\n     */\n    public function getRoutes(): RouteCollection;\n}\n"
  },
  {
    "path": "Matcher/Dumper/StaticPrefixCollection.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher\\Dumper;\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * Prefix tree of routes preserving routes order.\n *\n * @author Frank de Jonge <info@frankdejonge.nl>\n * @author Nicolas Grekas <p@tchwork.com>\n *\n * @internal\n */\nclass StaticPrefixCollection\n{\n    /**\n     * @var string[]\n     */\n    private array $staticPrefixes = [];\n\n    /**\n     * @var string[]\n     */\n    private array $prefixes = [];\n\n    /**\n     * @var array[]|self[]\n     */\n    private array $items = [];\n\n    public function __construct(\n        private string $prefix = '/',\n    ) {\n    }\n\n    public function getPrefix(): string\n    {\n        return $this->prefix;\n    }\n\n    /**\n     * @return array[]|self[]\n     */\n    public function getRoutes(): array\n    {\n        return $this->items;\n    }\n\n    /**\n     * Adds a route to a group.\n     */\n    public function addRoute(string $prefix, array|self $route): void\n    {\n        [$prefix, $staticPrefix] = $this->getCommonPrefix($prefix, $prefix);\n\n        for ($i = \\count($this->items) - 1; 0 <= $i; --$i) {\n            $item = $this->items[$i];\n\n            [$commonPrefix, $commonStaticPrefix] = $this->getCommonPrefix($prefix, $this->prefixes[$i]);\n\n            if ($this->prefix === $commonPrefix) {\n                // the new route and a previous one have no common prefix, let's see if they are exclusive to each others\n\n                if ($this->prefix !== $staticPrefix && $this->prefix !== $this->staticPrefixes[$i]) {\n                    // the new route and the previous one have exclusive static prefixes\n                    continue;\n                }\n\n                if ($this->prefix === $staticPrefix && $this->prefix === $this->staticPrefixes[$i]) {\n                    // the new route and the previous one have no static prefix\n                    break;\n                }\n\n                if ($this->prefixes[$i] !== $this->staticPrefixes[$i] && $this->prefix === $this->staticPrefixes[$i]) {\n                    // the previous route is non-static and has no static prefix\n                    break;\n                }\n\n                if ($prefix !== $staticPrefix && $this->prefix === $staticPrefix) {\n                    // the new route is non-static and has no static prefix\n                    break;\n                }\n\n                continue;\n            }\n\n            if ($item instanceof self && $this->prefixes[$i] === $commonPrefix) {\n                // the new route is a child of a previous one, let's nest it\n                $item->addRoute($prefix, $route);\n            } else {\n                // the new route and a previous one have a common prefix, let's merge them\n                $child = new self($commonPrefix);\n                [$child->prefixes[0], $child->staticPrefixes[0]] = $child->getCommonPrefix($this->prefixes[$i], $this->prefixes[$i]);\n                [$child->prefixes[1], $child->staticPrefixes[1]] = $child->getCommonPrefix($prefix, $prefix);\n                $child->items = [$this->items[$i], $route];\n\n                $this->staticPrefixes[$i] = $commonStaticPrefix;\n                $this->prefixes[$i] = $commonPrefix;\n                $this->items[$i] = $child;\n            }\n\n            return;\n        }\n\n        // No optimised case was found, in this case we simple add the route for possible\n        // grouping when new routes are added.\n        $this->staticPrefixes[] = $staticPrefix;\n        $this->prefixes[] = $prefix;\n        $this->items[] = $route;\n    }\n\n    /**\n     * Linearizes back a set of nested routes into a collection.\n     */\n    public function populateCollection(RouteCollection $routes): RouteCollection\n    {\n        foreach ($this->items as $route) {\n            if ($route instanceof self) {\n                $route->populateCollection($routes);\n            } else {\n                $routes->add(...$route);\n            }\n        }\n\n        return $routes;\n    }\n\n    /**\n     * Gets the full and static common prefixes between two route patterns.\n     *\n     * The static prefix stops at last at the first opening bracket.\n     */\n    private function getCommonPrefix(string $prefix, string $anotherPrefix): array\n    {\n        $baseLength = \\strlen($this->prefix);\n        $end = min(\\strlen($prefix), \\strlen($anotherPrefix));\n        $staticLength = null;\n        set_error_handler(self::handleError(...));\n\n        try {\n            for ($i = $baseLength; $i < $end && $prefix[$i] === $anotherPrefix[$i]; ++$i) {\n                if ('(' === $prefix[$i]) {\n                    $staticLength ??= $i;\n                    for ($j = 1 + $i, $n = 1; $j < $end && 0 < $n; ++$j) {\n                        if ($prefix[$j] !== $anotherPrefix[$j]) {\n                            break 2;\n                        }\n                        if ('(' === $prefix[$j]) {\n                            ++$n;\n                        } elseif (')' === $prefix[$j]) {\n                            --$n;\n                        } elseif ('\\\\' === $prefix[$j] && (++$j === $end || $prefix[$j] !== $anotherPrefix[$j])) {\n                            --$j;\n                            break;\n                        }\n                    }\n                    if (0 < $n) {\n                        break;\n                    }\n                    if (('?' === ($prefix[$j] ?? '') || '?' === ($anotherPrefix[$j] ?? '')) && ($prefix[$j] ?? '') !== ($anotherPrefix[$j] ?? '')) {\n                        break;\n                    }\n                    $subPattern = substr($prefix, $i, $j - $i);\n                    if ($prefix !== $anotherPrefix && !preg_match('/^\\(\\[[^\\]]++\\]\\+\\+\\)$/', $subPattern) && !preg_match('{(?<!'.$subPattern.')}', '')) {\n                        // sub-patterns of variable length are not considered as common prefixes because their greediness would break in-order matching\n                        break;\n                    }\n                    $i = $j - 1;\n                } elseif ('\\\\' === $prefix[$i] && (++$i === $end || $prefix[$i] !== $anotherPrefix[$i])) {\n                    --$i;\n                    break;\n                }\n            }\n        } finally {\n            restore_error_handler();\n        }\n        if ($i < $end && 0b10 === (\\ord($prefix[$i]) >> 6) && preg_match('//u', $prefix.' '.$anotherPrefix)) {\n            do {\n                // Prevent cutting in the middle of an UTF-8 characters\n                --$i;\n            } while (0b10 === (\\ord($prefix[$i]) >> 6));\n        }\n\n        return [substr($prefix, 0, $i), substr($prefix, 0, $staticLength ?? $i)];\n    }\n\n    public static function handleError(int $type, string $msg): bool\n    {\n        return str_contains($msg, 'Compilation failed: lookbehind assertion is not fixed length')\n            || str_contains($msg, 'Compilation failed: length of lookbehind assertion is not limited');\n    }\n}\n"
  },
  {
    "path": "Matcher/ExpressionLanguageProvider.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionFunction;\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface;\nuse Symfony\\Contracts\\Service\\ServiceProviderInterface;\n\n/**\n * Exposes functions defined in the request context to route conditions.\n *\n * @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>\n */\nclass ExpressionLanguageProvider implements ExpressionFunctionProviderInterface\n{\n    public function __construct(\n        private ServiceProviderInterface $functions,\n    ) {\n    }\n\n    public function getFunctions(): array\n    {\n        $functions = [];\n\n        foreach ($this->functions->getProvidedServices() as $function => $type) {\n            $functions[] = new ExpressionFunction(\n                $function,\n                static fn (...$args) => \\sprintf('($context->getParameter(\\'_functions\\')->get(%s)(%s))', var_export($function, true), implode(', ', $args)),\n                static fn ($values, ...$args) => $values['context']->getParameter('_functions')->get($function)(...$args)\n            );\n        }\n\n        return $functions;\n    }\n\n    public function get(string $function): callable\n    {\n        return $this->functions->get($function);\n    }\n}\n"
  },
  {
    "path": "Matcher/RedirectableUrlMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\Routing\\Exception\\ExceptionInterface;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\n\n/**\n * @author Fabien Potencier <fabien@symfony.com>\n */\nabstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface\n{\n    public function match(string $pathinfo): array\n    {\n        try {\n            return parent::match($pathinfo);\n        } catch (ResourceNotFoundException $e) {\n            if (!\\in_array($this->context->getMethod(), ['HEAD', 'GET'], true)) {\n                throw $e;\n            }\n\n            if ($this->allowSchemes) {\n                redirect_scheme:\n                $scheme = $this->context->getScheme();\n                $this->context->setScheme(current($this->allowSchemes));\n                try {\n                    $ret = parent::match($pathinfo);\n\n                    return $this->redirect($pathinfo, $ret['_route'] ?? null, $this->context->getScheme()) + $ret;\n                } catch (ExceptionInterface) {\n                    throw $e;\n                } finally {\n                    $this->context->setScheme($scheme);\n                }\n            } elseif ('' === $trimmedPathinfo = rtrim($pathinfo, '/')) {\n                throw $e;\n            } else {\n                try {\n                    $pathinfo = $trimmedPathinfo === $pathinfo ? $pathinfo.'/' : $trimmedPathinfo;\n                    $ret = parent::match($pathinfo);\n\n                    return $this->redirect($pathinfo, $ret['_route'] ?? null) + $ret;\n                } catch (ExceptionInterface) {\n                    if ($this->allowSchemes) {\n                        goto redirect_scheme;\n                    }\n                    throw $e;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Matcher/RedirectableUrlMatcherInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\n/**\n * RedirectableUrlMatcherInterface knows how to redirect the user.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface RedirectableUrlMatcherInterface\n{\n    /**\n     * Redirects the user to another URL and returns the parameters for the redirection.\n     *\n     * @param string      $path   The path info to redirect to\n     * @param string      $route  The route name that matched\n     * @param string|null $scheme The URL scheme (null to keep the current one)\n     */\n    public function redirect(string $path, string $route, ?string $scheme = null): array;\n}\n"
  },
  {
    "path": "Matcher/RequestMatcherInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException;\nuse Symfony\\Component\\Routing\\Exception\\NoConfigurationException;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\n\n/**\n * RequestMatcherInterface is the interface that all request matcher classes must implement.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface RequestMatcherInterface\n{\n    /**\n     * Tries to match a request with a set of routes.\n     *\n     * If the matcher cannot find information, it must throw one of the exceptions documented\n     * below.\n     *\n     * @throws NoConfigurationException  If no routing configuration could be found\n     * @throws ResourceNotFoundException If no matching resource could be found\n     * @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed\n     */\n    public function matchRequest(Request $request): array;\n}\n"
  },
  {
    "path": "Matcher/TraceableUrlMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Exception\\ExceptionInterface;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * TraceableUrlMatcher helps debug path info matching by tracing the match.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass TraceableUrlMatcher extends UrlMatcher\n{\n    public const ROUTE_DOES_NOT_MATCH = 0;\n    public const ROUTE_ALMOST_MATCHES = 1;\n    public const ROUTE_MATCHES = 2;\n\n    protected array $traces;\n\n    public function getTraces(string $pathinfo): array\n    {\n        $this->traces = [];\n\n        try {\n            $this->match($pathinfo);\n        } catch (ExceptionInterface) {\n        }\n\n        return $this->traces;\n    }\n\n    public function getTracesForRequest(Request $request): array\n    {\n        $this->request = $request;\n        $traces = $this->getTraces($request->getPathInfo());\n        $this->request = null;\n\n        return $traces;\n    }\n\n    protected function matchCollection(string $pathinfo, RouteCollection $routes): array\n    {\n        // HEAD and GET are equivalent as per RFC\n        if ('HEAD' === $method = $this->context->getMethod()) {\n            $method = 'GET';\n        }\n        $supportsTrailingSlash = 'GET' === $method && $this instanceof RedirectableUrlMatcherInterface;\n        $trimmedPathinfo = '' === ($trimmedPathinfo = rtrim($pathinfo, '/')) ? '/' : $trimmedPathinfo;\n\n        foreach ($routes as $name => $route) {\n            $compiledRoute = $route->compile();\n            $staticPrefix = rtrim($compiledRoute->getStaticPrefix(), '/');\n            $requiredMethods = $route->getMethods();\n\n            // check the static prefix of the URL first. Only use the more expensive preg_match when it matches\n            if ('' !== $staticPrefix && !str_starts_with($trimmedPathinfo, $staticPrefix)) {\n                $this->addTrace(\\sprintf('Path \"%s\" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);\n                continue;\n            }\n            $regex = $compiledRoute->getRegex();\n\n            $pos = strrpos($regex, '$');\n            $hasTrailingSlash = '/' === $regex[$pos - 1];\n            $regex = substr_replace($regex, '/?$', $pos - $hasTrailingSlash, 1 + $hasTrailingSlash);\n\n            if (!preg_match($regex, $pathinfo, $matches)) {\n                // does it match without any requirements?\n                $r = new Route($route->getPath(), $route->getDefaults(), [], $route->getOptions());\n                $cr = $r->compile();\n                if (!preg_match($cr->getRegex(), $pathinfo)) {\n                    $this->addTrace(\\sprintf('Path \"%s\" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);\n\n                    continue;\n                }\n\n                foreach ($route->getRequirements() as $n => $regex) {\n                    $r = new Route($route->getPath(), $route->getDefaults(), [$n => $regex], $route->getOptions());\n                    $cr = $r->compile();\n\n                    if (\\in_array($n, $cr->getVariables()) && !preg_match($cr->getRegex(), $pathinfo)) {\n                        $this->addTrace(\\sprintf('Requirement for \"%s\" does not match (%s)', $n, $regex), self::ROUTE_ALMOST_MATCHES, $name, $route);\n\n                        continue 2;\n                    }\n                }\n\n                continue;\n            }\n\n            $hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\\{[\\w\\x80-\\xFF]+\\}/?$#', $route->getPath());\n\n            if ($hasTrailingVar && ($hasTrailingSlash || (null === $m = $matches[\\count($compiledRoute->getPathVariables())] ?? null) || '/' !== ($m[-1] ?? '/')) && preg_match($regex, $trimmedPathinfo, $m)) {\n                if ($hasTrailingSlash) {\n                    $matches = $m;\n                } else {\n                    $hasTrailingVar = false;\n                }\n            }\n\n            $hostMatches = [];\n            if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {\n                $this->addTrace(\\sprintf('Host \"%s\" does not match the requirement (\"%s\")', $this->context->getHost(), $route->getHost()), self::ROUTE_ALMOST_MATCHES, $name, $route);\n                continue;\n            }\n\n            $attributes = $this->getAttributes($route, $name, array_replace($matches, $hostMatches));\n\n            $status = $this->handleRouteRequirements($pathinfo, $name, $route, $attributes);\n\n            if (self::REQUIREMENT_MISMATCH === $status[0]) {\n                $this->addTrace(\\sprintf('Condition \"%s\" does not evaluate to \"true\"', $route->getCondition()), self::ROUTE_ALMOST_MATCHES, $name, $route);\n                continue;\n            }\n\n            if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {\n                if ($supportsTrailingSlash && (!$requiredMethods || \\in_array('GET', $requiredMethods, true))) {\n                    $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);\n\n                    return $this->allow = $this->allowSchemes = [];\n                }\n                $this->addTrace(\\sprintf('Path \"%s\" does not match', $route->getPath()), self::ROUTE_DOES_NOT_MATCH, $name, $route);\n                continue;\n            }\n\n            if ($route->getSchemes() && !$route->hasScheme($this->context->getScheme())) {\n                $this->allowSchemes = array_merge($this->allowSchemes, $route->getSchemes());\n                $this->addTrace(\\sprintf('Scheme \"%s\" does not match any of the required schemes (%s)', $this->context->getScheme(), implode(', ', $route->getSchemes())), self::ROUTE_ALMOST_MATCHES, $name, $route);\n                continue;\n            }\n\n            if ($requiredMethods && !\\in_array($method, $requiredMethods, true)) {\n                $this->allow = array_merge($this->allow, $requiredMethods);\n                $this->addTrace(\\sprintf('Method \"%s\" does not match any of the required methods (%s)', $this->context->getMethod(), implode(', ', $requiredMethods)), self::ROUTE_ALMOST_MATCHES, $name, $route);\n                continue;\n            }\n\n            $this->addTrace('Route matches!', self::ROUTE_MATCHES, $name, $route);\n\n            return array_replace($attributes, $status[1] ?? []);\n        }\n\n        return [];\n    }\n\n    private function addTrace(string $log, int $level = self::ROUTE_DOES_NOT_MATCH, ?string $name = null, ?Route $route = null): void\n    {\n        $this->traces[] = [\n            'log' => $log,\n            'name' => $name,\n            'level' => $level,\n            'path' => $route?->getPath(),\n        ];\n    }\n}\n"
  },
  {
    "path": "Matcher/UrlMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface;\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException;\nuse Symfony\\Component\\Routing\\Exception\\NoConfigurationException;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n/**\n * UrlMatcher matches URL based on a set of routes.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface\n{\n    public const REQUIREMENT_MATCH = 0;\n    public const REQUIREMENT_MISMATCH = 1;\n    public const ROUTE_MATCH = 2;\n\n    /**\n     * Collects HTTP methods that would be allowed for the request.\n     */\n    protected array $allow = [];\n\n    /**\n     * Collects URI schemes that would be allowed for the request.\n     *\n     * @internal\n     */\n    protected array $allowSchemes = [];\n    protected ?Request $request = null;\n    protected ExpressionLanguage $expressionLanguage;\n\n    /**\n     * @var ExpressionFunctionProviderInterface[]\n     */\n    protected array $expressionLanguageProviders = [];\n\n    public function __construct(\n        protected RouteCollection $routes,\n        protected RequestContext $context,\n    ) {\n    }\n\n    public function setContext(RequestContext $context): void\n    {\n        $this->context = $context;\n    }\n\n    public function getContext(): RequestContext\n    {\n        return $this->context;\n    }\n\n    public function match(string $pathinfo): array\n    {\n        $this->allow = $this->allowSchemes = [];\n        $pathinfo = '' === ($pathinfo = rawurldecode($pathinfo)) ? '/' : $pathinfo;\n\n        if ($ret = $this->matchCollection($pathinfo, $this->routes)) {\n            return $ret;\n        }\n\n        if ('/' === $pathinfo && !$this->allow && !$this->allowSchemes) {\n            throw new NoConfigurationException();\n        }\n\n        throw 0 < \\count($this->allow) ? new MethodNotAllowedException(array_unique($this->allow)) : new ResourceNotFoundException(\\sprintf('No routes found for \"%s\".', $pathinfo));\n    }\n\n    public function matchRequest(Request $request): array\n    {\n        $this->request = $request;\n\n        $ret = $this->match($request->getPathInfo());\n\n        $this->request = null;\n\n        return $ret;\n    }\n\n    public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider): void\n    {\n        $this->expressionLanguageProviders[] = $provider;\n    }\n\n    /**\n     * Tries to match a URL with a set of routes.\n     *\n     * @param string $pathinfo The path info to be parsed\n     *\n     * @throws NoConfigurationException  If no routing configuration could be found\n     * @throws ResourceNotFoundException If the resource could not be found\n     * @throws MethodNotAllowedException If the resource was found but the request method is not allowed\n     */\n    protected function matchCollection(string $pathinfo, RouteCollection $routes): array\n    {\n        // HEAD and GET are equivalent as per RFC\n        if ('HEAD' === $method = $this->context->getMethod()) {\n            $method = 'GET';\n        }\n        $supportsTrailingSlash = 'GET' === $method && $this instanceof RedirectableUrlMatcherInterface;\n        $trimmedPathinfo = '' === ($trimmedPathinfo = rtrim($pathinfo, '/')) ? '/' : $trimmedPathinfo;\n\n        foreach ($routes as $name => $route) {\n            $compiledRoute = $route->compile();\n            $staticPrefix = rtrim($compiledRoute->getStaticPrefix(), '/');\n            $requiredMethods = $route->getMethods();\n\n            // check the static prefix of the URL first. Only use the more expensive preg_match when it matches\n            if ('' !== $staticPrefix && !str_starts_with($trimmedPathinfo, $staticPrefix)) {\n                continue;\n            }\n            $regex = $compiledRoute->getRegex();\n\n            $pos = strrpos($regex, '$');\n            $hasTrailingSlash = '/' === $regex[$pos - 1];\n            $regex = substr_replace($regex, '/?$', $pos - $hasTrailingSlash, 1 + $hasTrailingSlash);\n\n            if (!preg_match($regex, $pathinfo, $matches)) {\n                continue;\n            }\n\n            $hasTrailingVar = $trimmedPathinfo !== $pathinfo && preg_match('#\\{[\\w\\x80-\\xFF]+\\}/?$#', $route->getPath());\n\n            if ($hasTrailingVar && ($hasTrailingSlash || (null === $m = $matches[\\count($compiledRoute->getPathVariables())] ?? null) || '/' !== ($m[-1] ?? '/')) && preg_match($regex, $trimmedPathinfo, $m)) {\n                if ($hasTrailingSlash) {\n                    $matches = $m;\n                } else {\n                    $hasTrailingVar = false;\n                }\n            }\n\n            $hostMatches = [];\n            if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {\n                continue;\n            }\n\n            $attributes = $this->getAttributes($route, $name, array_replace($matches, $hostMatches));\n\n            $status = $this->handleRouteRequirements($pathinfo, $name, $route, $attributes);\n\n            if (self::REQUIREMENT_MISMATCH === $status[0]) {\n                continue;\n            }\n\n            if ('/' !== $pathinfo && !$hasTrailingVar && $hasTrailingSlash === ($trimmedPathinfo === $pathinfo)) {\n                if ($supportsTrailingSlash && (!$requiredMethods || \\in_array('GET', $requiredMethods, true))) {\n                    return $this->allow = $this->allowSchemes = [];\n                }\n                continue;\n            }\n\n            if ($route->getSchemes() && !$route->hasScheme($this->context->getScheme())) {\n                $this->allowSchemes = array_merge($this->allowSchemes, $route->getSchemes());\n                continue;\n            }\n\n            if ($requiredMethods && !\\in_array($method, $requiredMethods, true)) {\n                $this->allow = array_merge($this->allow, $requiredMethods);\n                continue;\n            }\n\n            return array_replace($attributes, $status[1] ?? []);\n        }\n\n        return [];\n    }\n\n    /**\n     * Returns an array of values to use as request attributes.\n     *\n     * As this method requires the Route object, it is not available\n     * in matchers that do not have access to the matched Route instance\n     * (like the PHP and Apache matcher dumpers).\n     */\n    protected function getAttributes(Route $route, string $name, array $attributes): array\n    {\n        $defaults = $route->getDefaults();\n        if (isset($defaults['_canonical_route'])) {\n            $name = $defaults['_canonical_route'];\n            unset($defaults['_canonical_route']);\n        }\n        $attributes['_route'] = $name;\n\n        if ($mapping = $route->getOption('mapping')) {\n            $attributes['_route_mapping'] = $mapping;\n        }\n\n        return $this->mergeDefaults($attributes, $defaults);\n    }\n\n    /**\n     * Handles specific route requirements.\n     *\n     * @return array The first element represents the status, the second contains additional information\n     */\n    protected function handleRouteRequirements(string $pathinfo, string $name, Route $route, array $routeParameters): array\n    {\n        // expression condition\n        if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), [\n            'context' => $this->context,\n            'request' => $this->request ?: $this->createRequest($pathinfo),\n            'params' => $routeParameters,\n        ])) {\n            return [self::REQUIREMENT_MISMATCH, null];\n        }\n\n        return [self::REQUIREMENT_MATCH, null];\n    }\n\n    /**\n     * Get merged default parameters.\n     */\n    protected function mergeDefaults(array $params, array $defaults): array\n    {\n        foreach ($params as $key => $value) {\n            if (!\\is_int($key) && null !== $value) {\n                $defaults[$key] = $value;\n            }\n        }\n\n        return $defaults;\n    }\n\n    protected function getExpressionLanguage(): ExpressionLanguage\n    {\n        if (!isset($this->expressionLanguage)) {\n            if (!class_exists(ExpressionLanguage::class)) {\n                throw new \\LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed. Try running \"composer require symfony/expression-language\".');\n            }\n            $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);\n        }\n\n        return $this->expressionLanguage;\n    }\n\n    /**\n     * @internal\n     */\n    protected function createRequest(string $pathinfo): ?Request\n    {\n        if (!class_exists(Request::class)) {\n            return null;\n        }\n\n        return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), [], [], [\n            'SCRIPT_FILENAME' => $this->context->getBaseUrl(),\n            'SCRIPT_NAME' => $this->context->getBaseUrl(),\n        ]);\n    }\n}\n"
  },
  {
    "path": "Matcher/UrlMatcherInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Matcher;\n\nuse Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException;\nuse Symfony\\Component\\Routing\\Exception\\NoConfigurationException;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\nuse Symfony\\Component\\Routing\\RequestContextAwareInterface;\n\n/**\n * UrlMatcherInterface is the interface that all URL matcher classes must implement.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface UrlMatcherInterface extends RequestContextAwareInterface\n{\n    /**\n     * Tries to match a URL path with a set of routes.\n     *\n     * If the matcher cannot find information, it must throw one of the exceptions documented\n     * below.\n     *\n     * @param string $pathinfo The path info to be parsed (raw format, i.e. not urldecoded)\n     *\n     * @throws NoConfigurationException  If no routing configuration could be found\n     * @throws ResourceNotFoundException If the resource could not be found\n     * @throws MethodNotAllowedException If the resource was found but the request method is not allowed\n     */\n    public function match(string $pathinfo): array;\n}\n"
  },
  {
    "path": "README.md",
    "content": "Routing Component\n=================\n\nThe Routing component maps an HTTP request to a set of configuration variables.\n\nGetting Started\n---------------\n\n```bash\ncomposer require symfony/routing\n```\n\n```php\nuse App\\Controller\\BlogController;\nuse Symfony\\Component\\Routing\\Generator\\UrlGenerator;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcher;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n$route = new Route('/blog/{slug}', ['_controller' => BlogController::class]);\n$routes = new RouteCollection();\n$routes->add('blog_show', $route);\n\n$context = new RequestContext();\n\n// Routing can match routes with incoming requests\n$matcher = new UrlMatcher($routes, $context);\n$parameters = $matcher->match('/blog/lorem-ipsum');\n// $parameters = [\n//     '_controller' => 'App\\Controller\\BlogController',\n//     'slug' => 'lorem-ipsum',\n//     '_route' => 'blog_show'\n// ]\n\n// Routing can also generate URLs for a given route\n$generator = new UrlGenerator($routes, $context);\n$url = $generator->generate('blog_show', [\n    'slug' => 'my-blog-post',\n]);\n// $url = '/blog/my-blog-post'\n```\n\nSponsor\n-------\n\nHelp Symfony by [sponsoring][3] its development!\n\nResources\n---------\n\n * [Documentation](https://symfony.com/doc/current/routing.html)\n * [Contributing](https://symfony.com/doc/current/contributing/index.html)\n * [Report issues](https://github.com/symfony/symfony/issues) and\n   [send Pull Requests](https://github.com/symfony/symfony/pulls)\n   in the [main Symfony repository](https://github.com/symfony/symfony)\n\n[3]: https://symfony.com/sponsor\n"
  },
  {
    "path": "RequestContext.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\n\n/**\n * Holds information about the current request.\n *\n * This class implements a fluent interface.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\nclass RequestContext\n{\n    private string $baseUrl;\n    private string $pathInfo;\n    private string $method;\n    private string $host;\n    private string $scheme;\n    private int $httpPort;\n    private int $httpsPort;\n    private string $queryString;\n    private array $parameters = [];\n\n    public function __construct(string $baseUrl = '', string $method = 'GET', string $host = 'localhost', string $scheme = 'http', int $httpPort = 80, int $httpsPort = 443, string $path = '/', string $queryString = '', ?array $parameters = null)\n    {\n        $this->setBaseUrl($baseUrl);\n        $this->setMethod($method);\n        $this->setHost($host);\n        $this->setScheme($scheme);\n        $this->setHttpPort($httpPort);\n        $this->setHttpsPort($httpsPort);\n        $this->setPathInfo($path);\n        $this->setQueryString($queryString);\n        $this->parameters = $parameters ?? $this->parameters;\n    }\n\n    public static function fromUri(string $uri, string $host = 'localhost', string $scheme = 'http', int $httpPort = 80, int $httpsPort = 443): self\n    {\n        if (false !== ($i = strpos($uri, '\\\\')) && $i < strcspn($uri, '?#')) {\n            $uri = '';\n        }\n        if ('' !== $uri && (\\ord($uri[0]) <= 32 || \\ord($uri[-1]) <= 32 || \\strlen($uri) !== strcspn($uri, \"\\r\\n\\t\"))) {\n            $uri = '';\n        }\n\n        $uri = parse_url($uri);\n        $scheme = $uri['scheme'] ?? $scheme;\n        $host = $uri['host'] ?? $host;\n\n        if (isset($uri['port'])) {\n            if ('http' === $scheme) {\n                $httpPort = $uri['port'];\n            } elseif ('https' === $scheme) {\n                $httpsPort = $uri['port'];\n            }\n        }\n\n        return new self($uri['path'] ?? '', 'GET', $host, $scheme, $httpPort, $httpsPort);\n    }\n\n    /**\n     * Updates the RequestContext information based on a HttpFoundation Request.\n     *\n     * @return $this\n     */\n    public function fromRequest(Request $request): static\n    {\n        $this->setBaseUrl($request->getBaseUrl());\n        $this->setPathInfo($request->getPathInfo());\n        $this->setMethod($request->getMethod());\n        $this->setHost($request->getHost());\n        $this->setScheme($request->getScheme());\n        $this->setHttpPort($request->isSecure() || null === $request->getPort() ? $this->httpPort : $request->getPort());\n        $this->setHttpsPort($request->isSecure() && null !== $request->getPort() ? $request->getPort() : $this->httpsPort);\n        $this->setQueryString($request->server->get('QUERY_STRING', ''));\n\n        return $this;\n    }\n\n    /**\n     * Gets the base URL.\n     */\n    public function getBaseUrl(): string\n    {\n        return $this->baseUrl;\n    }\n\n    /**\n     * Sets the base URL.\n     *\n     * @return $this\n     */\n    public function setBaseUrl(string $baseUrl): static\n    {\n        $this->baseUrl = rtrim($baseUrl, '/');\n\n        return $this;\n    }\n\n    /**\n     * Gets the path info.\n     */\n    public function getPathInfo(): string\n    {\n        return $this->pathInfo;\n    }\n\n    /**\n     * Sets the path info.\n     *\n     * @return $this\n     */\n    public function setPathInfo(string $pathInfo): static\n    {\n        $this->pathInfo = $pathInfo;\n\n        return $this;\n    }\n\n    /**\n     * Gets the HTTP method.\n     *\n     * The method is always an uppercased string.\n     */\n    public function getMethod(): string\n    {\n        return $this->method;\n    }\n\n    /**\n     * Sets the HTTP method.\n     *\n     * @return $this\n     */\n    public function setMethod(string $method): static\n    {\n        $this->method = strtoupper($method);\n\n        return $this;\n    }\n\n    /**\n     * Gets the HTTP host.\n     *\n     * The host is always lowercased because it must be treated case-insensitive.\n     */\n    public function getHost(): string\n    {\n        return $this->host;\n    }\n\n    /**\n     * Sets the HTTP host.\n     *\n     * @return $this\n     */\n    public function setHost(string $host): static\n    {\n        $this->host = strtolower($host);\n\n        return $this;\n    }\n\n    /**\n     * Gets the HTTP scheme.\n     */\n    public function getScheme(): string\n    {\n        return $this->scheme;\n    }\n\n    /**\n     * Sets the HTTP scheme.\n     *\n     * @return $this\n     */\n    public function setScheme(string $scheme): static\n    {\n        $this->scheme = strtolower($scheme);\n\n        return $this;\n    }\n\n    /**\n     * Gets the HTTP port.\n     */\n    public function getHttpPort(): int\n    {\n        return $this->httpPort;\n    }\n\n    /**\n     * Sets the HTTP port.\n     *\n     * @return $this\n     */\n    public function setHttpPort(int $httpPort): static\n    {\n        $this->httpPort = $httpPort;\n\n        return $this;\n    }\n\n    /**\n     * Gets the HTTPS port.\n     */\n    public function getHttpsPort(): int\n    {\n        return $this->httpsPort;\n    }\n\n    /**\n     * Sets the HTTPS port.\n     *\n     * @return $this\n     */\n    public function setHttpsPort(int $httpsPort): static\n    {\n        $this->httpsPort = $httpsPort;\n\n        return $this;\n    }\n\n    /**\n     * Gets the query string without the \"?\".\n     */\n    public function getQueryString(): string\n    {\n        return $this->queryString;\n    }\n\n    /**\n     * Sets the query string.\n     *\n     * @return $this\n     */\n    public function setQueryString(?string $queryString): static\n    {\n        // string cast to be fault-tolerant, accepting null\n        $this->queryString = (string) $queryString;\n\n        return $this;\n    }\n\n    /**\n     * Returns the parameters.\n     */\n    public function getParameters(): array\n    {\n        return $this->parameters;\n    }\n\n    /**\n     * Sets the parameters.\n     *\n     * @param array $parameters The parameters\n     *\n     * @return $this\n     */\n    public function setParameters(array $parameters): static\n    {\n        $this->parameters = $parameters;\n\n        return $this;\n    }\n\n    /**\n     * Gets a parameter value.\n     */\n    public function getParameter(string $name): mixed\n    {\n        return $this->parameters[$name] ?? null;\n    }\n\n    /**\n     * Checks if a parameter value is set for the given parameter.\n     */\n    public function hasParameter(string $name): bool\n    {\n        return \\array_key_exists($name, $this->parameters);\n    }\n\n    /**\n     * Sets a parameter value.\n     *\n     * @return $this\n     */\n    public function setParameter(string $name, mixed $parameter): static\n    {\n        $this->parameters[$name] = $parameter;\n\n        return $this;\n    }\n\n    public function isSecure(): bool\n    {\n        return 'https' === $this->scheme;\n    }\n}\n"
  },
  {
    "path": "RequestContextAwareInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\ninterface RequestContextAwareInterface\n{\n    /**\n     * Sets the request context.\n     */\n    public function setContext(RequestContext $context): void;\n\n    /**\n     * Gets the request context.\n     */\n    public function getContext(): RequestContext;\n}\n"
  },
  {
    "path": "Requirement/EnumRequirement.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Requirement;\n\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\n\nfinal class EnumRequirement implements \\Stringable\n{\n    private string $requirement;\n\n    /**\n     * @template T of \\BackedEnum\n     *\n     * @param class-string<T>|list<T> $cases\n     */\n    public function __construct(string|array $cases = [])\n    {\n        if (\\is_string($cases)) {\n            if (!is_subclass_of($cases, \\BackedEnum::class, true)) {\n                throw new InvalidArgumentException(\\sprintf('\"%s\" is not a \"BackedEnum\" class.', $cases));\n            }\n\n            $cases = $cases::cases();\n        } else {\n            $class = null;\n\n            foreach ($cases as $case) {\n                if (!$case instanceof \\BackedEnum) {\n                    throw new InvalidArgumentException(\\sprintf('Case must be a \"BackedEnum\" instance, \"%s\" given.', get_debug_type($case)));\n                }\n\n                $class ??= $case::class;\n\n                if (!$case instanceof $class) {\n                    throw new InvalidArgumentException(\\sprintf('\"%s::%s\" is not a case of \"%s\".', get_debug_type($case), $case->name, $class));\n                }\n            }\n        }\n\n        $this->requirement = implode('|', array_map(static fn ($e) => preg_quote($e->value), $cases));\n    }\n\n    public function __toString(): string\n    {\n        return $this->requirement;\n    }\n}\n"
  },
  {
    "path": "Requirement/Requirement.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Requirement;\n\n/*\n * A collection of universal regular-expression constants to use as route parameter requirements.\n */\nenum Requirement\n{\n    public const ASCII_SLUG = '[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*'; // symfony/string AsciiSlugger default implementation\n    public const CATCH_ALL = '.+';\n    public const DATE_YMD = '[0-9]{4}-(?:0[1-9]|1[012])-(?:0[1-9]|[12][0-9]|(?<!02-)3[01])'; // YYYY-MM-DD\n    public const DIGITS = '[0-9]+';\n    public const MONGODB_ID = '[0-9a-f]{24}';\n    public const POSITIVE_INT = '[1-9][0-9]*';\n    public const UID_BASE32 = '[0-9A-HJKMNP-TV-Z]{26}';\n    public const UID_BASE58 = '[1-9A-HJ-NP-Za-km-z]{22}';\n    public const UID_RFC4122 = '[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}';\n    public const UID_RFC9562 = self::UID_RFC4122;\n    public const ULID = '[0-7][0-9A-HJKMNP-TV-Z]{25}';\n    public const UUID = '[0-9a-f]{8}-[0-9a-f]{4}-[13-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V1 = '[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V3 = '[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V4 = '[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V5 = '[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V6 = '[0-9a-f]{8}-[0-9a-f]{4}-6[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V7 = '[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n    public const UUID_V8 = '[0-9a-f]{8}-[0-9a-f]{4}-8[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}';\n}\n"
  },
  {
    "path": "Route.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\n/**\n * A Route describes a route and its parameters.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\nclass Route implements \\Serializable\n{\n    private string $path = '/';\n    private string $host = '';\n    private array $schemes = [];\n    private array $methods = [];\n    private array $defaults = [];\n    private array $requirements = [];\n    private array $options = [];\n    private string $condition = '';\n    private ?CompiledRoute $compiled = null;\n\n    /**\n     * Constructor.\n     *\n     * Available options:\n     *\n     *  * compiler_class: A class name able to compile this route instance (RouteCompiler by default)\n     *  * utf8:           Whether UTF-8 matching is enforced or not\n     *\n     * @param string                    $path         The path pattern to match\n     * @param array                     $defaults     An array of default parameter values\n     * @param array<string|\\Stringable> $requirements An array of requirements for parameters (regexes)\n     * @param array                     $options      An array of options\n     * @param string|null               $host         The host pattern to match\n     * @param string|string[]           $schemes      A required URI scheme or an array of restricted schemes\n     * @param string|string[]           $methods      A required HTTP method or an array of restricted methods\n     * @param string|null               $condition    A condition that should evaluate to true for the route to match\n     */\n    public function __construct(string $path, array $defaults = [], array $requirements = [], array $options = [], ?string $host = '', string|array $schemes = [], string|array $methods = [], ?string $condition = '')\n    {\n        $this->setPath($path);\n        $this->addDefaults($defaults);\n        $this->addRequirements($requirements);\n        $this->setOptions($options);\n        $this->setHost($host);\n        $this->setSchemes($schemes);\n        $this->setMethods($methods);\n        $this->setCondition($condition);\n    }\n\n    public function __serialize(): array\n    {\n        return [\n            'path' => $this->path,\n            'host' => $this->host,\n            'defaults' => $this->defaults,\n            'requirements' => $this->requirements,\n            'options' => $this->options,\n            'schemes' => $this->schemes,\n            'methods' => $this->methods,\n            'condition' => $this->condition,\n            'compiled' => $this->compiled,\n        ];\n    }\n\n    /**\n     * @internal\n     */\n    final public function serialize(): string\n    {\n        throw new \\BadMethodCallException('Cannot serialize '.__CLASS__);\n    }\n\n    public function __unserialize(array $data): void\n    {\n        $this->path = $data['path'];\n        $this->host = $data['host'];\n        $this->defaults = $data['defaults'];\n        $this->requirements = $data['requirements'];\n        $this->options = $data['options'];\n        $this->schemes = $data['schemes'];\n        $this->methods = $data['methods'];\n\n        if (isset($data['condition'])) {\n            $this->condition = $data['condition'];\n        }\n        if (isset($data['compiled'])) {\n            $this->compiled = $data['compiled'];\n        }\n    }\n\n    /**\n     * @internal\n     */\n    final public function unserialize(string $serialized): void\n    {\n        $this->__unserialize(unserialize($serialized));\n    }\n\n    public function getPath(): string\n    {\n        return $this->path;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setPath(string $pattern): static\n    {\n        $pattern = $this->extractInlineDefaultsAndRequirements($pattern);\n\n        // A pattern must start with a slash and must not have multiple slashes at the beginning because the\n        // generated path for this route would be confused with a network path, e.g. '//domain.com/path'.\n        $this->path = '/'.ltrim(trim($pattern), '/');\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    public function getHost(): string\n    {\n        return $this->host;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setHost(?string $pattern): static\n    {\n        $this->host = $this->extractInlineDefaultsAndRequirements((string) $pattern);\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    /**\n     * Returns the lowercased schemes this route is restricted to.\n     * So an empty array means that any scheme is allowed.\n     *\n     * @return string[]\n     */\n    public function getSchemes(): array\n    {\n        return $this->schemes;\n    }\n\n    /**\n     * Sets the schemes (e.g. 'https') this route is restricted to.\n     * So an empty array means that any scheme is allowed.\n     *\n     * @param string|string[] $schemes The scheme or an array of schemes\n     *\n     * @return $this\n     */\n    public function setSchemes(string|array $schemes): static\n    {\n        $this->schemes = array_map('strtolower', (array) $schemes);\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    /**\n     * Checks if a scheme requirement has been set.\n     */\n    public function hasScheme(string $scheme): bool\n    {\n        return \\in_array(strtolower($scheme), $this->schemes, true);\n    }\n\n    /**\n     * Returns the uppercased HTTP methods this route is restricted to.\n     * So an empty array means that any method is allowed.\n     *\n     * @return string[]\n     */\n    public function getMethods(): array\n    {\n        return $this->methods;\n    }\n\n    /**\n     * Sets the HTTP methods (e.g. 'POST') this route is restricted to.\n     * So an empty array means that any method is allowed.\n     *\n     * @param string|string[] $methods The method or an array of methods\n     *\n     * @return $this\n     */\n    public function setMethods(string|array $methods): static\n    {\n        $this->methods = array_map('strtoupper', (array) $methods);\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    public function getOptions(): array\n    {\n        return $this->options;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setOptions(array $options): static\n    {\n        $this->options = [\n            'compiler_class' => RouteCompiler::class,\n        ];\n\n        return $this->addOptions($options);\n    }\n\n    /**\n     * @return $this\n     */\n    public function addOptions(array $options): static\n    {\n        foreach ($options as $name => $option) {\n            $this->options[$name] = $option;\n        }\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    /**\n     * Sets an option value.\n     *\n     * @return $this\n     */\n    public function setOption(string $name, mixed $value): static\n    {\n        $this->options[$name] = $value;\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    /**\n     * Returns the option value or null when not found.\n     */\n    public function getOption(string $name): mixed\n    {\n        return $this->options[$name] ?? null;\n    }\n\n    public function hasOption(string $name): bool\n    {\n        return \\array_key_exists($name, $this->options);\n    }\n\n    public function getDefaults(): array\n    {\n        return $this->defaults;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setDefaults(array $defaults): static\n    {\n        $this->defaults = [];\n\n        return $this->addDefaults($defaults);\n    }\n\n    /**\n     * @return $this\n     */\n    public function addDefaults(array $defaults): static\n    {\n        if (isset($defaults['_locale']) && $this->isLocalized()) {\n            unset($defaults['_locale']);\n        }\n\n        foreach ($defaults as $name => $default) {\n            $this->defaults[$name] = $default;\n        }\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    public function getDefault(string $name): mixed\n    {\n        return $this->defaults[$name] ?? null;\n    }\n\n    public function hasDefault(string $name): bool\n    {\n        return \\array_key_exists($name, $this->defaults);\n    }\n\n    /**\n     * @return $this\n     */\n    public function setDefault(string $name, mixed $default): static\n    {\n        if ('_locale' === $name && $this->isLocalized()) {\n            return $this;\n        }\n\n        $this->defaults[$name] = $default;\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    public function getRequirements(): array\n    {\n        return $this->requirements;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setRequirements(array $requirements): static\n    {\n        $this->requirements = [];\n\n        return $this->addRequirements($requirements);\n    }\n\n    /**\n     * @return $this\n     */\n    public function addRequirements(array $requirements): static\n    {\n        if (isset($requirements['_locale']) && $this->isLocalized()) {\n            unset($requirements['_locale']);\n        }\n\n        foreach ($requirements as $key => $regex) {\n            $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);\n        }\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    public function getRequirement(string $key): ?string\n    {\n        return $this->requirements[$key] ?? null;\n    }\n\n    public function hasRequirement(string $key): bool\n    {\n        return \\array_key_exists($key, $this->requirements);\n    }\n\n    /**\n     * @return $this\n     */\n    public function setRequirement(string $key, string $regex): static\n    {\n        if ('_locale' === $key && $this->isLocalized()) {\n            return $this;\n        }\n\n        $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    public function getCondition(): string\n    {\n        return $this->condition;\n    }\n\n    /**\n     * @return $this\n     */\n    public function setCondition(?string $condition): static\n    {\n        $this->condition = (string) $condition;\n        $this->compiled = null;\n\n        return $this;\n    }\n\n    /**\n     * Compiles the route.\n     *\n     * @throws \\LogicException If the Route cannot be compiled because the\n     *                         path or host pattern is invalid\n     *\n     * @see RouteCompiler which is responsible for the compilation process\n     */\n    public function compile(): CompiledRoute\n    {\n        if (null !== $this->compiled) {\n            return $this->compiled;\n        }\n\n        $class = $this->getOption('compiler_class');\n\n        return $this->compiled = $class::compile($this);\n    }\n\n    private function extractInlineDefaultsAndRequirements(string $pattern): string\n    {\n        if (false === strpbrk($pattern, '?<:')) {\n            return $pattern;\n        }\n\n        $mapping = $this->getDefault('_route_mapping') ?? [];\n\n        $pattern = preg_replace_callback('#\\{(!?)([\\w\\x80-\\xFF]++)(:([\\w\\x80-\\xFF]++)(\\.[\\w\\x80-\\xFF]++)?)?(<.*?>)?(\\?[^\\}]*+)?\\}#', function ($m) use (&$mapping) {\n            if (isset($m[7][0])) {\n                $this->setDefault($m[2], '?' !== $m[7] ? substr($m[7], 1) : null);\n            }\n            if (isset($m[6][0])) {\n                $this->setRequirement($m[2], substr($m[6], 1, -1));\n            }\n            if (isset($m[4][0])) {\n                $mapping[$m[2]] = isset($m[5][0]) ? [$m[4], substr($m[5], 1)] : $m[4];\n            }\n\n            return '{'.$m[1].$m[2].'}';\n        }, $pattern);\n\n        if ($mapping) {\n            $this->setDefault('_route_mapping', $mapping);\n        }\n\n        return $pattern;\n    }\n\n    private function sanitizeRequirement(string $key, string $regex): string\n    {\n        if ('' !== $regex) {\n            if ('^' === $regex[0]) {\n                $regex = substr($regex, 1);\n            } elseif (str_starts_with($regex, '\\\\A')) {\n                $regex = substr($regex, 2);\n            }\n        }\n\n        if (str_ends_with($regex, '$')) {\n            $regex = substr($regex, 0, -1);\n        } elseif (\\strlen($regex) - 2 === strpos($regex, '\\\\z')) {\n            $regex = substr($regex, 0, -2);\n        }\n\n        if ('' === $regex) {\n            throw new \\InvalidArgumentException(\\sprintf('Routing requirement for \"%s\" cannot be empty.', $key));\n        }\n\n        return $regex;\n    }\n\n    private function isLocalized(): bool\n    {\n        return isset($this->defaults['_locale']) && isset($this->defaults['_canonical_route']) && ($this->requirements['_locale'] ?? null) === preg_quote($this->defaults['_locale']);\n    }\n}\n"
  },
  {
    "path": "RouteCollection.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\nuse Symfony\\Component\\Config\\Resource\\ResourceInterface;\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Exception\\RouteCircularReferenceException;\n\n/**\n * A RouteCollection represents a set of Route instances.\n *\n * When adding a route at the end of the collection, an existing route\n * with the same name is removed first. So there can only be one route\n * with a given name.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n *\n * @implements \\IteratorAggregate<string, Route>\n */\nclass RouteCollection implements \\IteratorAggregate, \\Countable\n{\n    /**\n     * @var array<string, Route>\n     */\n    private array $routes = [];\n\n    /**\n     * @var array<string, Alias>\n     */\n    private array $aliases = [];\n\n    /**\n     * @var array<string, ResourceInterface>\n     */\n    private array $resources = [];\n\n    /**\n     * @var array<string, int>\n     */\n    private array $priorities = [];\n\n    public function __clone()\n    {\n        foreach ($this->routes as $name => $route) {\n            $this->routes[$name] = clone $route;\n        }\n\n        foreach ($this->aliases as $name => $alias) {\n            $this->aliases[$name] = clone $alias;\n        }\n    }\n\n    /**\n     * Gets the current RouteCollection as an Iterator that includes all routes.\n     *\n     * It implements \\IteratorAggregate.\n     *\n     * @see all()\n     *\n     * @return \\ArrayIterator<string, Route>\n     */\n    public function getIterator(): \\ArrayIterator\n    {\n        return new \\ArrayIterator($this->all());\n    }\n\n    /**\n     * Gets the number of Routes in this collection.\n     */\n    public function count(): int\n    {\n        return \\count($this->routes);\n    }\n\n    public function add(string $name, Route $route, int $priority = 0): void\n    {\n        unset($this->routes[$name], $this->priorities[$name], $this->aliases[$name]);\n\n        $this->routes[$name] = $route;\n\n        if ($priority) {\n            $this->priorities[$name] = $priority;\n        }\n    }\n\n    /**\n     * Returns all routes in this collection.\n     *\n     * @return array<string, Route>\n     */\n    public function all(): array\n    {\n        if ($this->priorities) {\n            $priorities = $this->priorities;\n            $keysOrder = array_flip(array_keys($this->routes));\n            uksort($this->routes, static fn ($n1, $n2) => (($priorities[$n2] ?? 0) <=> ($priorities[$n1] ?? 0)) ?: ($keysOrder[$n1] <=> $keysOrder[$n2]));\n        }\n\n        return $this->routes;\n    }\n\n    /**\n     * Gets a route by name.\n     */\n    public function get(string $name): ?Route\n    {\n        $visited = [];\n        while (null !== $alias = $this->aliases[$name] ?? null) {\n            if (false !== $searchKey = array_search($name, $visited)) {\n                $visited[] = $name;\n\n                throw new RouteCircularReferenceException($name, \\array_slice($visited, $searchKey));\n            }\n\n            if ($alias->isDeprecated()) {\n                $deprecation = $alias->getDeprecation($name);\n\n                trigger_deprecation($deprecation['package'], $deprecation['version'], $deprecation['message']);\n            }\n\n            $visited[] = $name;\n            $name = $alias->getId();\n        }\n\n        return $this->routes[$name] ?? null;\n    }\n\n    /**\n     * Removes a route or an array of routes by name from the collection.\n     *\n     * @param string|string[] $name The route name or an array of route names\n     */\n    public function remove(string|array $name): void\n    {\n        $routes = [];\n        foreach ((array) $name as $n) {\n            if (isset($this->routes[$n])) {\n                $routes[] = $n;\n            }\n\n            unset($this->routes[$n], $this->priorities[$n], $this->aliases[$n]);\n        }\n\n        if (!$routes) {\n            return;\n        }\n\n        foreach ($this->aliases as $k => $alias) {\n            if (\\in_array($alias->getId(), $routes, true)) {\n                unset($this->aliases[$k]);\n            }\n        }\n    }\n\n    /**\n     * Adds a route collection at the end of the current set by appending all\n     * routes of the added collection.\n     */\n    public function addCollection(self $collection): void\n    {\n        // we need to remove all routes with the same names first because just replacing them\n        // would not place the new route at the end of the merged array\n        foreach ($collection->all() as $name => $route) {\n            unset($this->routes[$name], $this->priorities[$name], $this->aliases[$name]);\n            $this->routes[$name] = $route;\n\n            if (isset($collection->priorities[$name])) {\n                $this->priorities[$name] = $collection->priorities[$name];\n            }\n        }\n\n        foreach ($collection->getAliases() as $name => $alias) {\n            unset($this->routes[$name], $this->priorities[$name], $this->aliases[$name]);\n\n            $this->aliases[$name] = $alias;\n        }\n\n        foreach ($collection->getResources() as $resource) {\n            $this->addResource($resource);\n        }\n    }\n\n    /**\n     * Adds a prefix to the path of all child routes.\n     */\n    public function addPrefix(string $prefix, array $defaults = [], array $requirements = []): void\n    {\n        $prefix = trim(trim($prefix), '/');\n\n        if ('' === $prefix) {\n            return;\n        }\n\n        foreach ($this->routes as $route) {\n            $route->setPath('/'.$prefix.$route->getPath());\n            $route->addDefaults($defaults);\n            $route->addRequirements($requirements);\n        }\n    }\n\n    /**\n     * Adds a prefix to the name of all the routes within in the collection.\n     */\n    public function addNamePrefix(string $prefix): void\n    {\n        $prefixedRoutes = [];\n        $prefixedPriorities = [];\n        $prefixedAliases = [];\n\n        foreach ($this->routes as $name => $route) {\n            $prefixedRoutes[$prefix.$name] = $route;\n            if (null !== $canonicalName = $route->getDefault('_canonical_route')) {\n                $route->setDefault('_canonical_route', $prefix.$canonicalName);\n            }\n            if (isset($this->priorities[$name])) {\n                $prefixedPriorities[$prefix.$name] = $this->priorities[$name];\n            }\n        }\n\n        foreach ($this->aliases as $name => $alias) {\n            $targetId = $alias->getId();\n\n            if (isset($this->routes[$targetId]) || isset($this->aliases[$targetId])) {\n                $targetId = $prefix.$targetId;\n            }\n\n            $prefixedAliases[$prefix.$name] = $alias->withId($targetId);\n        }\n\n        $this->routes = $prefixedRoutes;\n        $this->priorities = $prefixedPriorities;\n        $this->aliases = $prefixedAliases;\n    }\n\n    /**\n     * Sets the host pattern on all routes.\n     */\n    public function setHost(?string $pattern, array $defaults = [], array $requirements = []): void\n    {\n        foreach ($this->routes as $route) {\n            $route->setHost($pattern);\n            $route->addDefaults($defaults);\n            $route->addRequirements($requirements);\n        }\n    }\n\n    /**\n     * Sets a condition on all routes.\n     *\n     * Existing conditions will be overridden.\n     */\n    public function setCondition(?string $condition): void\n    {\n        foreach ($this->routes as $route) {\n            $route->setCondition($condition);\n        }\n    }\n\n    /**\n     * Adds defaults to all routes.\n     *\n     * An existing default value under the same name in a route will be overridden.\n     */\n    public function addDefaults(array $defaults): void\n    {\n        if ($defaults) {\n            foreach ($this->routes as $route) {\n                $route->addDefaults($defaults);\n            }\n        }\n    }\n\n    /**\n     * Adds requirements to all routes.\n     *\n     * An existing requirement under the same name in a route will be overridden.\n     */\n    public function addRequirements(array $requirements): void\n    {\n        if ($requirements) {\n            foreach ($this->routes as $route) {\n                $route->addRequirements($requirements);\n            }\n        }\n    }\n\n    /**\n     * Adds options to all routes.\n     *\n     * An existing option value under the same name in a route will be overridden.\n     */\n    public function addOptions(array $options): void\n    {\n        if ($options) {\n            foreach ($this->routes as $route) {\n                $route->addOptions($options);\n            }\n        }\n    }\n\n    /**\n     * Sets the schemes (e.g. 'https') all child routes are restricted to.\n     *\n     * @param string|string[] $schemes The scheme or an array of schemes\n     */\n    public function setSchemes(string|array $schemes): void\n    {\n        foreach ($this->routes as $route) {\n            $route->setSchemes($schemes);\n        }\n    }\n\n    /**\n     * Sets the HTTP methods (e.g. 'POST') all child routes are restricted to.\n     *\n     * @param string|string[] $methods The method or an array of methods\n     */\n    public function setMethods(string|array $methods): void\n    {\n        foreach ($this->routes as $route) {\n            $route->setMethods($methods);\n        }\n    }\n\n    /**\n     * Returns an array of resources loaded to build this collection.\n     *\n     * @return ResourceInterface[]\n     */\n    public function getResources(): array\n    {\n        return array_values($this->resources);\n    }\n\n    /**\n     * Adds a resource for this collection. If the resource already exists\n     * it is not added.\n     */\n    public function addResource(ResourceInterface $resource): void\n    {\n        $key = (string) $resource;\n\n        if (!isset($this->resources[$key])) {\n            $this->resources[$key] = $resource;\n        }\n    }\n\n    /**\n     * Sets an alias for an existing route.\n     *\n     * @param string $name  The alias to create\n     * @param string $alias The route to alias\n     *\n     * @throws InvalidArgumentException if the alias is for itself\n     */\n    public function addAlias(string $name, string $alias): Alias\n    {\n        if ($name === $alias) {\n            throw new InvalidArgumentException(\\sprintf('Route alias \"%s\" can not reference itself.', $name));\n        }\n\n        unset($this->routes[$name], $this->priorities[$name]);\n\n        return $this->aliases[$name] = new Alias($alias);\n    }\n\n    /**\n     * @return array<string, Alias>\n     */\n    public function getAliases(): array\n    {\n        return $this->aliases;\n    }\n\n    public function getAlias(string $name): ?Alias\n    {\n        return $this->aliases[$name] ?? null;\n    }\n\n    public function getPriority(string $name): ?int\n    {\n        return $this->priorities[$name] ?? null;\n    }\n}\n"
  },
  {
    "path": "RouteCompiler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\n/**\n * RouteCompiler compiles Route instances to CompiledRoute instances.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Tobias Schultze <http://tobion.de>\n */\nclass RouteCompiler implements RouteCompilerInterface\n{\n    /**\n     * This string defines the characters that are automatically considered separators in front of\n     * optional placeholders (with default and no static text following). Such a single separator\n     * can be left out together with the optional placeholder from matching and generating URLs.\n     */\n    public const SEPARATORS = '/,;.:-_~+*=@|';\n\n    /**\n     * The maximum supported length of a PCRE subpattern name\n     * http://pcre.org/current/doc/html/pcre2pattern.html#SEC16.\n     *\n     * @internal\n     */\n    public const VARIABLE_MAXIMUM_LENGTH = 32;\n\n    /**\n     * @throws \\InvalidArgumentException if a path variable is named _fragment\n     * @throws \\LogicException           if a variable is referenced more than once\n     * @throws \\DomainException          if a variable name starts with a digit or if it is too long to be successfully used as\n     *                                   a PCRE subpattern\n     */\n    public static function compile(Route $route): CompiledRoute\n    {\n        $hostVariables = [];\n        $variables = [];\n        $hostRegex = null;\n        $hostTokens = [];\n\n        if ('' !== $host = $route->getHost()) {\n            $result = self::compilePattern($route, $host, true);\n\n            $hostVariables = $result['variables'];\n            $variables = $hostVariables;\n\n            $hostTokens = $result['tokens'];\n            $hostRegex = $result['regex'];\n        }\n\n        $locale = $route->getDefault('_locale');\n        if (null !== $locale && null !== $route->getDefault('_canonical_route') && preg_quote($locale) === $route->getRequirement('_locale')) {\n            $requirements = $route->getRequirements();\n            unset($requirements['_locale']);\n            $route->setRequirements($requirements);\n            $route->setPath(str_replace('{_locale}', $locale, $route->getPath()));\n        }\n\n        $path = $route->getPath();\n\n        $result = self::compilePattern($route, $path, false);\n\n        $staticPrefix = $result['staticPrefix'];\n\n        $pathVariables = $result['variables'];\n\n        foreach ($pathVariables as $pathParam) {\n            if ('_fragment' === $pathParam) {\n                throw new \\InvalidArgumentException(\\sprintf('Route pattern \"%s\" cannot contain \"_fragment\" as a path parameter.', $route->getPath()));\n            }\n        }\n\n        $variables = array_merge($variables, $pathVariables);\n\n        $tokens = $result['tokens'];\n        $regex = $result['regex'];\n\n        return new CompiledRoute(\n            $staticPrefix,\n            $regex,\n            $tokens,\n            $pathVariables,\n            $hostRegex,\n            $hostTokens,\n            $hostVariables,\n            array_unique($variables)\n        );\n    }\n\n    private static function compilePattern(Route $route, string $pattern, bool $isHost): array\n    {\n        $tokens = [];\n        $variables = [];\n        $matches = [];\n        $pos = 0;\n        $defaultSeparator = $isHost ? '.' : '/';\n        $useUtf8 = preg_match('//u', $pattern);\n        $needsUtf8 = $route->getOption('utf8');\n\n        if (!$needsUtf8 && $useUtf8 && preg_match('/[\\x80-\\xFF]/', $pattern)) {\n            throw new \\LogicException(\\sprintf('Cannot use UTF-8 route patterns without setting the \"utf8\" option for route \"%s\".', $route->getPath()));\n        }\n        if (!$useUtf8 && $needsUtf8) {\n            throw new \\LogicException(\\sprintf('Cannot mix UTF-8 requirements with non-UTF-8 pattern \"%s\".', $pattern));\n        }\n\n        // Match all variables enclosed in \"{}\" and iterate over them. But we only want to match the innermost variable\n        // in case of nested \"{}\", e.g. {foo{bar}}. This in ensured because \\w does not match \"{\" or \"}\" itself.\n        preg_match_all('#\\{(!)?([\\w\\x80-\\xFF]+)\\}#', $pattern, $matches, \\PREG_OFFSET_CAPTURE | \\PREG_SET_ORDER);\n        foreach ($matches as $match) {\n            $important = $match[1][1] >= 0;\n            $varName = $match[2][0];\n            // get all static text preceding the current variable\n            $precedingText = substr($pattern, $pos, $match[0][1] - $pos);\n            $pos = $match[0][1] + \\strlen($match[0][0]);\n\n            if (!\\strlen($precedingText)) {\n                $precedingChar = '';\n            } elseif ($useUtf8) {\n                preg_match('/.$/u', $precedingText, $precedingChar);\n                $precedingChar = $precedingChar[0];\n            } else {\n                $precedingChar = substr($precedingText, -1);\n            }\n            $isSeparator = '' !== $precedingChar && str_contains(static::SEPARATORS, $precedingChar);\n\n            // A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the\n            // variable would not be usable as a Controller action argument.\n            if (preg_match('/^\\d/', $varName)) {\n                throw new \\DomainException(\\sprintf('Variable name \"%s\" cannot start with a digit in route pattern \"%s\". Please use a different name.', $varName, $pattern));\n            }\n            if (\\in_array($varName, $variables)) {\n                throw new \\LogicException(\\sprintf('Route pattern \"%s\" cannot reference variable name \"%s\" more than once.', $pattern, $varName));\n            }\n\n            if (\\strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) {\n                throw new \\DomainException(\\sprintf('Variable name \"%s\" cannot be longer than %d characters in route pattern \"%s\". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern));\n            }\n\n            if ($isSeparator && $precedingText !== $precedingChar) {\n                $tokens[] = ['text', substr($precedingText, 0, -\\strlen($precedingChar))];\n            } elseif (!$isSeparator && '' !== $precedingText) {\n                $tokens[] = ['text', $precedingText];\n            }\n\n            $regexp = $route->getRequirement($varName);\n            if (null === $regexp) {\n                $followingPattern = substr($pattern, $pos);\n                // Find the next static character after the variable that functions as a separator. By default, this separator and '/'\n                // are disallowed for the variable. This default requirement makes sure that optional variables can be matched at all\n                // and that the generating-matching-combination of URLs unambiguous, i.e. the params used for generating the URL are\n                // the same that will be matched. Example: new Route('/{page}.{_format}', ['_format' => 'html'])\n                // If {page} would also match the separating dot, {_format} would never match as {page} will eagerly consume everything.\n                // Also even if {_format} was not optional the requirement prevents that {page} matches something that was originally\n                // part of {_format} when generating the URL, e.g. _format = 'mobile.html'.\n                $nextSeparator = self::findNextSeparator($followingPattern, $useUtf8);\n                $regexp = \\sprintf(\n                    '[^%s%s]+',\n                    preg_quote($defaultSeparator),\n                    $defaultSeparator !== $nextSeparator && '' !== $nextSeparator ? preg_quote($nextSeparator) : ''\n                );\n                if (('' !== $nextSeparator && !preg_match('#^\\{[\\w\\x80-\\xFF]+\\}#', $followingPattern)) || '' === $followingPattern) {\n                    // When we have a separator, which is disallowed for the variable, we can optimize the regex with a possessive\n                    // quantifier. This prevents useless backtracking of PCRE and improves performance by 20% for matching those patterns.\n                    // Given the above example, there is no point in backtracking into {page} (that forbids the dot) when a dot must follow\n                    // after it. This optimization cannot be applied when the next char is no real separator or when the next variable is\n                    // directly adjacent, e.g. '/{x}{y}'.\n                    $regexp .= '+';\n                }\n            } else {\n                if (!preg_match('//u', $regexp)) {\n                    $useUtf8 = false;\n                } elseif (!$needsUtf8 && preg_match('/[\\x80-\\xFF]|(?<!\\\\\\\\)\\\\\\\\(?:\\\\\\\\\\\\\\\\)*+(?-i:X|[pP][\\{CLMNPSZ]|x\\{[A-Fa-f0-9]{3})/', $regexp)) {\n                    throw new \\LogicException(\\sprintf('Cannot use UTF-8 route requirements without setting the \"utf8\" option for variable \"%s\" in pattern \"%s\".', $varName, $pattern));\n                }\n                if (!$useUtf8 && $needsUtf8) {\n                    throw new \\LogicException(\\sprintf('Cannot mix UTF-8 requirement with non-UTF-8 charset for variable \"%s\" in pattern \"%s\".', $varName, $pattern));\n                }\n                $regexp = self::transformCapturingGroupsToNonCapturings($regexp);\n            }\n\n            if ($important) {\n                $token = ['variable', $isSeparator ? $precedingChar : '', $regexp, $varName, false, true];\n            } else {\n                $token = ['variable', $isSeparator ? $precedingChar : '', $regexp, $varName];\n            }\n\n            $tokens[] = $token;\n            $variables[] = $varName;\n        }\n\n        if ($pos < \\strlen($pattern)) {\n            $tokens[] = ['text', substr($pattern, $pos)];\n        }\n\n        // find the first optional token\n        $firstOptional = \\PHP_INT_MAX;\n        if (!$isHost) {\n            for ($i = \\count($tokens) - 1; $i >= 0; --$i) {\n                $token = $tokens[$i];\n                // variable is optional when it is not important and has a default value\n                if ('variable' === $token[0] && !($token[5] ?? false) && $route->hasDefault($token[3])) {\n                    $firstOptional = $i;\n                } else {\n                    break;\n                }\n            }\n        }\n\n        // compute the matching regexp\n        $regexp = '';\n        for ($i = 0, $nbToken = \\count($tokens); $i < $nbToken; ++$i) {\n            $regexp .= self::computeRegexp($tokens, $i, $firstOptional);\n        }\n        $regexp = '{^'.$regexp.'$}sD'.($isHost ? 'i' : '');\n\n        // enable Utf8 matching if really required\n        if ($needsUtf8) {\n            $regexp .= 'u';\n            for ($i = 0, $nbToken = \\count($tokens); $i < $nbToken; ++$i) {\n                if ('variable' === $tokens[$i][0]) {\n                    $tokens[$i][4] = true;\n                }\n            }\n        }\n\n        return [\n            'staticPrefix' => self::determineStaticPrefix($route, $tokens),\n            'regex' => $regexp,\n            'tokens' => array_reverse($tokens),\n            'variables' => $variables,\n        ];\n    }\n\n    /**\n     * Determines the longest static prefix possible for a route.\n     */\n    private static function determineStaticPrefix(Route $route, array $tokens): string\n    {\n        if ('text' !== $tokens[0][0]) {\n            return ($route->hasDefault($tokens[0][3]) || '/' === $tokens[0][1]) ? '' : $tokens[0][1];\n        }\n\n        $prefix = $tokens[0][1];\n\n        if (isset($tokens[1][1]) && '/' !== $tokens[1][1] && false === $route->hasDefault($tokens[1][3])) {\n            $prefix .= $tokens[1][1];\n        }\n\n        return $prefix;\n    }\n\n    /**\n     * Returns the next static character in the Route pattern that will serve as a separator (or the empty string when none available).\n     */\n    private static function findNextSeparator(string $pattern, bool $useUtf8): string\n    {\n        if ('' == $pattern) {\n            // return empty string if pattern is empty or false (false which can be returned by substr)\n            return '';\n        }\n        // first remove all placeholders from the pattern so we can find the next real static character\n        if ('' === $pattern = preg_replace('#\\{[\\w\\x80-\\xFF]+\\}#', '', $pattern)) {\n            return '';\n        }\n        if ($useUtf8) {\n            preg_match('/^./u', $pattern, $pattern);\n        }\n\n        return str_contains(static::SEPARATORS, $pattern[0]) ? $pattern[0] : '';\n    }\n\n    /**\n     * Computes the regexp used to match a specific token. It can be static text or a subpattern.\n     *\n     * @param array $tokens        The route tokens\n     * @param int   $index         The index of the current token\n     * @param int   $firstOptional The index of the first optional token\n     */\n    private static function computeRegexp(array $tokens, int $index, int $firstOptional): string\n    {\n        $token = $tokens[$index];\n        if ('text' === $token[0]) {\n            // Text tokens\n            return preg_quote($token[1]);\n        }\n\n        // Variable tokens\n        if (0 === $index && 0 === $firstOptional) {\n            // When the only token is an optional variable token, the separator is required\n            return \\sprintf('%s(?P<%s>%s)?', preg_quote($token[1]), $token[3], $token[2]);\n        }\n\n        $regexp = \\sprintf('%s(?P<%s>%s)', preg_quote($token[1]), $token[3], $token[2]);\n        if ($index >= $firstOptional) {\n            // Enclose each optional token in a subpattern to make it optional.\n            // \"?:\" means it is non-capturing, i.e. the portion of the subject string that\n            // matched the optional subpattern is not passed back.\n            $regexp = \"(?:$regexp\";\n            $nbTokens = \\count($tokens);\n            if ($nbTokens - 1 == $index) {\n                // Close the optional subpatterns\n                $regexp .= str_repeat(')?', $nbTokens - $firstOptional - (0 === $firstOptional ? 1 : 0));\n            }\n        }\n\n        return $regexp;\n    }\n\n    private static function transformCapturingGroupsToNonCapturings(string $regexp): string\n    {\n        for ($i = 0; $i < \\strlen($regexp); ++$i) {\n            if ('\\\\' === $regexp[$i]) {\n                ++$i;\n                continue;\n            }\n            if ('(' !== $regexp[$i] || !isset($regexp[$i + 2])) {\n                continue;\n            }\n            if ('*' === $regexp[++$i] || '?' === $regexp[$i]) {\n                ++$i;\n                continue;\n            }\n            $regexp = substr_replace($regexp, '?:', $i, 0);\n            ++$i;\n        }\n\n        return $regexp;\n    }\n}\n"
  },
  {
    "path": "RouteCompilerInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\n/**\n * RouteCompilerInterface is the interface that all RouteCompiler classes must implement.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface RouteCompilerInterface\n{\n    /**\n     * Compiles the current route instance.\n     *\n     * @throws \\LogicException If the Route cannot be compiled because the\n     *                         path or host pattern is invalid\n     */\n    public static function compile(Route $route): CompiledRoute;\n}\n"
  },
  {
    "path": "Router.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\Config\\ConfigCacheFactory;\nuse Symfony\\Component\\Config\\ConfigCacheFactoryInterface;\nuse Symfony\\Component\\Config\\ConfigCacheInterface;\nuse Symfony\\Component\\Config\\Loader\\LoaderInterface;\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Generator\\CompiledUrlGenerator;\nuse Symfony\\Component\\Routing\\Generator\\ConfigurableRequirementsInterface;\nuse Symfony\\Component\\Routing\\Generator\\Dumper\\CompiledUrlGeneratorDumper;\nuse Symfony\\Component\\Routing\\Generator\\Dumper\\GeneratorDumperInterface;\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\nuse Symfony\\Component\\Routing\\Matcher\\CompiledUrlMatcher;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\MatcherDumperInterface;\nuse Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface;\n\n/**\n * The Router class is an example of the integration of all pieces of the\n * routing system for easier use.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass Router implements RouterInterface, RequestMatcherInterface\n{\n    protected UrlMatcherInterface|RequestMatcherInterface $matcher;\n    protected UrlGeneratorInterface $generator;\n    protected RequestContext $context;\n    protected RouteCollection $collection;\n    protected array $options = [];\n\n    private ConfigCacheFactoryInterface $configCacheFactory;\n\n    /**\n     * @var ExpressionFunctionProviderInterface[]\n     */\n    private array $expressionLanguageProviders = [];\n\n    private static ?array $cache = [];\n\n    public function __construct(\n        protected LoaderInterface $loader,\n        protected mixed $resource,\n        array $options = [],\n        ?RequestContext $context = null,\n        protected ?LoggerInterface $logger = null,\n        protected ?string $defaultLocale = null,\n    ) {\n        $this->context = $context ?? new RequestContext();\n        $this->setOptions($options);\n    }\n\n    /**\n     * Sets options.\n     *\n     * Available options:\n     *\n     *   * cache_dir:              The cache directory (or null to disable caching)\n     *   * debug:                  Whether to enable debugging or not (false by default)\n     *   * generator_class:        The name of a UrlGeneratorInterface implementation\n     *   * generator_dumper_class: The name of a GeneratorDumperInterface implementation\n     *   * matcher_class:          The name of a UrlMatcherInterface implementation\n     *   * matcher_dumper_class:   The name of a MatcherDumperInterface implementation\n     *   * resource_type:          Type hint for the main resource (optional)\n     *   * strict_requirements:    Configure strict requirement checking for generators\n     *                             implementing ConfigurableRequirementsInterface (default is true)\n     *\n     * @throws \\InvalidArgumentException When unsupported option is provided\n     */\n    public function setOptions(array $options): void\n    {\n        $this->options = [\n            'cache_dir' => null,\n            'debug' => false,\n            'generator_class' => CompiledUrlGenerator::class,\n            'generator_dumper_class' => CompiledUrlGeneratorDumper::class,\n            'matcher_class' => CompiledUrlMatcher::class,\n            'matcher_dumper_class' => CompiledUrlMatcherDumper::class,\n            'resource_type' => null,\n            'strict_requirements' => true,\n        ];\n\n        // check option names and live merge, if errors are encountered Exception will be thrown\n        $invalid = [];\n        foreach ($options as $key => $value) {\n            if (\\array_key_exists($key, $this->options)) {\n                $this->options[$key] = $value;\n            } else {\n                $invalid[] = $key;\n            }\n        }\n\n        if ($invalid) {\n            throw new \\InvalidArgumentException(\\sprintf('The Router does not support the following options: \"%s\".', implode('\", \"', $invalid)));\n        }\n    }\n\n    /**\n     * Sets an option.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function setOption(string $key, mixed $value): void\n    {\n        if (!\\array_key_exists($key, $this->options)) {\n            throw new \\InvalidArgumentException(\\sprintf('The Router does not support the \"%s\" option.', $key));\n        }\n\n        $this->options[$key] = $value;\n    }\n\n    /**\n     * Gets an option value.\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function getOption(string $key): mixed\n    {\n        if (!\\array_key_exists($key, $this->options)) {\n            throw new \\InvalidArgumentException(\\sprintf('The Router does not support the \"%s\" option.', $key));\n        }\n\n        return $this->options[$key];\n    }\n\n    public function getRouteCollection(): RouteCollection\n    {\n        return $this->collection ??= $this->loader->load($this->resource, $this->options['resource_type']);\n    }\n\n    public function setContext(RequestContext $context): void\n    {\n        $this->context = $context;\n\n        if (isset($this->matcher)) {\n            $this->getMatcher()->setContext($context);\n        }\n        if (isset($this->generator)) {\n            $this->getGenerator()->setContext($context);\n        }\n    }\n\n    public function getContext(): RequestContext\n    {\n        return $this->context;\n    }\n\n    /**\n     * Sets the ConfigCache factory to use.\n     */\n    public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory): void\n    {\n        $this->configCacheFactory = $configCacheFactory;\n    }\n\n    public function generate(string $name, array $parameters = [], int $referenceType = self::ABSOLUTE_PATH): string\n    {\n        return $this->getGenerator()->generate($name, $parameters, $referenceType);\n    }\n\n    public function match(string $pathinfo): array\n    {\n        return $this->getMatcher()->match($pathinfo);\n    }\n\n    public function matchRequest(Request $request): array\n    {\n        $matcher = $this->getMatcher();\n        if (!$matcher instanceof RequestMatcherInterface) {\n            // fallback to the default UrlMatcherInterface\n            return $matcher->match($request->getPathInfo());\n        }\n\n        return $matcher->matchRequest($request);\n    }\n\n    /**\n     * Gets the UrlMatcher or RequestMatcher instance associated with this Router.\n     */\n    public function getMatcher(): UrlMatcherInterface|RequestMatcherInterface\n    {\n        if (isset($this->matcher)) {\n            return $this->matcher;\n        }\n\n        if (null === $this->options['cache_dir']) {\n            $routes = $this->getRouteCollection();\n            $compiled = is_a($this->options['matcher_class'], CompiledUrlMatcher::class, true);\n            if ($compiled) {\n                $routes = (new CompiledUrlMatcherDumper($routes))->getCompiledRoutes();\n            }\n            $this->matcher = new $this->options['matcher_class']($routes, $this->context);\n            if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {\n                foreach ($this->expressionLanguageProviders as $provider) {\n                    $this->matcher->addExpressionLanguageProvider($provider);\n                }\n            }\n\n            return $this->matcher;\n        }\n\n        $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/url_matching_routes.php',\n            function (ConfigCacheInterface $cache) {\n                $dumper = $this->getMatcherDumperInstance();\n                if (method_exists($dumper, 'addExpressionLanguageProvider')) {\n                    foreach ($this->expressionLanguageProviders as $provider) {\n                        $dumper->addExpressionLanguageProvider($provider);\n                    }\n                }\n\n                $cache->write($dumper->dump(), $this->getRouteCollection()->getResources());\n                unset(self::$cache[$cache->getPath()]);\n            }\n        );\n\n        return $this->matcher = new $this->options['matcher_class'](self::getCompiledRoutes($cache->getPath()), $this->context);\n    }\n\n    /**\n     * Gets the UrlGenerator instance associated with this Router.\n     */\n    public function getGenerator(): UrlGeneratorInterface\n    {\n        if (isset($this->generator)) {\n            return $this->generator;\n        }\n\n        if (null === $this->options['cache_dir']) {\n            $routes = $this->getRouteCollection();\n            $compiled = is_a($this->options['generator_class'], CompiledUrlGenerator::class, true);\n            if ($compiled) {\n                $generatorDumper = new CompiledUrlGeneratorDumper($routes);\n                $routes = array_merge($generatorDumper->getCompiledRoutes(), $generatorDumper->getCompiledAliases());\n            }\n            $this->generator = new $this->options['generator_class']($routes, $this->context, $this->logger, $this->defaultLocale);\n        } else {\n            $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/url_generating_routes.php',\n                function (ConfigCacheInterface $cache) {\n                    $dumper = $this->getGeneratorDumperInstance();\n\n                    $cache->write($dumper->dump(), $this->getRouteCollection()->getResources());\n                    unset(self::$cache[$cache->getPath()]);\n                }\n            );\n\n            $this->generator = new $this->options['generator_class'](self::getCompiledRoutes($cache->getPath()), $this->context, $this->logger, $this->defaultLocale);\n        }\n\n        if ($this->generator instanceof ConfigurableRequirementsInterface) {\n            $this->generator->setStrictRequirements($this->options['strict_requirements']);\n        }\n\n        return $this->generator;\n    }\n\n    public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider): void\n    {\n        $this->expressionLanguageProviders[] = $provider;\n    }\n\n    protected function getGeneratorDumperInstance(): GeneratorDumperInterface\n    {\n        return new $this->options['generator_dumper_class']($this->getRouteCollection());\n    }\n\n    protected function getMatcherDumperInstance(): MatcherDumperInterface\n    {\n        return new $this->options['matcher_dumper_class']($this->getRouteCollection());\n    }\n\n    /**\n     * Provides the ConfigCache factory implementation, falling back to a\n     * default implementation if necessary.\n     */\n    private function getConfigCacheFactory(): ConfigCacheFactoryInterface\n    {\n        return $this->configCacheFactory ??= new ConfigCacheFactory($this->options['debug']);\n    }\n\n    private static function getCompiledRoutes(string $path): array\n    {\n        if ([] === self::$cache && \\function_exists('opcache_invalidate') && filter_var(\\ini_get('opcache.enable'), \\FILTER_VALIDATE_BOOL) && (!\\in_array(\\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true) || filter_var(\\ini_get('opcache.enable_cli'), \\FILTER_VALIDATE_BOOL))) {\n            self::$cache = null;\n        }\n\n        if (null === self::$cache) {\n            return require $path;\n        }\n\n        return self::$cache[$path] ??= require $path;\n    }\n}\n"
  },
  {
    "path": "RouterInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing;\n\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface;\n\n/**\n * RouterInterface is the interface that all Router classes must implement.\n *\n * This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\ninterface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface\n{\n    /**\n     * Gets the RouteCollection instance associated with this Router.\n     *\n     * WARNING: This method should never be used at runtime as it is SLOW.\n     *          You might use it in a cache warmer though.\n     */\n    public function getRouteCollection(): RouteCollection;\n}\n"
  },
  {
    "path": "Tests/Attribute/RouteTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Attribute;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\FooController;\n\nclass RouteTest extends TestCase\n{\n    #[DataProvider('getValidParameters')]\n    public function testLoadFromAttribute(string $methodName, string $property, mixed $expectedReturn)\n    {\n        $route = (new \\ReflectionMethod(FooController::class, $methodName))->getAttributes(Route::class)[0]->newInstance();\n\n        $this->assertEquals($route->$property, $expectedReturn);\n    }\n\n    public static function getValidParameters(): iterable\n    {\n        return [\n            ['simplePath', 'path', '/Blog'],\n            ['localized', 'path', ['nl' => '/hier', 'en' => '/here']],\n            ['requirements', 'requirements', ['locale' => 'en']],\n            ['options', 'options', ['compiler_class' => 'RouteCompiler']],\n            ['name', 'name', 'blog_index'],\n            ['defaults', 'defaults', ['_controller' => 'MyBlogBundle:Blog:index']],\n            ['schemes', 'schemes', ['https']],\n            ['methods', 'methods', ['GET', 'POST']],\n            ['host', 'host', '{locale}.example.com'],\n            ['condition', 'condition', 'context.getMethod() == \\'GET\\''],\n            ['alias', 'aliases', ['alias', 'completely_different_name']],\n        ];\n    }\n}\n"
  },
  {
    "path": "Tests/CompiledRouteTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\CompiledRoute;\n\nclass CompiledRouteTest extends TestCase\n{\n    public function testAccessors()\n    {\n        $compiled = new CompiledRoute('prefix', 'regex', ['tokens'], [], null, [], [], ['variables']);\n        $this->assertEquals('prefix', $compiled->getStaticPrefix(), '__construct() takes a static prefix as its second argument');\n        $this->assertEquals('regex', $compiled->getRegex(), '__construct() takes a regexp as its third argument');\n        $this->assertEquals(['tokens'], $compiled->getTokens(), '__construct() takes an array of tokens as its fourth argument');\n        $this->assertEquals(['variables'], $compiled->getVariables(), '__construct() takes an array of variables as its ninth argument');\n    }\n}\n"
  },
  {
    "path": "Tests/DependencyInjection/AddExpressionLanguageProvidersPassTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\DependencyInjection;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Definition;\nuse Symfony\\Component\\DependencyInjection\\Reference;\nuse Symfony\\Component\\Routing\\DependencyInjection\\AddExpressionLanguageProvidersPass;\n\nclass AddExpressionLanguageProvidersPassTest extends TestCase\n{\n    public function testProcessForRouter()\n    {\n        $container = new ContainerBuilder();\n        $container->addCompilerPass(new AddExpressionLanguageProvidersPass());\n\n        $definition = new Definition(\\stdClass::class);\n        $definition->addTag('routing.expression_language_provider');\n        $container->setDefinition('some_routing_provider', $definition->setPublic(true));\n\n        $container->register('router.default', \\stdClass::class)->setPublic(true);\n        $container->compile();\n\n        $router = $container->getDefinition('router.default');\n        $calls = $router->getMethodCalls();\n        $this->assertCount(1, $calls);\n        $this->assertEquals('addExpressionLanguageProvider', $calls[0][0]);\n        $this->assertEquals(new Reference('some_routing_provider'), $calls[0][1][0]);\n    }\n\n    public function testProcessForRouterAlias()\n    {\n        $container = new ContainerBuilder();\n        $container->addCompilerPass(new AddExpressionLanguageProvidersPass());\n\n        $definition = new Definition(\\stdClass::class);\n        $definition->addTag('routing.expression_language_provider');\n        $container->setDefinition('some_routing_provider', $definition->setPublic(true));\n\n        $container->register('my_router', \\stdClass::class)->setPublic(true);\n        $container->setAlias('router.default', 'my_router');\n        $container->compile();\n\n        $router = $container->getDefinition('my_router');\n        $calls = $router->getMethodCalls();\n        $this->assertCount(1, $calls);\n        $this->assertEquals('addExpressionLanguageProvider', $calls[0][0]);\n        $this->assertEquals(new Reference('some_routing_provider'), $calls[0][1][0]);\n    }\n}\n"
  },
  {
    "path": "Tests/DependencyInjection/RoutingControllerPassTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\DependencyInjection;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Definition;\nuse Symfony\\Component\\Routing\\DependencyInjection\\RoutingControllerPass;\n\nclass RoutingControllerPassTest extends TestCase\n{\n    public function testProcessInjectsTaggedControllerClassesOrderedAndUnique()\n    {\n        $container = new ContainerBuilder();\n        $container->setParameter('ctrl_a.class', CtrlA::class);\n\n        $container->register('routing.loader.attribute.services', \\stdClass::class)\n            ->setArguments([null]);\n\n        $container->register('ctrl_a', '%ctrl_a.class%')->addTag('routing.controller', ['priority' => 10]);\n        $container->register('ctrl_b', CtrlB::class)->addTag('routing.controller', ['priority' => 20]);\n        $container->register('ctrl_c', CtrlC::class)->addTag('routing.controller', ['priority' => -5]);\n\n        (new RoutingControllerPass())->process($container);\n\n        $this->assertSame([\n            CtrlB::class,\n            CtrlA::class,\n            CtrlC::class,\n        ], $container->getDefinition('routing.loader.attribute.services')->getArgument(0));\n    }\n\n    public function testProcessWithNoTaggedControllersSetsEmptyList()\n    {\n        $container = new ContainerBuilder();\n\n        $loaderDef = new Definition(\\stdClass::class);\n        $loaderDef->setArguments([['preexisting']]);\n        $container->setDefinition('routing.loader.attribute.services', $loaderDef);\n\n        (new RoutingControllerPass())->process($container);\n\n        $this->assertSame([], $container->getDefinition('routing.loader.attribute.services')->getArgument(0));\n    }\n}\n"
  },
  {
    "path": "Tests/DependencyInjection/RoutingResolverPassTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\DependencyInjection;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolver;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\nuse Symfony\\Component\\DependencyInjection\\Reference;\nuse Symfony\\Component\\Routing\\DependencyInjection\\RoutingResolverPass;\n\nclass RoutingResolverPassTest extends TestCase\n{\n    public function testProcess()\n    {\n        $container = new ContainerBuilder();\n        $container->register('routing.resolver', LoaderResolver::class);\n        $container->register('loader1')->addTag('routing.loader');\n        $container->register('loader2')->addTag('routing.loader');\n\n        (new RoutingResolverPass())->process($container);\n\n        $this->assertEquals(\n            [['addLoader', [new Reference('loader1')]], ['addLoader', [new Reference('loader2')]]],\n            $container->getDefinition('routing.resolver')->getMethodCalls()\n        );\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/AbstractClassController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nabstract class AbstractClassController\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/ActionPathController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass ActionPathController\n{\n    #[Route('/path', name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/AliasClassController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/hello', alias: ['alias', 'completely_different_name'])]\nclass AliasClassController\n{\n    #[Route('/world')]\n    public function actionWorld()\n    {\n    }\n\n    #[Route('/symfony')]\n    public function actionSymfony()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/AliasInvokableController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/path', name:'invokable_path', alias: ['alias', 'completely_different_name'])]\nclass AliasInvokableController\n{\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/AliasLocalizedRouteController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass AliasLocalizedRouteController\n{\n    #[Route(['nl_NL' => '/nl/localized', 'fr_FR' => '/fr/localized'], name: 'localized_route', alias: ['localized_alias'])]\n    public function localized()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/AliasRouteController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass AliasRouteController\n{\n    #[Route('/path', name: 'action_with_alias', alias: ['alias', 'completely_different_name'])]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/BazClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[\n    Route(path: '/1', name: 'route1', schemes: ['https'], methods: ['GET']),\n    Route(path: '/2', name: 'route2', schemes: ['https'], methods: ['GET']),\n]\nclass BazClass\n{\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/DefaultValueController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses\\BarClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestIntBackedEnum;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestStringBackedEnum;\n\nclass DefaultValueController\n{\n    #[Route(path: '/{default}/path', name: 'action')]\n    public function action($default = 'value')\n    {\n    }\n\n    #[\n        Route(path: '/hello/{name<\\w+>}', name: 'hello_without_default'),\n        Route(path: 'hello/{name<\\w+>?Symfony}', name: 'hello_with_default'),\n    ]\n    public function hello(string $name = 'World')\n    {\n    }\n\n    #[Route(path: '/enum/{default}', name: 'string_enum_action')]\n    public function stringEnumAction(TestStringBackedEnum $default = TestStringBackedEnum::Diamonds)\n    {\n    }\n\n    #[Route(path: '/enum/{default<\\d+>}', name: 'int_enum_action')]\n    public function intEnumAction(TestIntBackedEnum $default = TestIntBackedEnum::Diamonds)\n    {\n    }\n\n    #[Route(path: '/defaultMappedParam/{libelle:bar}', name: 'defaultMappedParam_default')]\n    public function defaultMappedParam(?BarClass $bar = null)\n    {\n    }\n\n    #[Route(path: '/defaultAdvancedMappedParam/{barLibelle:bar.libelle}', name: 'defaultAdvancedMappedParam_default')]\n    public function defaultAdvancedMappedParam(?BarClass $bar = null)\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/DeprecatedAliasCustomMessageRouteController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\DeprecatedAlias;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass DeprecatedAliasCustomMessageRouteController\n{\n\n    #[Route('/path', name: 'action_with_deprecated_alias', alias: new DeprecatedAlias('my_other_alias_deprecated', 'MyBundleFixture', '1.0', message: '%alias_id% alias is deprecated.'))]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/DeprecatedAliasRouteController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\DeprecatedAlias;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass DeprecatedAliasRouteController\n{\n    #[Route('/path', name: 'action_with_deprecated_alias', alias: new DeprecatedAlias('my_other_alias_deprecated', 'MyBundleFixture', '1.0'))]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/EncodingClass.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass EncodingClass\n{\n    #[Route]\n    public function routeÀction()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/ExplicitLocalizedActionPathController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass ExplicitLocalizedActionPathController\n{\n    #[Route(path: ['en' => '/path', 'nl' => '/pad'], name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/ExtendedRoute.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[\\Attribute(\\Attribute::IS_REPEATABLE | \\Attribute::TARGET_CLASS | \\Attribute::TARGET_METHOD)]\nclass ExtendedRoute extends Route\n{\n    public function __construct(array|string|null $path = null, ?string $name = null, array $defaults = [])\n    {\n        parent::__construct(\"/{section<(foo|bar|baz)>}\" . $path, $name, [], [], array_merge(['section' => 'foo'], $defaults));\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/ExtendedRouteOnClassController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[ExtendedRoute('/class-level')]\nclass ExtendedRouteOnClassController\n{\n    #[Route(path: '/method-level', name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/ExtendedRouteOnMethodController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nclass ExtendedRouteOnMethodController\n{\n    #[ExtendedRoute(path: '/method-level', name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/FooController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass FooController\n{\n    #[Route('/Blog')]\n    public function simplePath()\n    {\n    }\n\n    #[Route(['nl' => '/hier', 'en' => '/here'])]\n    public function localized()\n    {\n    }\n\n    #[Route(requirements: ['locale' => 'en'])]\n    public function requirements()\n    {\n    }\n\n    #[Route(options: ['compiler_class' => 'RouteCompiler'])]\n    public function options()\n    {\n    }\n\n    #[Route(name: 'blog_index')]\n    public function name()\n    {\n    }\n\n    #[Route(defaults: ['_controller' => 'MyBlogBundle:Blog:index'])]\n    public function defaults()\n    {\n    }\n\n    #[Route(schemes: ['https'])]\n    public function schemes()\n    {\n    }\n\n    #[Route(methods: ['GET', 'POST'])]\n    public function methods()\n    {\n    }\n\n    #[Route(host: '{locale}.example.com')]\n    public function host()\n    {\n    }\n\n    #[Route(condition: 'context.getMethod() == \\'GET\\'')]\n    public function condition()\n    {\n    }\n\n    #[Route(alias: ['alias', 'completely_different_name'])]\n    public function alias()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/GlobalDefaultsClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: '/defaults', methods: ['GET'], schemes: ['https'], locale: 'g_locale', format: 'g_format')]\nclass GlobalDefaultsClass\n{\n    #[Route(path: '/specific-locale', name: 'specific_locale', locale: 's_locale')]\n    public function locale()\n    {\n    }\n\n    #[Route(path: '/specific-format', name: 'specific_format', format: 's_format')]\n    public function format()\n    {\n    }\n\n    #[Route(path: '/redundant-method', name: 'redundant_method',  methods: ['GET'])]\n    public function redundantMethod()\n    {\n    }\n\n    #[Route(path: '/redundant-scheme', name: 'redundant_scheme', schemes: ['https'])]\n    public function redundantScheme()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/InvokableController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: '/here', name: 'lol', methods: [\"GET\", \"POST\"], schemes: ['https'])]\nclass InvokableController\n{\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/InvokableFQCNAliasConflictController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: '/foobarccc', name: self::class)]\nclass InvokableFQCNAliasConflictController\n{\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/InvokableLocalizedController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: [\"nl\" => \"/hier\", \"en\" => \"/here\"], name: 'action')]\nclass InvokableLocalizedController\n{\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/InvokableMethodController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass InvokableMethodController\n{\n    #[Route(path: '/here', name: 'lol', methods: [\"GET\", \"POST\"], schemes: ['https'])]\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/LocalizedActionPathController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass LocalizedActionPathController\n{\n    #[Route(path: ['en' => '/path', 'nl' => '/pad'], name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/LocalizedMethodActionControllers.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: ['en' => '/the/path', 'nl' => '/het/pad'])]\nclass LocalizedMethodActionControllers\n{\n    #[Route(name: 'post', methods: ['POST'])]\n    public function post()\n    {\n    }\n\n    #[Route(name: 'put', methods: ['PUT'])]\n    public function put()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixLocalizedActionController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: ['nl' => '/nl', 'en' => '/en'])]\nclass LocalizedPrefixLocalizedActionController\n{\n    #[Route(path: ['nl' => '/actie', 'en' => '/action'], name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixMissingLocaleActionController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: ['nl' => '/nl'])]\nclass LocalizedPrefixMissingLocaleActionController\n{\n    #[Route(path: ['nl' => '/actie', 'en' => '/action'], name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixMissingRouteLocaleActionController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: ['nl' => '/nl', 'en' => '/en'])]\nclass LocalizedPrefixMissingRouteLocaleActionController\n{\n    #[Route(path: ['nl' => '/actie'], name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/LocalizedPrefixWithRouteWithoutLocale.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: ['en' => '/en', 'nl' => '/nl'])]\nclass LocalizedPrefixWithRouteWithoutLocale\n{\n    #[Route(path: '/suffix', name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/MethodActionControllers.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/the/path')]\nclass MethodActionControllers\n{\n    #[Route(name: 'post', methods: ['POST'])]\n    public function post()\n    {\n    }\n\n    #[Route(name: 'put', methods: ['PUT'], priority: 10)]\n    public function put()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/MethodsAndSchemes.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nfinal class MethodsAndSchemes\n{\n    #[Route(path: '/array-many', name: 'array_many', methods: ['GET', 'POST'], schemes: ['http', 'https'])]\n    public function arrayMany(): void\n    {\n    }\n\n    #[Route(path: '/array-one', name: 'array_one', methods: ['GET'], schemes: ['http'])]\n    public function arrayOne(): void\n    {\n    }\n\n    #[Route(path: '/string', name: 'string', methods: 'POST', schemes: 'https')]\n    public function string(): void\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/MissingRouteNameController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass MissingRouteNameController\n{\n    #[Route('/path')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/MultipleDeprecatedAliasRouteController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\DeprecatedAlias;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass MultipleDeprecatedAliasRouteController\n{\n    #[Route('/path', name: 'action_with_multiple_deprecated_alias', alias: [\n        new DeprecatedAlias('my_first_alias_deprecated', 'MyFirstBundleFixture', '1.0'),\n        new DeprecatedAlias('my_second_alias_deprecated', 'MySecondBundleFixture', '2.0'),\n        new DeprecatedAlias('my_third_alias_deprecated', 'SurprisedThirdBundleFixture', '3.0'),\n    ])]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/NothingButNameController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass NothingButNameController\n{\n    #[Route(name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/PrefixedActionLocalizedRouteController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/prefix')]\nclass PrefixedActionLocalizedRouteController\n{\n    #[Route(path: ['en' => '/path', 'nl' => '/pad'], name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/PrefixedActionPathController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: '/prefix', host: 'frankdejonge.nl', condition: 'lol=fun')]\nclass PrefixedActionPathController\n{\n    #[Route(path: '/path', name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/RequirementsWithoutPlaceholderNameController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(path: '/', requirements: ['foo', '\\d+'])]\nclass RequirementsWithoutPlaceholderNameController\n{\n    #[Route(path: '/{foo}', name: 'foo', requirements: ['foo', '\\d+'])]\n    public function foo()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/RouteWithEnv.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route(env: 'some-env')]\nclass RouteWithEnv\n{\n    #[Route(path: '/path', name: 'action')]\n    public function action()\n    {\n    }\n\n    #[Route(path: '/path2', name: 'action2', env: 'some-other-env')]\n    public function action2()\n    {\n    }\n\n    #[Route(path: '/path3', name: 'action3', env: ['some-other-env', 'some-other-env-two'])]\n    public function action3()\n    {\n    }\n\n    #[Route(path: '/path4', name: 'action4', env: null)]\n    public function action4()\n    {\n    }\n\n    #[Route(path: '/path5', name: 'action5', env: ['some-other-env', 'some-env'])]\n    public function action5()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/RouteWithPrefixController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/prefix')]\nclass RouteWithPrefixController\n{\n    #[Route(path: '/path', name: 'action')]\n    public function action()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/RouteWithPriorityController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass RouteWithPriorityController\n{\n    #[Route('/important', name: 'important', priority: 2)]\n    public function important()\n    {\n    }\n\n    #[Route('/also-important', name: 'also_important', priority: 1, defaults: ['_locale' => 'cs'])]\n    public function alsoImportant()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributeFixtures/Utf8ActionControllers.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/test', utf8: true)]\nclass Utf8ActionControllers\n{\n    #[Route(name: 'one')]\n    public function one()\n    {\n    }\n\n    #[Route(name: 'two', utf8: false)]\n    public function two()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributedClasses/AbstractClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nabstract class AbstractClass\n{\n    abstract public function abstractRouteAction();\n\n    #[Route('/path/to/route/{arg1}')]\n    public function routeAction($arg1, $arg2 = 'defaultValue2', $arg3 = 'defaultValue3')\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributedClasses/BarClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\nclass BarClass\n{\n    public function routeAction($arg1, $arg2 = 'defaultValue2', $arg3 = 'defaultValue3')\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributedClasses/BazClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\nclass BazClass\n{\n    public function __invoke()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributedClasses/EncodingClass.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\nclass EncodingClass\n{\n    public function routeÀction()\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributedClasses/FooClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\nclass FooClass\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributedClasses/FooTrait.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses;\n\ntrait FooTrait\n{\n    public function doBar()\n    {\n        self::class;\n        if (true) {\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Attributes/FooAttributes.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes;\n\n#[\\Attribute(\\Attribute::TARGET_CLASS)]\nclass FooAttributes\n{\n    public string $class;\n    public array $foo = [];\n\n    public function __construct(string $class, array $foo)\n    {\n        $this->class = $class;\n        $this->foo = $foo;\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(\n    foo: [\n        'bar' => ['foo','bar'],\n        'foo',\n    ],\n    class: \\stdClass::class\n)]\nclass AttributesClassParamAfterCommaController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(\n    class: \\stdClass::class,\n    foo: [\n        'bar' => ['foo','bar'],\n        'foo',\n    ]\n)]\nclass AttributesClassParamAfterParenthesisController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(foo: ['bar' => ['foo','bar'],'foo'],class: \\stdClass::class)]\nclass AttributesClassParamInlineAfterCommaController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(class: \\stdClass::class,foo: ['bar' => ['foo','bar'],'foo'])]\nclass AttributesClassParamInlineAfterParenthesisController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(foo: ['bar' => ['foo','bar'],'foo'],class: 'Symfony\\Component\\Security\\Core\\User\\User')]\nclass AttributesClassParamInlineQuotedAfterCommaController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(class: \\stdClass::class,foo: ['bar' => ['foo','bar'],'foo'])]\nclass AttributesClassParamInlineQuotedAfterParenthesisController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(\n    foo: [\n        'bar' => ['foo','bar'],\n        'foo',\n    ],\n    class: 'Symfony\\Component\\Security\\Core\\User\\User'\n)]\nclass AttributesClassParamQuotedAfterCommaController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Attributes\\FooAttributes;\n\n#[FooAttributes(\n    class: 'Symfony\\Component\\Security\\Core\\User\\User',\n    foo: [\n        'bar' => ['foo','bar'],\n        'foo',\n    ]\n)]\nclass AttributesClassParamQuotedAfterParenthesisController\n{\n\n}\n"
  },
  {
    "path": "Tests/Fixtures/CustomCompiledRoute.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures;\n\nuse Symfony\\Component\\Routing\\CompiledRoute;\n\nclass CustomCompiledRoute extends CompiledRoute\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/CustomRouteCompiler.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures;\n\nuse Symfony\\Component\\Routing\\CompiledRoute;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCompiler;\n\nclass CustomRouteCompiler extends RouteCompiler\n{\n    public static function compile(Route $route): CompiledRoute\n    {\n        return new CustomCompiledRoute('', '', [], []);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Enum/TestIntBackedEnum.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum;\n\nenum TestIntBackedEnum: int\n{\n    case Hearts = 10;\n    case Diamonds = 20;\n    case Clubs = 30;\n    case Spades = 40;\n}\n"
  },
  {
    "path": "Tests/Fixtures/Enum/TestStringBackedEnum.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum;\n\nenum TestStringBackedEnum: string\n{\n    case Hearts = 'hearts';\n    case Diamonds = 'diamonds';\n    case Clubs = 'clubs';\n    case Spades = 'spades';\n}\n"
  },
  {
    "path": "Tests/Fixtures/Enum/TestStringBackedEnum2.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum;\n\nenum TestStringBackedEnum2: string\n{\n    case Hearts = 'hearts';\n    case Diamonds = 'diamonds';\n    case Clubs = 'clubs';\n    case Spades = 'spa|des';\n}\n"
  },
  {
    "path": "Tests/Fixtures/Enum/TestUnitEnum.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum;\n\nenum TestUnitEnum\n{\n    case Hearts;\n    case Diamonds;\n    case Clubs;\n    case Spades;\n}\n"
  },
  {
    "path": "Tests/Fixtures/OtherAnnotatedClasses/NoStartTagClass.php",
    "content": "class NoStartTagClass\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/OtherAnnotatedClasses/VariadicClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\OtherAnnotatedClasses;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nclass VariadicClass\n{\n    #[Route('/path/to/{id}')]\n    public function routeAction(...$params)\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/MyController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/my/route', name: 'my_route')]\nfinal class MyController\n{\n    public function __invoke(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/MyUnannotatedController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nfinal class MyUnannotatedController\n{\n    public function myAction(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/EvenDeeperNamespace/MyOtherController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace\\EvenDeeperNamespace;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/my/other/route', name: 'my_other_controller_', methods: ['PUT'])]\nfinal class MyOtherController\n{\n    #[Route('/first', name: 'one')]\n    public function firstAction(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n\n    #[Route('/second', name: 'two')]\n    public function secondAction(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantClass.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\n\n/**\n * An irrelevant class.\n *\n * This fixture is not referenced anywhere. Its presence makes sure, classes without attributes are silently ignored\n * when loading routes from a directory.\n */\nfinal class IrrelevantClass\n{\n    public function irrelevantAction(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantEnum.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\n/**\n * An irrelevant enum.\n *\n * This fixture is not referenced anywhere. Its presence makes sure, enums are silently ignored when loading routes\n * from a directory.\n */\nenum IrrelevantEnum\n{\n    case Foo;\n    case Bar;\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/IrrelevantInterface.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\ninterface IrrelevantInterface\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/MyAbstractController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nabstract class MyAbstractController\n{\n    #[Route('/a/route/from/an/abstract/controller', name: 'from_abstract')]\n    public function someAction(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/MyChildController.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/my/child/controller', name: 'my_child_controller_')]\nfinal class MyChildController extends MyAbstractController\n{\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/MyControllerWithATrait.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\n#[Route('/my/controller/with/a/trait', name: 'my_controller_')]\nfinal class MyControllerWithATrait implements IrrelevantInterface\n{\n    use SomeSharedImplementation;\n}\n"
  },
  {
    "path": "Tests/Fixtures/Psr4Controllers/SubNamespace/SomeSharedImplementation.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace;\n\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\ntrait SomeSharedImplementation\n{\n    #[Route('/a/route/from/a/trait', name: 'with_a_trait')]\n    public function someAction(): Response\n    {\n        return new Response(status: Response::HTTP_NO_CONTENT);\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/RedirectableUrlMatcher.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures;\n\nuse Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcher;\n\n/**\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface\n{\n    public function redirect(string $path, string $route, ?string $scheme = null): array\n    {\n        return [\n            '_controller' => 'Some controller reference...',\n            'path' => $path,\n            'scheme' => $scheme,\n        ];\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/TraceableAttributeClassLoader.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Fixtures;\n\nuse Symfony\\Component\\Routing\\Loader\\AttributeClassLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nfinal class TraceableAttributeClassLoader extends AttributeClassLoader\n{\n    /** @var list<string> */\n    public array $foundClasses = [];\n\n    public function load(mixed $class, ?string $type = null): RouteCollection\n    {\n        if (!is_string($class)) {\n            throw new \\InvalidArgumentException(sprintf('Expected string, got \"%s\"', get_debug_type($class)));\n        }\n\n        $this->foundClasses[] = $class;\n\n        return parent::load($class, $type);\n    }\n\n    protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n    {\n    }\n}\n"
  },
  {
    "path": "Tests/Fixtures/alias/alias.php",
    "content": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RoutingConfigurator;\n\nreturn static function (RoutingConfigurator $routes): void {\n    $routes->add('route', '/hello');\n    $routes->add('overrided', '/');\n    $routes->alias('alias', 'route');\n    $routes->alias('deprecated', 'route')\n        ->deprecate('foo/bar', '1.0.0', '');\n    $routes->alias('deprecated-with-custom-message', 'route')\n        ->deprecate('foo/bar', '1.0.0', 'foo %alias_id%.');\n    $routes->alias('deep', 'alias');\n    $routes->alias('overrided', 'route');\n};\n"
  },
  {
    "path": "Tests/Fixtures/alias/alias.yaml",
    "content": "route:\n  path: /hello\noverrided:\n  path: /\nalias:\n  alias: route\ndeprecated:\n  alias: route\n  deprecated:\n    package: \"foo/bar\"\n    version: \"1.0.0\"\ndeprecated-with-custom-message:\n  alias: route\n  deprecated:\n    package: \"foo/bar\"\n    version: \"1.0.0\"\n    message: \"foo %alias_id%.\"\ndeep:\n  alias: alias\n_import:\n  resource: override.yaml\n"
  },
  {
    "path": "Tests/Fixtures/alias/expected.php",
    "content": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nreturn static function (string $format) {\n    $expectedRoutes = new RouteCollection();\n\n    $expectedRoutes->add('route', new Route('/hello'));\n    $expectedRoutes->addAlias('alias', 'route');\n    $expectedRoutes->addAlias('deprecated', 'route')\n        ->setDeprecated('foo/bar', '1.0.0', '');\n    $expectedRoutes->addAlias('deprecated-with-custom-message', 'route')\n        ->setDeprecated('foo/bar', '1.0.0', 'foo %alias_id%.');\n    $expectedRoutes->addAlias('deep', 'alias');\n    $expectedRoutes->addAlias('overrided', 'route');\n\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/alias.$format\"));\n    if ('yaml' === $format) {\n        $expectedRoutes->addResource(new FileResource(__DIR__.\"/override.$format\"));\n    }\n\n    return $expectedRoutes;\n};\n"
  },
  {
    "path": "Tests/Fixtures/alias/invalid-alias.yaml",
    "content": "invalid:\n  alias: route\n  path: \"/\"\n"
  },
  {
    "path": "Tests/Fixtures/alias/invalid-deprecated-no-package.yaml",
    "content": "invalid:\n  alias: route\n  deprecated:\n    version: \"1.0.0\"\n"
  },
  {
    "path": "Tests/Fixtures/alias/invalid-deprecated-no-version.yaml",
    "content": "invalid:\n  alias: route\n  deprecated:\n    package: \"foo/bar\"\n"
  },
  {
    "path": "Tests/Fixtures/alias/override.yaml",
    "content": "overrided:\n  alias: route\n"
  },
  {
    "path": "Tests/Fixtures/annotated.php",
    "content": ""
  },
  {
    "path": "Tests/Fixtures/array_routes.php",
    "content": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Routes;\n\nreturn Routes::config([\n    'a' => ['path' => '/a'],\n    'b' => ['path' => '/b', 'methods' => ['GET']],\n]);\n"
  },
  {
    "path": "Tests/Fixtures/array_when_env.php",
    "content": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Routes;\n\nreturn Routes::config([\n    'when@some-env' => [\n        'x' => ['path' => '/x'],\n    ],\n    'a' => ['path' => '/a'],\n]);\n"
  },
  {
    "path": "Tests/Fixtures/bad_format.yml",
    "content": "blog_show:\n\tpath:     /blog/{slug}\n\tdefaults: { _controller: \"MyBundle:Blog:show\" }\n"
  },
  {
    "path": "Tests/Fixtures/class-attributes.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\MyController;\n\nreturn function (RoutingConfigurator $routes): void {\n    $routes\n        ->import(\n            resource: MyController::class,\n            type: 'attribute',\n        )\n        ->prefix('/my-prefix');\n};\n"
  },
  {
    "path": "Tests/Fixtures/class-attributes.yaml",
    "content": "my_controllers:\n    resource: Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\MyController\n    type: attribute\n    prefix: /my-prefix\n"
  },
  {
    "path": "Tests/Fixtures/collection-defaults.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $collection = $routes->collection();\n    $collection\n        ->methods(['GET'])\n        ->defaults(['attribute' => true])\n        ->stateless();\n\n    $collection->add('defaultsA', '/defaultsA')\n        ->locale('en')\n        ->format('html');\n\n    $collection->add('defaultsB', '/defaultsB')\n        ->methods(['POST'])\n        ->stateless(false)\n        ->locale('en')\n        ->format('html');\n};\n"
  },
  {
    "path": "Tests/Fixtures/controller/empty_wildcard/.gitignore",
    "content": ""
  },
  {
    "path": "Tests/Fixtures/controller/import__controller.yml",
    "content": "_static:\n    resource: routing.yml\n    defaults:\n        _controller: FrameworkBundle:Template:template\n"
  },
  {
    "path": "Tests/Fixtures/controller/import_controller.yml",
    "content": "_static:\n    resource: routing.yml\n    controller: FrameworkBundle:Template:template\n"
  },
  {
    "path": "Tests/Fixtures/controller/import_override_defaults.yml",
    "content": "_static:\n    resource: routing.yml\n    controller: FrameworkBundle:Template:template\n    defaults:\n        _controller: AppBundle:Homepage:show\n"
  },
  {
    "path": "Tests/Fixtures/controller/override_defaults.yml",
    "content": "app_blog:\n    path: /blog\n    controller: AppBundle:Homepage:show\n    defaults:\n        _controller: AppBundle:Blog:index\n"
  },
  {
    "path": "Tests/Fixtures/controller/routing.yml",
    "content": "app_homepage:\n    path: /\n    controller: AppBundle:Homepage:show\n\napp_blog:\n    path: /blog\n    defaults:\n        _controller: AppBundle:Blog:list\n\napp_logout:\n    path: /logout\n"
  },
  {
    "path": "Tests/Fixtures/defaults.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->add('defaults', '/defaults')\n        ->locale('en')\n        ->format('html')\n        ->stateless(true)\n    ;\n};\n"
  },
  {
    "path": "Tests/Fixtures/defaults.yml",
    "content": "defaults:\n  path: /defaults\n  locale: en\n  format: html\n  stateless: true\n"
  },
  {
    "path": "Tests/Fixtures/directory/recurse/routes1.yml",
    "content": "route1:\n    path: /route/1\n"
  },
  {
    "path": "Tests/Fixtures/directory/recurse/routes2.yml",
    "content": "route2:\n    path: /route/2\n"
  },
  {
    "path": "Tests/Fixtures/directory/routes3.yml",
    "content": "route3:\n    path: /route/3\n"
  },
  {
    "path": "Tests/Fixtures/directory_import/import.yml",
    "content": "_directory:\n    resource: \"../directory\"\n    type: directory\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher0.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n    ],\n    [ // $regexpList\n    ],\n    [ // $dynamicRoutes\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher1.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    true, // $matchHost\n    [ // $staticRoutes\n        '/test/baz' => [[['_route' => 'baz'], null, null, null, false, false, null]],\n        '/test/baz.html' => [[['_route' => 'baz2'], null, null, null, false, false, null]],\n        '/test/baz3' => [[['_route' => 'baz3'], null, null, null, true, false, null]],\n        '/foofoo' => [[['_route' => 'foofoo', 'def' => 'test'], null, null, null, false, false, null]],\n        '/spa ce' => [[['_route' => 'space'], null, null, null, false, false, null]],\n        '/multi/new' => [[['_route' => 'overridden2'], null, null, null, false, false, null]],\n        '/multi/hey' => [[['_route' => 'hey'], null, null, null, true, false, null]],\n        '/ababa' => [[['_route' => 'ababa'], null, null, null, false, false, null]],\n        '/route1' => [[['_route' => 'route1'], 'a.example.com', null, null, false, false, null]],\n        '/c2/route2' => [[['_route' => 'route2'], 'a.example.com', null, null, false, false, null]],\n        '/route4' => [[['_route' => 'route4'], 'a.example.com', null, null, false, false, null]],\n        '/c2/route3' => [[['_route' => 'route3'], 'b.example.com', null, null, false, false, null]],\n        '/route5' => [[['_route' => 'route5'], 'c.example.com', null, null, false, false, null]],\n        '/route6' => [[['_route' => 'route6'], null, null, null, false, false, null]],\n        '/route11' => [[['_route' => 'route11'], '{^(?P<var1>[^\\\\.]++)\\\\.example\\\\.com$}sDi', null, null, false, false, null]],\n        '/route12' => [[['_route' => 'route12', 'var1' => 'val'], '{^(?P<var1>[^\\\\.]++)\\\\.example\\\\.com$}sDi', null, null, false, false, null]],\n        '/route17' => [[['_route' => 'route17'], null, null, null, false, false, null]],\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n            .'|(?:(?:[^./]*+\\\\.)++)(?'\n                .'|/foo/(baz|symfony)(*:47)'\n                .'|/bar(?'\n                    .'|/([^/]++)(*:70)'\n                    .'|head/([^/]++)(*:90)'\n                .')'\n                .'|/test/([^/]++)(?'\n                    .'|(*:115)'\n                .')'\n                .'|/([\\']+)(*:131)'\n                .'|/a/(?'\n                    .'|b\\'b/([^/]++)(?'\n                        .'|(*:160)'\n                        .'|(*:168)'\n                    .')'\n                    .'|(.*)(*:181)'\n                    .'|b\\'b/([^/]++)(?'\n                        .'|(*:204)'\n                        .'|(*:212)'\n                    .')'\n                .')'\n                .'|/multi/hello(?:/([^/]++))?(*:248)'\n                .'|/([^/]++)/b/([^/]++)(?'\n                    .'|(*:279)'\n                    .'|(*:287)'\n                .')'\n                .'|/aba/([^/]++)(*:309)'\n            .')|(?i:([^\\\\.]++)\\\\.example\\\\.com)\\\\.(?'\n                .'|/route1(?'\n                    .'|3/([^/]++)(*:371)'\n                    .'|4/([^/]++)(*:389)'\n                .')'\n            .')|(?i:c\\\\.example\\\\.com)\\\\.(?'\n                .'|/route15/([^/]++)(*:441)'\n            .')|(?:(?:[^./]*+\\\\.)++)(?'\n                .'|/route16/([^/]++)(*:489)'\n                .'|/a/(?'\n                    .'|a\\\\.\\\\.\\\\.(*:510)'\n                    .'|b/(?'\n                        .'|([^/]++)(*:531)'\n                        .'|c/([^/]++)(*:549)'\n                    .')'\n                .')'\n            .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        47 => [[['_route' => 'foo', 'def' => 'test'], ['bar'], null, null, false, true, null]],\n        70 => [[['_route' => 'bar'], ['foo'], ['GET' => 0, 'HEAD' => 1], null, false, true, null]],\n        90 => [[['_route' => 'barhead'], ['foo'], ['GET' => 0], null, false, true, null]],\n        115 => [\n            [['_route' => 'baz4'], ['foo'], null, null, true, true, null],\n            [['_route' => 'baz5'], ['foo'], ['POST' => 0], null, true, true, null],\n            [['_route' => 'baz.baz6'], ['foo'], ['PUT' => 0], null, true, true, null],\n        ],\n        131 => [[['_route' => 'quoter'], ['quoter'], null, null, false, true, null]],\n        160 => [[['_route' => 'foo1'], ['foo'], ['PUT' => 0], null, false, true, null]],\n        168 => [[['_route' => 'bar1'], ['bar'], null, null, false, true, null]],\n        181 => [[['_route' => 'overridden'], ['var'], null, null, false, true, null]],\n        204 => [[['_route' => 'foo2'], ['foo1'], null, null, false, true, null]],\n        212 => [[['_route' => 'bar2'], ['bar1'], null, null, false, true, null]],\n        248 => [[['_route' => 'helloWorld', 'who' => 'World!'], ['who'], null, null, false, true, null]],\n        279 => [[['_route' => 'foo3'], ['_locale', 'foo'], null, null, false, true, null]],\n        287 => [[['_route' => 'bar3'], ['_locale', 'bar'], null, null, false, true, null]],\n        309 => [[['_route' => 'foo4'], ['foo'], null, null, false, true, null]],\n        371 => [[['_route' => 'route13'], ['var1', 'name'], null, null, false, true, null]],\n        389 => [[['_route' => 'route14', 'var1' => 'val'], ['var1', 'name'], null, null, false, true, null]],\n        441 => [[['_route' => 'route15'], ['name'], null, null, false, true, null]],\n        489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],\n        510 => [[['_route' => 'a'], [], null, null, false, false, null]],\n        531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],\n        549 => [\n            [['_route' => 'c'], ['var'], null, null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher10.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/c(?'\n                    .'|f(?'\n                        .'|cd20/([^/]++)/([^/]++)/([^/]++)/cfcd20(*:54)'\n                        .'|e(?'\n                            .'|cdb/([^/]++)/([^/]++)/([^/]++)/cfecdb(*:102)'\n                            .'|e39/([^/]++)/([^/]++)/([^/]++)/cfee39(*:147)'\n                        .')'\n                        .'|a086/([^/]++)/([^/]++)/([^/]++)/cfa086(*:194)'\n                        .'|004f/([^/]++)/([^/]++)/([^/]++)/cf004f(*:240)'\n                    .')'\n                    .'|4(?'\n                        .'|ca42/([^/]++)/([^/]++)/([^/]++)/c4ca42(*:291)'\n                        .'|5147/([^/]++)/([^/]++)/([^/]++)/c45147(*:337)'\n                        .'|1000/([^/]++)/([^/]++)/([^/]++)/c41000(*:383)'\n                    .')'\n                    .'|8(?'\n                        .'|1e72/([^/]++)/([^/]++)/([^/]++)/c81e72(*:434)'\n                        .'|ffe9/([^/]++)/([^/]++)/([^/]++)/c8ffe9(*:480)'\n                        .'|6a7e/([^/]++)/([^/]++)/([^/]++)/c86a7e(*:526)'\n                    .')'\n                    .'|9(?'\n                        .'|f0f8/([^/]++)/([^/]++)/([^/]++)/c9f0f8(*:577)'\n                        .'|e107/([^/]++)/([^/]++)/([^/]++)/c9e107(*:623)'\n                    .')'\n                    .'|2(?'\n                        .'|0(?'\n                            .'|ad4/([^/]++)/([^/]++)/([^/]++)/c20ad4(*:677)'\n                            .'|3d8/([^/]++)/([^/]++)/([^/]++)/c203d8(*:722)'\n                        .')'\n                        .'|4cd7/([^/]++)/([^/]++)/([^/]++)/c24cd7(*:769)'\n                    .')'\n                    .'|5(?'\n                        .'|1ce4/([^/]++)/([^/]++)/([^/]++)/c51ce4(*:820)'\n                        .'|2f1b/([^/]++)/([^/]++)/([^/]++)/c52f1b(*:866)'\n                        .'|ff25/([^/]++)/([^/]++)/([^/]++)/c5ff25(*:912)'\n                    .')'\n                    .'|7(?'\n                        .'|4d97/([^/]++)/([^/]++)/([^/]++)/c74d97(*:963)'\n                        .'|e124/([^/]++)/([^/]++)/([^/]++)/c7e124(*:1009)'\n                    .')'\n                    .'|16a53/([^/]++)/([^/]++)/([^/]++)/c16a53(*:1058)'\n                    .'|0(?'\n                        .'|c7c7/([^/]++)/([^/]++)/([^/]++)/c0c7c7(*:1109)'\n                        .'|e190/([^/]++)/([^/]++)/([^/]++)/c0e190(*:1156)'\n                        .'|42f4/([^/]++)/([^/]++)/([^/]++)/c042f4(*:1203)'\n                        .'|58f5/([^/]++)/([^/]++)/([^/]++)/c058f5(*:1250)'\n                    .')'\n                    .'|e(?'\n                        .'|debb/([^/]++)/([^/]++)/([^/]++)/cedebb(*:1302)'\n                        .'|e631/([^/]++)/([^/]++)/([^/]++)/cee631(*:1349)'\n                    .')'\n                    .'|a(?'\n                        .'|46c1/([^/]++)/([^/]++)/([^/]++)/ca46c1(*:1401)'\n                        .'|f1a3/([^/]++)/([^/]++)/([^/]++)/caf1a3(*:1448)'\n                    .')'\n                    .'|b70ab/([^/]++)/([^/]++)/([^/]++)/cb70ab(*:1497)'\n                    .'|d0069/([^/]++)/([^/]++)/([^/]++)/cd0069(*:1545)'\n                    .'|3(?'\n                        .'|e878/([^/]++)/([^/]++)/([^/]++)/c3e878(*:1596)'\n                        .'|c59e/([^/]++)/([^/]++)/([^/]++)/c3c59e(*:1643)'\n                    .')'\n                .')'\n                .'|/e(?'\n                    .'|c(?'\n                        .'|cbc8/([^/]++)/([^/]++)/([^/]++)/eccbc8(*:1701)'\n                        .'|8(?'\n                            .'|956/([^/]++)/([^/]++)/([^/]++)/ec8956(*:1751)'\n                            .'|ce6/([^/]++)/([^/]++)/([^/]++)/ec8ce6(*:1797)'\n                        .')'\n                        .'|5dec/([^/]++)/([^/]++)/([^/]++)/ec5dec(*:1845)'\n                    .')'\n                    .'|4(?'\n                        .'|da3b/([^/]++)/([^/]++)/([^/]++)/e4da3b(*:1897)'\n                        .'|a622/([^/]++)/([^/]++)/([^/]++)/e4a622(*:1944)'\n                        .'|6de7/([^/]++)/([^/]++)/([^/]++)/e46de7(*:1991)'\n                        .'|4fea/([^/]++)/([^/]++)/([^/]++)/e44fea(*:2038)'\n                    .')'\n                    .'|3(?'\n                        .'|6985/([^/]++)/([^/]++)/([^/]++)/e36985(*:2090)'\n                        .'|796a/([^/]++)/([^/]++)/([^/]++)/e3796a(*:2137)'\n                    .')'\n                    .'|a(?'\n                        .'|5d2f/([^/]++)/([^/]++)/([^/]++)/ea5d2f(*:2189)'\n                        .'|e27d/([^/]++)/([^/]++)/([^/]++)/eae27d(*:2236)'\n                    .')'\n                    .'|2(?'\n                        .'|c(?'\n                            .'|420/([^/]++)/([^/]++)/([^/]++)/e2c420(*:2291)'\n                            .'|0be/([^/]++)/([^/]++)/([^/]++)/e2c0be(*:2337)'\n                        .')'\n                        .'|ef52/([^/]++)/([^/]++)/([^/]++)/e2ef52(*:2385)'\n                    .')'\n                    .'|d(?'\n                        .'|3d2c/([^/]++)/([^/]++)/([^/]++)/ed3d2c(*:2437)'\n                        .'|a80a/([^/]++)/([^/]++)/([^/]++)/eda80a(*:2484)'\n                        .'|dea8/([^/]++)/([^/]++)/([^/]++)/eddea8(*:2531)'\n                    .')'\n                    .'|b(?'\n                        .'|16(?'\n                            .'|0d/([^/]++)/([^/]++)/([^/]++)/eb160d(*:2586)'\n                            .'|37/([^/]++)/([^/]++)/([^/]++)/eb1637(*:2631)'\n                        .')'\n                        .'|a0dc/([^/]++)/([^/]++)/([^/]++)/eba0dc(*:2679)'\n                    .')'\n                    .'|0(?'\n                        .'|0da0/([^/]++)/([^/]++)/([^/]++)/e00da0(*:2731)'\n                        .'|c641/([^/]++)/([^/]++)/([^/]++)/e0c641(*:2778)'\n                    .')'\n                    .'|e(?'\n                        .'|cca5/([^/]++)/([^/]++)/([^/]++)/eecca5(*:2830)'\n                        .'|d5af/([^/]++)/([^/]++)/([^/]++)/eed5af(*:2877)'\n                    .')'\n                    .'|96ed4/([^/]++)/([^/]++)/([^/]++)/e96ed4(*:2926)'\n                    .'|1(?'\n                        .'|6542/([^/]++)/([^/]++)/([^/]++)/e16542(*:2977)'\n                        .'|e32e/([^/]++)/([^/]++)/([^/]++)/e1e32e(*:3024)'\n                    .')'\n                    .'|56954/([^/]++)/([^/]++)/([^/]++)/e56954(*:3073)'\n                    .'|f(?'\n                        .'|0d39/([^/]++)/([^/]++)/([^/]++)/ef0d39(*:3124)'\n                        .'|e937/([^/]++)/([^/]++)/([^/]++)/efe937(*:3171)'\n                        .'|575e/([^/]++)/([^/]++)/([^/]++)/ef575e(*:3218)'\n                    .')'\n                    .'|7b24b/([^/]++)/([^/]++)/([^/]++)/e7b24b(*:3267)'\n                    .'|836d8/([^/]++)/([^/]++)/([^/]++)/e836d8(*:3315)'\n                .')'\n                .'|/a(?'\n                    .'|8(?'\n                        .'|7ff6/([^/]++)/([^/]++)/([^/]++)/a87ff6(*:3372)'\n                        .'|baa5/([^/]++)/([^/]++)/([^/]++)/a8baa5(*:3419)'\n                        .'|f15e/([^/]++)/([^/]++)/([^/]++)/a8f15e(*:3466)'\n                        .'|c88a/([^/]++)/([^/]++)/([^/]++)/a8c88a(*:3513)'\n                        .'|abb4/([^/]++)/([^/]++)/([^/]++)/a8abb4(*:3560)'\n                    .')'\n                    .'|a(?'\n                        .'|b323/([^/]++)/([^/]++)/([^/]++)/aab323(*:3612)'\n                        .'|942a/([^/]++)/([^/]++)/([^/]++)/aa942a(*:3659)'\n                    .')'\n                    .'|5(?'\n                        .'|bfc9/([^/]++)/([^/]++)/([^/]++)/a5bfc9(*:3711)'\n                        .'|771b/([^/]++)/([^/]++)/([^/]++)/a5771b(*:3758)'\n                        .'|e001/([^/]++)/([^/]++)/([^/]++)/a5e001(*:3805)'\n                        .'|97e5/([^/]++)/([^/]++)/([^/]++)/a597e5(*:3852)'\n                        .'|16a8/([^/]++)/([^/]++)/([^/]++)/a516a8(*:3899)'\n                    .')'\n                    .'|1d0c6/([^/]++)/([^/]++)/([^/]++)/a1d0c6(*:3948)'\n                    .'|6(?'\n                        .'|84ec/([^/]++)/([^/]++)/([^/]++)/a684ec(*:3999)'\n                        .'|6658/([^/]++)/([^/]++)/([^/]++)/a66658(*:4046)'\n                    .')'\n                    .'|3(?'\n                        .'|f390/([^/]++)/([^/]++)/([^/]++)/a3f390(*:4098)'\n                        .'|c65c/([^/]++)/([^/]++)/([^/]++)/a3c65c(*:4145)'\n                    .')'\n                    .'|d(?'\n                        .'|61ab/([^/]++)/([^/]++)/([^/]++)/ad61ab(*:4197)'\n                        .'|13a2/([^/]++)/([^/]++)/([^/]++)/ad13a2(*:4244)'\n                        .'|972f/([^/]++)/([^/]++)/([^/]++)/ad972f(*:4291)'\n                    .')'\n                    .'|c(?'\n                        .'|627a/([^/]++)/([^/]++)/([^/]++)/ac627a(*:4343)'\n                        .'|1dd2/([^/]++)/([^/]++)/([^/]++)/ac1dd2(*:4390)'\n                    .')'\n                    .'|9(?'\n                        .'|7da6/([^/]++)/([^/]++)/([^/]++)/a97da6(*:4442)'\n                        .'|6b65/([^/]++)/([^/]++)/([^/]++)/a96b65(*:4489)'\n                    .')'\n                    .'|0(?'\n                        .'|a080/([^/]++)/([^/]++)/([^/]++)/a0a080(*:4541)'\n                        .'|2ffd/([^/]++)/([^/]++)/([^/]++)/a02ffd(*:4588)'\n                        .'|1a03/([^/]++)/([^/]++)/([^/]++)/a01a03(*:4635)'\n                    .')'\n                    .'|4(?'\n                        .'|a042/([^/]++)/([^/]++)/([^/]++)/a4a042(*:4687)'\n                        .'|f236/([^/]++)/([^/]++)/([^/]++)/a4f236(*:4734)'\n                        .'|9e94/([^/]++)/([^/]++)/([^/]++)/a49e94(*:4781)'\n                    .')'\n                    .'|2557a/([^/]++)/([^/]++)/([^/]++)/a2557a(*:4830)'\n                    .'|b817c/([^/]++)/([^/]++)/([^/]++)/ab817c(*:4878)'\n                .')'\n                .'|/1(?'\n                    .'|6(?'\n                        .'|7909/([^/]++)/([^/]++)/([^/]++)/167909(*:4935)'\n                        .'|a5cd/([^/]++)/([^/]++)/([^/]++)/16a5cd(*:4982)'\n                        .'|51cf/([^/]++)/([^/]++)/([^/]++)/1651cf(*:5029)'\n                    .')'\n                    .'|f(?'\n                        .'|0e3d/([^/]++)/([^/]++)/([^/]++)/1f0e3d(*:5081)'\n                        .'|f(?'\n                            .'|1de/([^/]++)/([^/]++)/([^/]++)/1ff1de(*:5131)'\n                            .'|8a7/([^/]++)/([^/]++)/([^/]++)/1ff8a7(*:5177)'\n                        .')'\n                    .')'\n                    .'|8(?'\n                        .'|2be0/([^/]++)/([^/]++)/([^/]++)/182be0(*:5230)'\n                        .'|d804/([^/]++)/([^/]++)/([^/]++)/18d804(*:5277)'\n                        .'|9977/([^/]++)/([^/]++)/([^/]++)/189977(*:5324)'\n                    .')'\n                    .'|c(?'\n                        .'|383c/([^/]++)/([^/]++)/([^/]++)/1c383c(*:5376)'\n                        .'|9ac0/([^/]++)/([^/]++)/([^/]++)/1c9ac0(*:5423)'\n                    .')'\n                    .'|9(?'\n                        .'|ca14/([^/]++)/([^/]++)/([^/]++)/19ca14(*:5475)'\n                        .'|f3cd/([^/]++)/([^/]++)/([^/]++)/19f3cd(*:5522)'\n                    .')'\n                    .'|7(?'\n                        .'|e621/([^/]++)/([^/]++)/([^/]++)/17e621(*:5574)'\n                        .'|0000/([^/]++)/([^/]++)/([^/]++)/170000(*:5621)'\n                        .'|d63b/([^/]++)/([^/]++)/([^/]++)/17d63b(*:5668)'\n                    .')'\n                    .'|4(?'\n                        .'|bfa6/([^/]++)/([^/]++)/([^/]++)/14bfa6(*:5720)'\n                        .'|0f69/([^/]++)/([^/]++)/([^/]++)/140f69(*:5767)'\n                        .'|9e96/([^/]++)/([^/]++)/([^/]++)/149e96(*:5814)'\n                        .'|2949/([^/]++)/([^/]++)/([^/]++)/142949(*:5861)'\n                    .')'\n                    .'|a(?'\n                        .'|fa34/([^/]++)/([^/]++)/([^/]++)/1afa34(*:5913)'\n                        .'|5b1e/([^/]++)/([^/]++)/([^/]++)/1a5b1e(*:5960)'\n                    .')'\n                    .'|3(?'\n                        .'|8(?'\n                            .'|597/([^/]++)/([^/]++)/([^/]++)/138597(*:6015)'\n                            .'|bb0/([^/]++)/([^/]++)/([^/]++)/138bb0(*:6061)'\n                        .')'\n                        .'|f(?'\n                            .'|e9d/([^/]++)/([^/]++)/([^/]++)/13fe9d(*:6112)'\n                            .'|989/([^/]++)/([^/]++)/([^/]++)/13f989(*:6158)'\n                            .'|3cf/([^/]++)/([^/]++)/([^/]++)/13f3cf(*:6204)'\n                        .')'\n                    .')'\n                    .'|d7f7a/([^/]++)/([^/]++)/([^/]++)/1d7f7a(*:6254)'\n                    .'|5(?'\n                        .'|34b7/([^/]++)/([^/]++)/([^/]++)/1534b7(*:6305)'\n                        .'|8f30/([^/]++)/([^/]++)/([^/]++)/158f30(*:6352)'\n                        .'|4384/([^/]++)/([^/]++)/([^/]++)/154384(*:6399)'\n                        .'|d4e8/([^/]++)/([^/]++)/([^/]++)/15d4e8(*:6446)'\n                    .')'\n                    .'|1(?'\n                        .'|5f89/([^/]++)/([^/]++)/([^/]++)/115f89(*:6498)'\n                        .'|b984/([^/]++)/([^/]++)/([^/]++)/11b984(*:6545)'\n                    .')'\n                    .'|068c6/([^/]++)/([^/]++)/([^/]++)/1068c6(*:6594)'\n                    .'|be3bc/([^/]++)/([^/]++)/([^/]++)/1be3bc(*:6642)'\n                .')'\n                .'|/8(?'\n                    .'|f(?'\n                        .'|1(?'\n                            .'|4e4/([^/]++)/([^/]++)/([^/]++)/8f14e4(*:6702)'\n                            .'|21c/([^/]++)/([^/]++)/([^/]++)/8f121c(*:6748)'\n                        .')'\n                        .'|8551/([^/]++)/([^/]++)/([^/]++)/8f8551(*:6796)'\n                        .'|5329/([^/]++)/([^/]++)/([^/]++)/8f5329(*:6843)'\n                        .'|e009/([^/]++)/([^/]++)/([^/]++)/8fe009(*:6890)'\n                    .')'\n                    .'|e(?'\n                        .'|296a/([^/]++)/([^/]++)/([^/]++)/8e296a(*:6942)'\n                        .'|98d8/([^/]++)/([^/]++)/([^/]++)/8e98d8(*:6989)'\n                        .'|fb10/([^/]++)/([^/]++)/([^/]++)/8efb10(*:7036)'\n                        .'|6b42/([^/]++)/([^/]++)/([^/]++)/8e6b42(*:7083)'\n                    .')'\n                    .'|61398/([^/]++)/([^/]++)/([^/]++)/861398(*:7132)'\n                    .'|1(?'\n                        .'|2b4b/([^/]++)/([^/]++)/([^/]++)/812b4b(*:7183)'\n                        .'|9f46/([^/]++)/([^/]++)/([^/]++)/819f46(*:7230)'\n                        .'|6b11/([^/]++)/([^/]++)/([^/]++)/816b11(*:7277)'\n                    .')'\n                    .'|d(?'\n                        .'|5e95/([^/]++)/([^/]++)/([^/]++)/8d5e95(*:7329)'\n                        .'|3bba/([^/]++)/([^/]++)/([^/]++)/8d3bba(*:7376)'\n                        .'|d48d/([^/]++)/([^/]++)/([^/]++)/8dd48d(*:7423)'\n                        .'|7d8e/([^/]++)/([^/]++)/([^/]++)/8d7d8e(*:7470)'\n                    .')'\n                    .'|2(?'\n                        .'|aa4b/([^/]++)/([^/]++)/([^/]++)/82aa4b(*:7522)'\n                        .'|1(?'\n                            .'|612/([^/]++)/([^/]++)/([^/]++)/821612(*:7572)'\n                            .'|fa7/([^/]++)/([^/]++)/([^/]++)/821fa7(*:7618)'\n                        .')'\n                        .'|cec9/([^/]++)/([^/]++)/([^/]++)/82cec9(*:7666)'\n                    .')'\n                    .'|5(?'\n                        .'|d8ce/([^/]++)/([^/]++)/([^/]++)/85d8ce(*:7718)'\n                        .'|4d(?'\n                            .'|6f/([^/]++)/([^/]++)/([^/]++)/854d6f(*:7768)'\n                            .'|9f/([^/]++)/([^/]++)/([^/]++)/854d9f(*:7813)'\n                        .')'\n                    .')'\n                    .'|4d9ee/([^/]++)/([^/]++)/([^/]++)/84d9ee(*:7863)'\n                    .'|c(?'\n                        .'|19f5/([^/]++)/([^/]++)/([^/]++)/8c19f5(*:7914)'\n                        .'|b22b/([^/]++)/([^/]++)/([^/]++)/8cb22b(*:7961)'\n                    .')'\n                    .'|39ab4/([^/]++)/([^/]++)/([^/]++)/839ab4(*:8010)'\n                    .'|9f0fd/([^/]++)/([^/]++)/([^/]++)/89f0fd(*:8058)'\n                    .'|bf121/([^/]++)/([^/]++)/([^/]++)/8bf121(*:8106)'\n                    .'|77a9b/([^/]++)/([^/]++)/([^/]++)/877a9b(*:8154)'\n                .')'\n                .'|/4(?'\n                    .'|5(?'\n                        .'|c48c/([^/]++)/([^/]++)/([^/]++)/45c48c(*:8211)'\n                        .'|fbc6/([^/]++)/([^/]++)/([^/]++)/45fbc6(*:8258)'\n                    .')'\n                    .'|e732c/([^/]++)/([^/]++)/([^/]++)/4e732c(*:8307)'\n                    .'|4f683/([^/]++)/([^/]++)/([^/]++)/44f683(*:8355)'\n                    .'|3(?'\n                        .'|ec51/([^/]++)/([^/]++)/([^/]++)/43ec51(*:8406)'\n                        .'|2aca/([^/]++)/([^/]++)/([^/]++)/432aca(*:8453)'\n                    .')'\n                    .'|c5(?'\n                        .'|6ff/([^/]++)/([^/]++)/([^/]++)/4c56ff(*:8505)'\n                        .'|bde/([^/]++)/([^/]++)/([^/]++)/4c5bde(*:8551)'\n                    .')'\n                    .'|2(?'\n                        .'|a0e1/([^/]++)/([^/]++)/([^/]++)/42a0e1(*:8603)'\n                        .'|e7aa/([^/]++)/([^/]++)/([^/]++)/42e7aa(*:8650)'\n                        .'|998c/([^/]++)/([^/]++)/([^/]++)/42998c(*:8697)'\n                        .'|8fca/([^/]++)/([^/]++)/([^/]++)/428fca(*:8744)'\n                    .')'\n                    .'|7(?'\n                        .'|d1e9/([^/]++)/([^/]++)/([^/]++)/47d1e9(*:8796)'\n                        .'|34ba/([^/]++)/([^/]++)/([^/]++)/4734ba(*:8843)'\n                    .')'\n                    .'|6ba9f/([^/]++)/([^/]++)/([^/]++)/46ba9f(*:8892)'\n                    .'|8aedb/([^/]++)/([^/]++)/([^/]++)/48aedb(*:8940)'\n                    .'|9(?'\n                        .'|182f/([^/]++)/([^/]++)/([^/]++)/49182f(*:8991)'\n                        .'|6e05/([^/]++)/([^/]++)/([^/]++)/496e05(*:9038)'\n                        .'|ae49/([^/]++)/([^/]++)/([^/]++)/49ae49(*:9085)'\n                    .')'\n                    .'|0008b/([^/]++)/([^/]++)/([^/]++)/40008b(*:9134)'\n                    .'|1(?'\n                        .'|f1f1/([^/]++)/([^/]++)/([^/]++)/41f1f1(*:9185)'\n                        .'|ae36/([^/]++)/([^/]++)/([^/]++)/41ae36(*:9232)'\n                    .')'\n                    .'|f(?'\n                        .'|6ffe/([^/]++)/([^/]++)/([^/]++)/4f6ffe(*:9284)'\n                        .'|4adc/([^/]++)/([^/]++)/([^/]++)/4f4adc(*:9331)'\n                    .')'\n                .')'\n                .'|/d(?'\n                    .'|3(?'\n                        .'|d944/([^/]++)/([^/]++)/([^/]++)/d3d944(*:9389)'\n                        .'|9577/([^/]++)/([^/]++)/([^/]++)/d39577(*:9436)'\n                        .'|4ab1/([^/]++)/([^/]++)/([^/]++)/d34ab1(*:9483)'\n                    .')'\n                    .'|6(?'\n                        .'|7d8a/([^/]++)/([^/]++)/([^/]++)/d67d8a(*:9535)'\n                        .'|4592/([^/]++)/([^/]++)/([^/]++)/d64592(*:9582)'\n                        .'|baf6/([^/]++)/([^/]++)/([^/]++)/d6baf6(*:9629)'\n                        .'|1e4b/([^/]++)/([^/]++)/([^/]++)/d61e4b(*:9676)'\n                    .')'\n                    .'|9(?'\n                        .'|d4f4/([^/]++)/([^/]++)/([^/]++)/d9d4f4(*:9728)'\n                        .'|6409/([^/]++)/([^/]++)/([^/]++)/d96409(*:9775)'\n                        .'|47bf/([^/]++)/([^/]++)/([^/]++)/d947bf(*:9822)'\n                        .'|fc5b/([^/]++)/([^/]++)/([^/]++)/d9fc5b(*:9869)'\n                    .')'\n                    .'|8(?'\n                        .'|2c8d/([^/]++)/([^/]++)/([^/]++)/d82c8d(*:9921)'\n                        .'|1f9c/([^/]++)/([^/]++)/([^/]++)/d81f9c(*:9968)'\n                    .')'\n                    .'|2(?'\n                        .'|ddea/([^/]++)/([^/]++)/([^/]++)/d2ddea(*:10020)'\n                        .'|96c1/([^/]++)/([^/]++)/([^/]++)/d296c1(*:10068)'\n                    .')'\n                    .'|0(?'\n                        .'|9bf4/([^/]++)/([^/]++)/([^/]++)/d09bf4(*:10121)'\n                        .'|7e70/([^/]++)/([^/]++)/([^/]++)/d07e70(*:10169)'\n                    .')'\n                    .'|1(?'\n                        .'|f(?'\n                            .'|e17/([^/]++)/([^/]++)/([^/]++)/d1fe17(*:10225)'\n                            .'|491/([^/]++)/([^/]++)/([^/]++)/d1f491(*:10272)'\n                            .'|255/([^/]++)/([^/]++)/([^/]++)/d1f255(*:10319)'\n                        .')'\n                        .'|c38a/([^/]++)/([^/]++)/([^/]++)/d1c38a(*:10368)'\n                        .'|8f65/([^/]++)/([^/]++)/([^/]++)/d18f65(*:10416)'\n                    .')'\n                    .'|a4fb5/([^/]++)/([^/]++)/([^/]++)/da4fb5(*:10466)'\n                    .'|b8e1a/([^/]++)/([^/]++)/([^/]++)/db8e1a(*:10515)'\n                    .'|709f3/([^/]++)/([^/]++)/([^/]++)/d709f3(*:10564)'\n                    .'|c(?'\n                        .'|912a/([^/]++)/([^/]++)/([^/]++)/dc912a(*:10616)'\n                        .'|6a64/([^/]++)/([^/]++)/([^/]++)/dc6a64(*:10664)'\n                    .')'\n                    .'|db306/([^/]++)/([^/]++)/([^/]++)/ddb306(*:10714)'\n                .')'\n                .'|/6(?'\n                    .'|5(?'\n                        .'|12bd/([^/]++)/([^/]++)/([^/]++)/6512bd(*:10772)'\n                        .'|b9ee/([^/]++)/([^/]++)/([^/]++)/65b9ee(*:10820)'\n                        .'|ded5/([^/]++)/([^/]++)/([^/]++)/65ded5(*:10868)'\n                    .')'\n                    .'|f(?'\n                        .'|4922/([^/]++)/([^/]++)/([^/]++)/6f4922(*:10921)'\n                        .'|3ef7/([^/]++)/([^/]++)/([^/]++)/6f3ef7(*:10969)'\n                        .'|aa80/([^/]++)/([^/]++)/([^/]++)/6faa80(*:11017)'\n                    .')'\n                    .'|e(?'\n                        .'|a(?'\n                            .'|9ab/([^/]++)/([^/]++)/([^/]++)/6ea9ab(*:11073)'\n                            .'|2ef/([^/]++)/([^/]++)/([^/]++)/6ea2ef(*:11120)'\n                        .')'\n                        .'|cbdd/([^/]++)/([^/]++)/([^/]++)/6ecbdd(*:11169)'\n                    .')'\n                    .'|3(?'\n                        .'|64d3/([^/]++)/([^/]++)/([^/]++)/6364d3(*:11222)'\n                        .'|dc7e/([^/]++)/([^/]++)/([^/]++)/63dc7e(*:11270)'\n                        .'|923f/([^/]++)/([^/]++)/([^/]++)/63923f(*:11318)'\n                    .')'\n                    .'|c(?'\n                        .'|8349/([^/]++)/([^/]++)/([^/]++)/6c8349(*:11371)'\n                        .'|4b76/([^/]++)/([^/]++)/([^/]++)/6c4b76(*:11419)'\n                        .'|dd60/([^/]++)/([^/]++)/([^/]++)/6cdd60(*:11467)'\n                        .'|9882/([^/]++)/([^/]++)/([^/]++)/6c9882(*:11515)'\n                        .'|524f/([^/]++)/([^/]++)/([^/]++)/6c524f(*:11563)'\n                    .')'\n                    .'|7(?'\n                        .'|c6a1/([^/]++)/([^/]++)/([^/]++)/67c6a1(*:11616)'\n                        .'|f7fb/([^/]++)/([^/]++)/([^/]++)/67f7fb(*:11664)'\n                    .')'\n                    .'|42e92/([^/]++)/([^/]++)/([^/]++)/642e92(*:11714)'\n                    .'|6(?'\n                        .'|f041/([^/]++)/([^/]++)/([^/]++)/66f041(*:11766)'\n                        .'|808e/([^/]++)/([^/]++)/([^/]++)/66808e(*:11814)'\n                        .'|3682/([^/]++)/([^/]++)/([^/]++)/663682(*:11862)'\n                    .')'\n                    .'|8(?'\n                        .'|d30a/([^/]++)/([^/]++)/([^/]++)/68d30a(*:11915)'\n                        .'|8396/([^/]++)/([^/]++)/([^/]++)/688396(*:11963)'\n                        .'|5545/([^/]++)/([^/]++)/([^/]++)/685545(*:12011)'\n                        .'|ce19/([^/]++)/([^/]++)/([^/]++)/68ce19(*:12059)'\n                    .')'\n                    .'|9(?'\n                        .'|74ce/([^/]++)/([^/]++)/([^/]++)/6974ce(*:12112)'\n                        .'|8d51/([^/]++)/([^/]++)/([^/]++)/698d51(*:12160)'\n                        .'|adc1/([^/]++)/([^/]++)/([^/]++)/69adc1(*:12208)'\n                        .'|cb3e/([^/]++)/([^/]++)/([^/]++)/69cb3e(*:12256)'\n                    .')'\n                    .'|da(?'\n                        .'|900/([^/]++)/([^/]++)/([^/]++)/6da900(*:12309)'\n                        .'|37d/([^/]++)/([^/]++)/([^/]++)/6da37d(*:12356)'\n                    .')'\n                    .'|21bf6/([^/]++)/([^/]++)/([^/]++)/621bf6(*:12406)'\n                    .'|a9aed/([^/]++)/([^/]++)/([^/]++)/6a9aed(*:12455)'\n                .')'\n                .'|/9(?'\n                    .'|b(?'\n                        .'|f31c/([^/]++)/([^/]++)/([^/]++)/9bf31c(*:12513)'\n                        .'|8619/([^/]++)/([^/]++)/([^/]++)/9b8619(*:12561)'\n                        .'|04d1/([^/]++)/([^/]++)/([^/]++)/9b04d1(*:12609)'\n                        .'|e40c/([^/]++)/([^/]++)/([^/]++)/9be40c(*:12657)'\n                        .'|70e8/([^/]++)/([^/]++)/([^/]++)/9b70e8(*:12705)'\n                    .')'\n                    .'|8(?'\n                        .'|f137/([^/]++)/([^/]++)/([^/]++)/98f137(*:12758)'\n                        .'|dce8/([^/]++)/([^/]++)/([^/]++)/98dce8(*:12806)'\n                        .'|72ed/([^/]++)/([^/]++)/([^/]++)/9872ed(*:12854)'\n                        .'|b297/([^/]++)/([^/]++)/([^/]++)/98b297(*:12902)'\n                    .')'\n                    .'|a(?'\n                        .'|1158/([^/]++)/([^/]++)/([^/]++)/9a1158(*:12955)'\n                        .'|9687/([^/]++)/([^/]++)/([^/]++)/9a9687(*:13003)'\n                    .')'\n                    .'|f(?'\n                        .'|6140/([^/]++)/([^/]++)/([^/]++)/9f6140(*:13056)'\n                        .'|c3d7/([^/]++)/([^/]++)/([^/]++)/9fc3d7(*:13104)'\n                        .'|d818/([^/]++)/([^/]++)/([^/]++)/9fd818(*:13152)'\n                    .')'\n                    .'|7(?'\n                        .'|78d5/([^/]++)/([^/]++)/([^/]++)/9778d5(*:13205)'\n                        .'|6652/([^/]++)/([^/]++)/([^/]++)/976652(*:13253)'\n                        .'|9d47/([^/]++)/([^/]++)/([^/]++)/979d47(*:13301)'\n                    .')'\n                    .'|3db85/([^/]++)/([^/]++)/([^/]++)/93db85(*:13351)'\n                    .'|2c(?'\n                        .'|c22/([^/]++)/([^/]++)/([^/]++)/92cc22(*:13403)'\n                        .'|8c9/([^/]++)/([^/]++)/([^/]++)/92c8c9(*:13450)'\n                    .')'\n                    .'|03ce9/([^/]++)/([^/]++)/([^/]++)/903ce9(*:13500)'\n                    .'|6da2f/([^/]++)/([^/]++)/([^/]++)/96da2f(*:13549)'\n                    .'|d(?'\n                        .'|cb88/([^/]++)/([^/]++)/([^/]++)/9dcb88(*:13601)'\n                        .'|fcd5/([^/]++)/([^/]++)/([^/]++)/9dfcd5(*:13649)'\n                        .'|e6d1/([^/]++)/([^/]++)/([^/]++)/9de6d1(*:13697)'\n                    .')'\n                    .'|c(?'\n                        .'|fdf1/([^/]++)/([^/]++)/([^/]++)/9cfdf1(*:13750)'\n                        .'|838d/([^/]++)/([^/]++)/([^/]++)/9c838d(*:13798)'\n                    .')'\n                    .'|18(?'\n                        .'|890/([^/]++)/([^/]++)/([^/]++)/918890(*:13851)'\n                        .'|317/([^/]++)/([^/]++)/([^/]++)/918317(*:13898)'\n                    .')'\n                    .'|4(?'\n                        .'|f6d7/([^/]++)/([^/]++)/([^/]++)/94f6d7(*:13951)'\n                        .'|1e1a/([^/]++)/([^/]++)/([^/]++)/941e1a(*:13999)'\n                        .'|31c8/([^/]++)/([^/]++)/([^/]++)/9431c8(*:14047)'\n                        .'|61cc/([^/]++)/([^/]++)/([^/]++)/9461cc(*:14095)'\n                    .')'\n                    .'|50a41/([^/]++)/([^/]++)/([^/]++)/950a41(*:14145)'\n                .')'\n                .'|/7(?'\n                    .'|0(?'\n                        .'|efdf/([^/]++)/([^/]++)/([^/]++)/70efdf(*:14203)'\n                        .'|5f21/([^/]++)/([^/]++)/([^/]++)/705f21(*:14251)'\n                        .'|c639/([^/]++)/([^/]++)/([^/]++)/70c639(*:14299)'\n                    .')'\n                    .'|2b32a/([^/]++)/([^/]++)/([^/]++)/72b32a(*:14349)'\n                    .'|f(?'\n                        .'|39f8/([^/]++)/([^/]++)/([^/]++)/7f39f8(*:14401)'\n                        .'|6ffa/([^/]++)/([^/]++)/([^/]++)/7f6ffa(*:14449)'\n                        .'|1(?'\n                            .'|de2/([^/]++)/([^/]++)/([^/]++)/7f1de2(*:14500)'\n                            .'|00b/([^/]++)/([^/]++)/([^/]++)/7f100b(*:14547)'\n                        .')'\n                        .'|e1f8/([^/]++)/([^/]++)/([^/]++)/7fe1f8(*:14596)'\n                    .')'\n                    .'|3(?'\n                        .'|5b90/([^/]++)/([^/]++)/([^/]++)/735b90(*:14649)'\n                        .'|278a/([^/]++)/([^/]++)/([^/]++)/73278a(*:14697)'\n                        .'|80ad/([^/]++)/([^/]++)/([^/]++)/7380ad(*:14745)'\n                    .')'\n                    .'|cbbc4/([^/]++)/([^/]++)/([^/]++)/7cbbc4(*:14795)'\n                    .'|6(?'\n                        .'|4796/([^/]++)/([^/]++)/([^/]++)/764796(*:14847)'\n                        .'|dc61/([^/]++)/([^/]++)/([^/]++)/76dc61(*:14895)'\n                    .')'\n                    .'|e(?'\n                        .'|f605/([^/]++)/([^/]++)/([^/]++)/7ef605(*:14948)'\n                        .'|7757/([^/]++)/([^/]++)/([^/]++)/7e7757(*:14996)'\n                        .'|a(?'\n                            .'|be3/([^/]++)/([^/]++)/([^/]++)/7eabe3(*:15047)'\n                            .'|cb5/([^/]++)/([^/]++)/([^/]++)/7eacb5(*:15094)'\n                        .')'\n                    .')'\n                    .'|5(?'\n                        .'|7b50/([^/]++)/([^/]++)/([^/]++)/757b50(*:15148)'\n                        .'|8874/([^/]++)/([^/]++)/([^/]++)/758874(*:15196)'\n                        .'|fc09/([^/]++)/([^/]++)/([^/]++)/75fc09(*:15244)'\n                    .')'\n                    .'|4(?'\n                        .'|db12/([^/]++)/([^/]++)/([^/]++)/74db12(*:15297)'\n                        .'|071a/([^/]++)/([^/]++)/([^/]++)/74071a(*:15345)'\n                    .')'\n                    .'|a614f/([^/]++)/([^/]++)/([^/]++)/7a614f(*:15395)'\n                    .'|d04bb/([^/]++)/([^/]++)/([^/]++)/7d04bb(*:15444)'\n                .')'\n                .'|/3(?'\n                    .'|c(?'\n                        .'|59dc/([^/]++)/([^/]++)/([^/]++)/3c59dc(*:15502)'\n                        .'|ec07/([^/]++)/([^/]++)/([^/]++)/3cec07(*:15550)'\n                        .'|7781/([^/]++)/([^/]++)/([^/]++)/3c7781(*:15598)'\n                        .'|f166/([^/]++)/([^/]++)/([^/]++)/3cf166(*:15646)'\n                    .')'\n                    .'|7(?'\n                        .'|693c/([^/]++)/([^/]++)/([^/]++)/37693c(*:15699)'\n                        .'|a749/([^/]++)/([^/]++)/([^/]++)/37a749(*:15747)'\n                        .'|bc2f/([^/]++)/([^/]++)/([^/]++)/37bc2f(*:15795)'\n                        .'|1bce/([^/]++)/([^/]++)/([^/]++)/371bce(*:15843)'\n                    .')'\n                    .'|3(?'\n                        .'|e75f/([^/]++)/([^/]++)/([^/]++)/33e75f(*:15896)'\n                        .'|5f53/([^/]++)/([^/]++)/([^/]++)/335f53(*:15944)'\n                    .')'\n                    .'|4(?'\n                        .'|1(?'\n                            .'|73c/([^/]++)/([^/]++)/([^/]++)/34173c(*:16000)'\n                            .'|6a7/([^/]++)/([^/]++)/([^/]++)/3416a7(*:16047)'\n                        .')'\n                        .'|ed06/([^/]++)/([^/]++)/([^/]++)/34ed06(*:16096)'\n                    .')'\n                    .'|2(?'\n                        .'|95c7/([^/]++)/([^/]++)/([^/]++)/3295c7(*:16149)'\n                        .'|bb90/([^/]++)/([^/]++)/([^/]++)/32bb90(*:16197)'\n                        .'|0722/([^/]++)/([^/]++)/([^/]++)/320722(*:16245)'\n                    .')'\n                    .'|5(?'\n                        .'|f4a8/([^/]++)/([^/]++)/([^/]++)/35f4a8(*:16298)'\n                        .'|7a6f/([^/]++)/([^/]++)/([^/]++)/357a6f(*:16346)'\n                        .'|2fe2/([^/]++)/([^/]++)/([^/]++)/352fe2(*:16394)'\n                        .'|0510/([^/]++)/([^/]++)/([^/]++)/350510(*:16442)'\n                    .')'\n                    .'|ef815/([^/]++)/([^/]++)/([^/]++)/3ef815(*:16492)'\n                    .'|8(?'\n                        .'|b3ef/([^/]++)/([^/]++)/([^/]++)/38b3ef(*:16544)'\n                        .'|af86/([^/]++)/([^/]++)/([^/]++)/38af86(*:16592)'\n                        .'|db3a/([^/]++)/([^/]++)/([^/]++)/38db3a(*:16640)'\n                    .')'\n                    .'|d(?'\n                        .'|ef18/([^/]++)/([^/]++)/([^/]++)/3def18(*:16693)'\n                        .'|d48a/([^/]++)/([^/]++)/([^/]++)/3dd48a(*:16741)'\n                    .')'\n                    .'|9(?'\n                        .'|88c7/([^/]++)/([^/]++)/([^/]++)/3988c7(*:16794)'\n                        .'|0597/([^/]++)/([^/]++)/([^/]++)/390597(*:16842)'\n                        .'|461a/([^/]++)/([^/]++)/([^/]++)/39461a(*:16890)'\n                    .')'\n                    .'|6(?'\n                        .'|3663/([^/]++)/([^/]++)/([^/]++)/363663(*:16943)'\n                        .'|44a6/([^/]++)/([^/]++)/([^/]++)/3644a6(*:16991)'\n                        .'|660e/([^/]++)/([^/]++)/([^/]++)/36660e(*:17039)'\n                    .')'\n                    .'|1(?'\n                        .'|fefc/([^/]++)/([^/]++)/([^/]++)/31fefc(*:17092)'\n                        .'|0dcb/([^/]++)/([^/]++)/([^/]++)/310dcb(*:17140)'\n                    .')'\n                    .'|b8a61/([^/]++)/([^/]++)/([^/]++)/3b8a61(*:17190)'\n                    .'|fe94a/([^/]++)/([^/]++)/([^/]++)/3fe94a(*:17239)'\n                    .'|ad7c2/([^/]++)/([^/]++)/([^/]++)/3ad7c2(*:17288)'\n                .')'\n                .'|/b(?'\n                    .'|6(?'\n                        .'|d767/([^/]++)/([^/]++)/([^/]++)/b6d767(*:17346)'\n                        .'|f047/([^/]++)/([^/]++)/([^/]++)/b6f047(*:17394)'\n                    .')'\n                    .'|53(?'\n                        .'|b3a/([^/]++)/([^/]++)/([^/]++)/b53b3a(*:17447)'\n                        .'|4ba/([^/]++)/([^/]++)/([^/]++)/b534ba(*:17494)'\n                    .')'\n                    .'|3(?'\n                        .'|e3e3/([^/]++)/([^/]++)/([^/]++)/b3e3e3(*:17547)'\n                        .'|967a/([^/]++)/([^/]++)/([^/]++)/b3967a(*:17595)'\n                    .')'\n                    .'|7(?'\n                        .'|3ce3/([^/]++)/([^/]++)/([^/]++)/b73ce3(*:17648)'\n                        .'|b16e/([^/]++)/([^/]++)/([^/]++)/b7b16e(*:17696)'\n                    .')'\n                    .'|d(?'\n                        .'|4c9a/([^/]++)/([^/]++)/([^/]++)/bd4c9a(*:17749)'\n                        .'|686f/([^/]++)/([^/]++)/([^/]++)/bd686f(*:17797)'\n                    .')'\n                    .'|f8229/([^/]++)/([^/]++)/([^/]++)/bf8229(*:17847)'\n                    .'|1(?'\n                        .'|d10e/([^/]++)/([^/]++)/([^/]++)/b1d10e(*:17899)'\n                        .'|a59b/([^/]++)/([^/]++)/([^/]++)/b1a59b(*:17947)'\n                    .')'\n                    .'|c(?'\n                        .'|be33/([^/]++)/([^/]++)/([^/]++)/bcbe33(*:18000)'\n                        .'|6dc4/([^/]++)/([^/]++)/([^/]++)/bc6dc4(*:18048)'\n                        .'|a82e/([^/]++)/([^/]++)/([^/]++)/bca82e(*:18096)'\n                    .')'\n                    .'|e(?'\n                        .'|83ab/([^/]++)/([^/]++)/([^/]++)/be83ab(*:18149)'\n                        .'|ed13/([^/]++)/([^/]++)/([^/]++)/beed13(*:18197)'\n                    .')'\n                    .'|2eb73/([^/]++)/([^/]++)/([^/]++)/b2eb73(*:18247)'\n                    .'|83aac/([^/]++)/([^/]++)/([^/]++)/b83aac(*:18296)'\n                    .'|ac916/([^/]++)/([^/]++)/([^/]++)/bac916(*:18345)'\n                    .'|b(?'\n                        .'|f94b/([^/]++)/([^/]++)/([^/]++)/bbf94b(*:18397)'\n                        .'|cbff/([^/]++)/([^/]++)/([^/]++)/bbcbff(*:18445)'\n                    .')'\n                    .'|9228e/([^/]++)/([^/]++)/([^/]++)/b9228e(*:18495)'\n                .')'\n                .'|/0(?'\n                    .'|2(?'\n                        .'|e74f/([^/]++)/([^/]++)/([^/]++)/02e74f(*:18553)'\n                        .'|522a/([^/]++)/([^/]++)/([^/]++)/02522a(*:18601)'\n                        .'|66e3/([^/]++)/([^/]++)/([^/]++)/0266e3(*:18649)'\n                    .')'\n                    .'|9(?'\n                        .'|3f65/([^/]++)/([^/]++)/([^/]++)/093f65(*:18702)'\n                        .'|1d58/([^/]++)/([^/]++)/([^/]++)/091d58(*:18750)'\n                    .')'\n                    .'|7(?'\n                        .'|2b03/([^/]++)/([^/]++)/([^/]++)/072b03(*:18803)'\n                        .'|e1cd/([^/]++)/([^/]++)/([^/]++)/07e1cd(*:18851)'\n                        .'|7(?'\n                            .'|7d5/([^/]++)/([^/]++)/([^/]++)/0777d5(*:18902)'\n                            .'|e29/([^/]++)/([^/]++)/([^/]++)/077e29(*:18949)'\n                        .')'\n                        .'|cdfd/([^/]++)/([^/]++)/([^/]++)/07cdfd(*:18998)'\n                    .')'\n                    .'|3(?'\n                        .'|afdb/([^/]++)/([^/]++)/([^/]++)/03afdb(*:19051)'\n                        .'|36dc/([^/]++)/([^/]++)/([^/]++)/0336dc(*:19099)'\n                        .'|c6b0/([^/]++)/([^/]++)/([^/]++)/03c6b0(*:19147)'\n                        .'|53ab/([^/]++)/([^/]++)/([^/]++)/0353ab(*:19195)'\n                    .')'\n                    .'|6(?'\n                        .'|9059/([^/]++)/([^/]++)/([^/]++)/069059(*:19248)'\n                        .'|4096/([^/]++)/([^/]++)/([^/]++)/064096(*:19296)'\n                        .'|0ad9/([^/]++)/([^/]++)/([^/]++)/060ad9(*:19344)'\n                        .'|138b/([^/]++)/([^/]++)/([^/]++)/06138b(*:19392)'\n                        .'|eb61/([^/]++)/([^/]++)/([^/]++)/06eb61(*:19440)'\n                    .')'\n                    .'|1(?'\n                        .'|3(?'\n                            .'|d40/([^/]++)/([^/]++)/([^/]++)/013d40(*:19496)'\n                            .'|86b/([^/]++)/([^/]++)/([^/]++)/01386b(*:19543)'\n                        .')'\n                        .'|161a/([^/]++)/([^/]++)/([^/]++)/01161a(*:19592)'\n                        .'|9d38/([^/]++)/([^/]++)/([^/]++)/019d38(*:19640)'\n                    .')'\n                    .'|f(?'\n                        .'|28b5/([^/]++)/([^/]++)/([^/]++)/0f28b5(*:19693)'\n                        .'|49c8/([^/]++)/([^/]++)/([^/]++)/0f49c8(*:19741)'\n                    .')'\n                    .'|a(?'\n                        .'|09c8/([^/]++)/([^/]++)/([^/]++)/0a09c8(*:19794)'\n                        .'|a188/([^/]++)/([^/]++)/([^/]++)/0aa188(*:19842)'\n                    .')'\n                    .'|0(?'\n                        .'|6f52/([^/]++)/([^/]++)/([^/]++)/006f52(*:19895)'\n                        .'|4114/([^/]++)/([^/]++)/([^/]++)/004114(*:19943)'\n                        .'|ec53/([^/]++)/([^/]++)/([^/]++)/00ec53(*:19991)'\n                    .')'\n                    .'|4(?'\n                        .'|5117/([^/]++)/([^/]++)/([^/]++)/045117(*:20044)'\n                        .'|0259/([^/]++)/([^/]++)/([^/]++)/040259(*:20092)'\n                    .')'\n                    .'|84b6f/([^/]++)/([^/]++)/([^/]++)/084b6f(*:20142)'\n                    .'|e(?'\n                        .'|6597/([^/]++)/([^/]++)/([^/]++)/0e6597(*:20194)'\n                        .'|0193/([^/]++)/([^/]++)/([^/]++)/0e0193(*:20242)'\n                    .')'\n                    .'|bb4ae/([^/]++)/([^/]++)/([^/]++)/0bb4ae(*:20292)'\n                    .'|5(?'\n                        .'|049e/([^/]++)/([^/]++)/([^/]++)/05049e(*:20344)'\n                        .'|84ce/([^/]++)/([^/]++)/([^/]++)/0584ce(*:20392)'\n                        .'|f971/([^/]++)/([^/]++)/([^/]++)/05f971(*:20440)'\n                    .')'\n                    .'|c74b7/([^/]++)/([^/]++)/([^/]++)/0c74b7(*:20490)'\n                    .'|d(?'\n                        .'|0fd7/([^/]++)/([^/]++)/([^/]++)/0d0fd7(*:20542)'\n                        .'|eb1c/([^/]++)/([^/]++)/([^/]++)/0deb1c(*:20590)'\n                    .')'\n                .')'\n                .'|/f(?'\n                    .'|7(?'\n                        .'|1(?'\n                            .'|771/([^/]++)/([^/]++)/([^/]++)/f71771(*:20652)'\n                            .'|849/([^/]++)/([^/]++)/([^/]++)/f71849(*:20699)'\n                        .')'\n                        .'|e6c8/([^/]++)/([^/]++)/([^/]++)/f7e6c8(*:20748)'\n                        .'|6640/([^/]++)/([^/]++)/([^/]++)/f76640(*:20796)'\n                        .'|3b76/([^/]++)/([^/]++)/([^/]++)/f73b76(*:20844)'\n                        .'|4909/([^/]++)/([^/]++)/([^/]++)/f74909(*:20892)'\n                        .'|70b6/([^/]++)/([^/]++)/([^/]++)/f770b6(*:20940)'\n                    .')'\n                    .'|4(?'\n                        .'|57c5/([^/]++)/([^/]++)/([^/]++)/f457c5(*:20993)'\n                        .'|b9ec/([^/]++)/([^/]++)/([^/]++)/f4b9ec(*:21041)'\n                        .'|f6dc/([^/]++)/([^/]++)/([^/]++)/f4f6dc(*:21089)'\n                    .')'\n                    .'|c(?'\n                        .'|490c/([^/]++)/([^/]++)/([^/]++)/fc490c(*:21142)'\n                        .'|2213/([^/]++)/([^/]++)/([^/]++)/fc2213(*:21190)'\n                        .'|cb60/([^/]++)/([^/]++)/([^/]++)/fccb60(*:21238)'\n                    .')'\n                    .'|b(?'\n                        .'|d793/([^/]++)/([^/]++)/([^/]++)/fbd793(*:21291)'\n                        .'|7b9f/([^/]++)/([^/]++)/([^/]++)/fb7b9f(*:21339)'\n                    .')'\n                    .'|0(?'\n                        .'|33ab/([^/]++)/([^/]++)/([^/]++)/f033ab(*:21392)'\n                        .'|935e/([^/]++)/([^/]++)/([^/]++)/f0935e(*:21440)'\n                    .')'\n                    .'|e(?'\n                        .'|9fc2/([^/]++)/([^/]++)/([^/]++)/fe9fc2(*:21493)'\n                        .'|131d/([^/]++)/([^/]++)/([^/]++)/fe131d(*:21541)'\n                        .'|73f6/([^/]++)/([^/]++)/([^/]++)/fe73f6(*:21589)'\n                    .')'\n                    .'|8(?'\n                        .'|9913/([^/]++)/([^/]++)/([^/]++)/f89913(*:21642)'\n                        .'|c1f2/([^/]++)/([^/]++)/([^/]++)/f8c1f2(*:21690)'\n                        .'|5454/([^/]++)/([^/]++)/([^/]++)/f85454(*:21738)'\n                    .')'\n                    .'|2(?'\n                        .'|2170/([^/]++)/([^/]++)/([^/]++)/f22170(*:21791)'\n                        .'|fc99/([^/]++)/([^/]++)/([^/]++)/f2fc99(*:21839)'\n                    .')'\n                    .'|a(?'\n                        .'|7cdf/([^/]++)/([^/]++)/([^/]++)/fa7cdf(*:21892)'\n                        .'|a9af/([^/]++)/([^/]++)/([^/]++)/faa9af(*:21940)'\n                    .')'\n                    .'|340f1/([^/]++)/([^/]++)/([^/]++)/f340f1(*:21990)'\n                    .'|9(?'\n                        .'|0f2a/([^/]++)/([^/]++)/([^/]++)/f90f2a(*:22042)'\n                        .'|b902/([^/]++)/([^/]++)/([^/]++)/f9b902(*:22090)'\n                    .')'\n                    .'|fd52f/([^/]++)/([^/]++)/([^/]++)/ffd52f(*:22140)'\n                    .'|61d69/([^/]++)/([^/]++)/([^/]++)/f61d69(*:22189)'\n                    .'|5f859/([^/]++)/([^/]++)/([^/]++)/f5f859(*:22238)'\n                    .'|1b6f2/([^/]++)/([^/]++)/([^/]++)/f1b6f2(*:22287)'\n                .')'\n                .'|/2(?'\n                    .'|8(?'\n                        .'|3802/([^/]++)/([^/]++)/([^/]++)/283802(*:22345)'\n                        .'|dd2c/([^/]++)/([^/]++)/([^/]++)/28dd2c(*:22393)'\n                        .'|9dff/([^/]++)/([^/]++)/([^/]++)/289dff(*:22441)'\n                        .'|f0b8/([^/]++)/([^/]++)/([^/]++)/28f0b8(*:22489)'\n                    .')'\n                    .'|a(?'\n                        .'|38a4/([^/]++)/([^/]++)/([^/]++)/2a38a4(*:22542)'\n                        .'|79ea/([^/]++)/([^/]++)/([^/]++)/2a79ea(*:22590)'\n                    .')'\n                    .'|6(?'\n                        .'|657d/([^/]++)/([^/]++)/([^/]++)/26657d(*:22643)'\n                        .'|e359/([^/]++)/([^/]++)/([^/]++)/26e359(*:22691)'\n                        .'|3373/([^/]++)/([^/]++)/([^/]++)/263373(*:22739)'\n                    .')'\n                    .'|7(?'\n                        .'|23d0/([^/]++)/([^/]++)/([^/]++)/2723d0(*:22792)'\n                        .'|4ad4/([^/]++)/([^/]++)/([^/]++)/274ad4(*:22840)'\n                    .')'\n                    .'|b(?'\n                        .'|4492/([^/]++)/([^/]++)/([^/]++)/2b4492(*:22893)'\n                        .'|24d4/([^/]++)/([^/]++)/([^/]++)/2b24d4(*:22941)'\n                    .')'\n                    .'|0(?'\n                        .'|2cb9/([^/]++)/([^/]++)/([^/]++)/202cb9(*:22994)'\n                        .'|f075/([^/]++)/([^/]++)/([^/]++)/20f075(*:23042)'\n                        .'|50e0/([^/]++)/([^/]++)/([^/]++)/2050e0(*:23090)'\n                    .')'\n                    .'|f(?'\n                        .'|2b26/([^/]++)/([^/]++)/([^/]++)/2f2b26(*:23143)'\n                        .'|5570/([^/]++)/([^/]++)/([^/]++)/2f5570(*:23191)'\n                    .')'\n                    .'|4(?'\n                        .'|b16f/([^/]++)/([^/]++)/([^/]++)/24b16f(*:23244)'\n                        .'|8e84/([^/]++)/([^/]++)/([^/]++)/248e84(*:23292)'\n                        .'|21fc/([^/]++)/([^/]++)/([^/]++)/2421fc(*:23340)'\n                    .')'\n                    .'|5(?'\n                        .'|b282/([^/]++)/([^/]++)/([^/]++)/25b282(*:23393)'\n                        .'|0cf8/([^/]++)/([^/]++)/([^/]++)/250cf8(*:23441)'\n                        .'|ddc0/([^/]++)/([^/]++)/([^/]++)/25ddc0(*:23489)'\n                    .')'\n                    .'|18a0a/([^/]++)/([^/]++)/([^/]++)/218a0a(*:23539)'\n                .')'\n                .'|/5(?'\n                    .'|4229a/([^/]++)/([^/]++)/([^/]++)/54229a(*:23594)'\n                    .'|f(?'\n                        .'|93f9/([^/]++)/([^/]++)/([^/]++)/5f93f9(*:23646)'\n                        .'|d0b3/([^/]++)/([^/]++)/([^/]++)/5fd0b3(*:23694)'\n                    .')'\n                    .'|ef(?'\n                        .'|0(?'\n                            .'|59/([^/]++)/([^/]++)/([^/]++)/5ef059(*:23750)'\n                            .'|b4/([^/]++)/([^/]++)/([^/]++)/5ef0b4(*:23796)'\n                        .')'\n                        .'|698/([^/]++)/([^/]++)/([^/]++)/5ef698(*:23844)'\n                    .')'\n                    .'|8(?'\n                        .'|78a7/([^/]++)/([^/]++)/([^/]++)/5878a7(*:23897)'\n                        .'|a2fc/([^/]++)/([^/]++)/([^/]++)/58a2fc(*:23945)'\n                        .'|238e/([^/]++)/([^/]++)/([^/]++)/58238e(*:23993)'\n                    .')'\n                    .'|7(?'\n                        .'|aeee/([^/]++)/([^/]++)/([^/]++)/57aeee(*:24046)'\n                        .'|7(?'\n                            .'|ef1/([^/]++)/([^/]++)/([^/]++)/577ef1(*:24097)'\n                            .'|bcc/([^/]++)/([^/]++)/([^/]++)/577bcc(*:24144)'\n                        .')'\n                        .'|37c6/([^/]++)/([^/]++)/([^/]++)/5737c6(*:24193)'\n                    .')'\n                    .'|3(?'\n                        .'|9fd5/([^/]++)/([^/]++)/([^/]++)/539fd5(*:24246)'\n                        .'|c3bc/([^/]++)/([^/]++)/([^/]++)/53c3bc(*:24294)'\n                    .')'\n                    .'|5(?'\n                        .'|5d67/([^/]++)/([^/]++)/([^/]++)/555d67(*:24347)'\n                        .'|0a14/([^/]++)/([^/]++)/([^/]++)/550a14(*:24395)'\n                        .'|9cb9/([^/]++)/([^/]++)/([^/]++)/559cb9(*:24443)'\n                        .'|a7cf/([^/]++)/([^/]++)/([^/]++)/55a7cf(*:24491)'\n                    .')'\n                    .'|02e4a/([^/]++)/([^/]++)/([^/]++)/502e4a(*:24541)'\n                    .'|b8add/([^/]++)/([^/]++)/([^/]++)/5b8add(*:24590)'\n                    .'|2720e/([^/]++)/([^/]++)/([^/]++)/52720e(*:24639)'\n                    .'|a4b25/([^/]++)/([^/]++)/([^/]++)/5a4b25(*:24688)'\n                    .'|1d92b/([^/]++)/([^/]++)/([^/]++)/51d92b(*:24737)'\n                    .'|98b3e/([^/]++)/([^/]++)/([^/]++)/598b3e(*:24786)'\n                .')'\n            .')/?$}sD',\n        24786 => '{^(?'\n                .'|/5(?'\n                    .'|b69b9/([^/]++)/([^/]++)/([^/]++)/5b69b9(*:24837)'\n                    .'|9(?'\n                        .'|b90e/([^/]++)/([^/]++)/([^/]++)/59b90e(*:24889)'\n                        .'|c330/([^/]++)/([^/]++)/([^/]++)/59c330(*:24937)'\n                    .')'\n                    .'|3(?'\n                        .'|fde9/([^/]++)/([^/]++)/([^/]++)/53fde9(*:24990)'\n                        .'|e3a7/([^/]++)/([^/]++)/([^/]++)/53e3a7(*:25038)'\n                    .')'\n                    .'|e(?'\n                        .'|a164/([^/]++)/([^/]++)/([^/]++)/5ea164(*:25091)'\n                        .'|3881/([^/]++)/([^/]++)/([^/]++)/5e3881(*:25139)'\n                        .'|9f92/([^/]++)/([^/]++)/([^/]++)/5e9f92(*:25187)'\n                        .'|c91a/([^/]++)/([^/]++)/([^/]++)/5ec91a(*:25235)'\n                    .')'\n                    .'|7(?'\n                        .'|3703/([^/]++)/([^/]++)/([^/]++)/573703(*:25288)'\n                        .'|51ec/([^/]++)/([^/]++)/([^/]++)/5751ec(*:25336)'\n                        .'|05e1/([^/]++)/([^/]++)/([^/]++)/5705e1(*:25384)'\n                    .')'\n                    .'|8(?'\n                        .'|ae74/([^/]++)/([^/]++)/([^/]++)/58ae74(*:25437)'\n                        .'|d4d1/([^/]++)/([^/]++)/([^/]++)/58d4d1(*:25485)'\n                        .'|07a6/([^/]++)/([^/]++)/([^/]++)/5807a6(*:25533)'\n                        .'|e4d4/([^/]++)/([^/]++)/([^/]++)/58e4d4(*:25581)'\n                    .')'\n                    .'|d(?'\n                        .'|44ee/([^/]++)/([^/]++)/([^/]++)/5d44ee(*:25634)'\n                        .'|d9db/([^/]++)/([^/]++)/([^/]++)/5dd9db(*:25682)'\n                    .')'\n                    .'|5(?'\n                        .'|b37c/([^/]++)/([^/]++)/([^/]++)/55b37c(*:25735)'\n                        .'|743c/([^/]++)/([^/]++)/([^/]++)/55743c(*:25783)'\n                        .'|6f39/([^/]++)/([^/]++)/([^/]++)/556f39(*:25831)'\n                    .')'\n                    .'|c(?'\n                        .'|0492/([^/]++)/([^/]++)/([^/]++)/5c0492(*:25884)'\n                        .'|572e/([^/]++)/([^/]++)/([^/]++)/5c572e(*:25932)'\n                        .'|9362/([^/]++)/([^/]++)/([^/]++)/5c9362(*:25980)'\n                    .')'\n                    .'|4(?'\n                        .'|8731/([^/]++)/([^/]++)/([^/]++)/548731(*:26033)'\n                        .'|a367/([^/]++)/([^/]++)/([^/]++)/54a367(*:26081)'\n                    .')'\n                    .'|0(?'\n                        .'|0e75/([^/]++)/([^/]++)/([^/]++)/500e75(*:26134)'\n                        .'|c3d7/([^/]++)/([^/]++)/([^/]++)/50c3d7(*:26182)'\n                    .')'\n                    .'|f(?'\n                        .'|2c22/([^/]++)/([^/]++)/([^/]++)/5f2c22(*:26235)'\n                        .'|0f5e/([^/]++)/([^/]++)/([^/]++)/5f0f5e(*:26283)'\n                    .')'\n                    .'|1ef18/([^/]++)/([^/]++)/([^/]++)/51ef18(*:26333)'\n                .')'\n                .'|/b(?'\n                    .'|5(?'\n                        .'|b41f/([^/]++)/([^/]++)/([^/]++)/b5b41f(*:26391)'\n                        .'|dc4e/([^/]++)/([^/]++)/([^/]++)/b5dc4e(*:26439)'\n                        .'|6a18/([^/]++)/([^/]++)/([^/]++)/b56a18(*:26487)'\n                        .'|5ec2/([^/]++)/([^/]++)/([^/]++)/b55ec2(*:26535)'\n                    .')'\n                    .'|337e8/([^/]++)/([^/]++)/([^/]++)/b337e8(*:26585)'\n                    .'|a(?'\n                        .'|2fd3/([^/]++)/([^/]++)/([^/]++)/ba2fd3(*:26637)'\n                        .'|3866/([^/]++)/([^/]++)/([^/]++)/ba3866(*:26685)'\n                    .')'\n                    .'|2(?'\n                        .'|eeb7/([^/]++)/([^/]++)/([^/]++)/b2eeb7(*:26738)'\n                        .'|f627/([^/]++)/([^/]++)/([^/]++)/b2f627(*:26786)'\n                    .')'\n                    .'|7(?'\n                        .'|3dfe/([^/]++)/([^/]++)/([^/]++)/b73dfe(*:26839)'\n                        .'|bb35/([^/]++)/([^/]++)/([^/]++)/b7bb35(*:26887)'\n                        .'|ee6f/([^/]++)/([^/]++)/([^/]++)/b7ee6f(*:26935)'\n                        .'|892f/([^/]++)/([^/]++)/([^/]++)/b7892f(*:26983)'\n                        .'|0683/([^/]++)/([^/]++)/([^/]++)/b70683(*:27031)'\n                    .')'\n                    .'|4(?'\n                        .'|288d/([^/]++)/([^/]++)/([^/]++)/b4288d(*:27084)'\n                        .'|a528/([^/]++)/([^/]++)/([^/]++)/b4a528(*:27132)'\n                    .')'\n                    .'|e(?'\n                        .'|3159/([^/]++)/([^/]++)/([^/]++)/be3159(*:27185)'\n                        .'|b22f/([^/]++)/([^/]++)/([^/]++)/beb22f(*:27233)'\n                        .'|a595/([^/]++)/([^/]++)/([^/]++)/bea595(*:27281)'\n                    .')'\n                    .'|1(?'\n                        .'|eec3/([^/]++)/([^/]++)/([^/]++)/b1eec3(*:27334)'\n                        .'|37fd/([^/]++)/([^/]++)/([^/]++)/b137fd(*:27382)'\n                    .')'\n                    .'|0(?'\n                        .'|56eb/([^/]++)/([^/]++)/([^/]++)/b056eb(*:27435)'\n                        .'|b183/([^/]++)/([^/]++)/([^/]++)/b0b183(*:27483)'\n                    .')'\n                    .'|f6276/([^/]++)/([^/]++)/([^/]++)/bf6276(*:27533)'\n                    .'|6(?'\n                        .'|edc1/([^/]++)/([^/]++)/([^/]++)/b6edc1(*:27585)'\n                        .'|a108/([^/]++)/([^/]++)/([^/]++)/b6a108(*:27633)'\n                    .')'\n                    .'|86e8d/([^/]++)/([^/]++)/([^/]++)/b86e8d(*:27683)'\n                .')'\n                .'|/2(?'\n                    .'|8(?'\n                        .'|5e19/([^/]++)/([^/]++)/([^/]++)/285e19(*:27741)'\n                        .'|2(?'\n                            .'|3f4/([^/]++)/([^/]++)/([^/]++)/2823f4(*:27792)'\n                            .'|67a/([^/]++)/([^/]++)/([^/]++)/28267a(*:27839)'\n                        .')'\n                        .'|8cc0/([^/]++)/([^/]++)/([^/]++)/288cc0(*:27888)'\n                        .'|7e03/([^/]++)/([^/]++)/([^/]++)/287e03(*:27936)'\n                    .')'\n                    .'|d(?'\n                        .'|6cc4/([^/]++)/([^/]++)/([^/]++)/2d6cc4(*:27989)'\n                        .'|ea61/([^/]++)/([^/]++)/([^/]++)/2dea61(*:28037)'\n                        .'|ace7/([^/]++)/([^/]++)/([^/]++)/2dace7(*:28085)'\n                    .')'\n                    .'|b(?'\n                        .'|8a61/([^/]++)/([^/]++)/([^/]++)/2b8a61(*:28138)'\n                        .'|b232/([^/]++)/([^/]++)/([^/]++)/2bb232(*:28186)'\n                        .'|a596/([^/]++)/([^/]++)/([^/]++)/2ba596(*:28234)'\n                        .'|cab9/([^/]++)/([^/]++)/([^/]++)/2bcab9(*:28282)'\n                    .')'\n                    .'|9(?'\n                        .'|8f95/([^/]++)/([^/]++)/([^/]++)/298f95(*:28335)'\n                        .'|1597/([^/]++)/([^/]++)/([^/]++)/291597(*:28383)'\n                    .')'\n                    .'|58be1/([^/]++)/([^/]++)/([^/]++)/258be1(*:28433)'\n                    .'|3(?'\n                        .'|3509/([^/]++)/([^/]++)/([^/]++)/233509(*:28485)'\n                        .'|ce18/([^/]++)/([^/]++)/([^/]++)/23ce18(*:28533)'\n                    .')'\n                    .'|6(?'\n                        .'|dd0d/([^/]++)/([^/]++)/([^/]++)/26dd0d(*:28586)'\n                        .'|408f/([^/]++)/([^/]++)/([^/]++)/26408f(*:28634)'\n                    .')'\n                    .'|f(?'\n                        .'|37d1/([^/]++)/([^/]++)/([^/]++)/2f37d1(*:28687)'\n                        .'|885d/([^/]++)/([^/]++)/([^/]++)/2f885d(*:28735)'\n                    .')'\n                    .'|2(?'\n                        .'|91d2/([^/]++)/([^/]++)/([^/]++)/2291d2(*:28788)'\n                        .'|ac3c/([^/]++)/([^/]++)/([^/]++)/22ac3c(*:28836)'\n                        .'|fb0c/([^/]++)/([^/]++)/([^/]++)/22fb0c(*:28884)'\n                    .')'\n                    .'|4(?'\n                        .'|6819/([^/]++)/([^/]++)/([^/]++)/246819(*:28937)'\n                        .'|896e/([^/]++)/([^/]++)/([^/]++)/24896e(*:28985)'\n                    .')'\n                    .'|a(?'\n                        .'|fe45/([^/]++)/([^/]++)/([^/]++)/2afe45(*:29038)'\n                        .'|084e/([^/]++)/([^/]++)/([^/]++)/2a084e(*:29086)'\n                        .'|9d12/([^/]++)/([^/]++)/([^/]++)/2a9d12(*:29134)'\n                        .'|b564/([^/]++)/([^/]++)/([^/]++)/2ab564(*:29182)'\n                    .')'\n                    .'|1(?'\n                        .'|7eed/([^/]++)/([^/]++)/([^/]++)/217eed(*:29235)'\n                        .'|0f76/([^/]++)/([^/]++)/([^/]++)/210f76(*:29283)'\n                    .')'\n                    .'|e65f2/([^/]++)/([^/]++)/([^/]++)/2e65f2(*:29333)'\n                    .'|ca65f/([^/]++)/([^/]++)/([^/]++)/2ca65f(*:29382)'\n                    .'|0aee3/([^/]++)/([^/]++)/([^/]++)/20aee3(*:29431)'\n                .')'\n                .'|/e(?'\n                    .'|8(?'\n                        .'|c065/([^/]++)/([^/]++)/([^/]++)/e8c065(*:29489)'\n                        .'|20a4/([^/]++)/([^/]++)/([^/]++)/e820a4(*:29537)'\n                    .')'\n                    .'|2(?'\n                        .'|230b/([^/]++)/([^/]++)/([^/]++)/e2230b(*:29590)'\n                        .'|a2dc/([^/]++)/([^/]++)/([^/]++)/e2a2dc(*:29638)'\n                        .'|05ee/([^/]++)/([^/]++)/([^/]++)/e205ee(*:29686)'\n                    .')'\n                    .'|b(?'\n                        .'|d962/([^/]++)/([^/]++)/([^/]++)/ebd962(*:29739)'\n                        .'|6fdc/([^/]++)/([^/]++)/([^/]++)/eb6fdc(*:29787)'\n                    .')'\n                    .'|d(?'\n                        .'|265b/([^/]++)/([^/]++)/([^/]++)/ed265b(*:29840)'\n                        .'|fbe1/([^/]++)/([^/]++)/([^/]++)/edfbe1(*:29888)'\n                        .'|e7e2/([^/]++)/([^/]++)/([^/]++)/ede7e2(*:29936)'\n                    .')'\n                    .'|6(?'\n                        .'|b4b2/([^/]++)/([^/]++)/([^/]++)/e6b4b2(*:29989)'\n                        .'|cb2a/([^/]++)/([^/]++)/([^/]++)/e6cb2a(*:30037)'\n                    .')'\n                    .'|5(?'\n                        .'|f6ad/([^/]++)/([^/]++)/([^/]++)/e5f6ad(*:30090)'\n                        .'|55eb/([^/]++)/([^/]++)/([^/]++)/e555eb(*:30138)'\n                        .'|841d/([^/]++)/([^/]++)/([^/]++)/e5841d(*:30186)'\n                        .'|7c6b/([^/]++)/([^/]++)/([^/]++)/e57c6b(*:30234)'\n                    .')'\n                    .'|aae33/([^/]++)/([^/]++)/([^/]++)/eaae33(*:30284)'\n                    .'|4(?'\n                        .'|bb4c/([^/]++)/([^/]++)/([^/]++)/e4bb4c(*:30336)'\n                        .'|9b8b/([^/]++)/([^/]++)/([^/]++)/e49b8b(*:30384)'\n                    .')'\n                    .'|7(?'\n                        .'|0611/([^/]++)/([^/]++)/([^/]++)/e70611(*:30437)'\n                        .'|f8a7/([^/]++)/([^/]++)/([^/]++)/e7f8a7(*:30485)'\n                        .'|44f9/([^/]++)/([^/]++)/([^/]++)/e744f9(*:30533)'\n                    .')'\n                    .'|9(?'\n                        .'|95f9/([^/]++)/([^/]++)/([^/]++)/e995f9(*:30586)'\n                        .'|4550/([^/]++)/([^/]++)/([^/]++)/e94550(*:30634)'\n                        .'|7ee2/([^/]++)/([^/]++)/([^/]++)/e97ee2(*:30682)'\n                    .')'\n                    .'|e(?'\n                        .'|fc9e/([^/]++)/([^/]++)/([^/]++)/eefc9e(*:30735)'\n                        .'|b69a/([^/]++)/([^/]++)/([^/]++)/eeb69a(*:30783)'\n                    .')'\n                    .'|0(?'\n                        .'|7413/([^/]++)/([^/]++)/([^/]++)/e07413(*:30836)'\n                        .'|cf1f/([^/]++)/([^/]++)/([^/]++)/e0cf1f(*:30884)'\n                        .'|ec45/([^/]++)/([^/]++)/([^/]++)/e0ec45(*:30932)'\n                    .')'\n                    .'|f4e3b/([^/]++)/([^/]++)/([^/]++)/ef4e3b(*:30982)'\n                    .'|c5aa0/([^/]++)/([^/]++)/([^/]++)/ec5aa0(*:31031)'\n                .')'\n                .'|/f(?'\n                    .'|f(?'\n                        .'|4d5f/([^/]++)/([^/]++)/([^/]++)/ff4d5f(*:31089)'\n                        .'|eabd/([^/]++)/([^/]++)/([^/]++)/ffeabd(*:31137)'\n                    .')'\n                    .'|3(?'\n                        .'|f27a/([^/]++)/([^/]++)/([^/]++)/f3f27a(*:31190)'\n                        .'|8762/([^/]++)/([^/]++)/([^/]++)/f38762(*:31238)'\n                    .')'\n                    .'|4(?'\n                        .'|be00/([^/]++)/([^/]++)/([^/]++)/f4be00(*:31291)'\n                        .'|5526/([^/]++)/([^/]++)/([^/]++)/f45526(*:31339)'\n                        .'|7d0a/([^/]++)/([^/]++)/([^/]++)/f47d0a(*:31387)'\n                    .')'\n                    .'|0(?'\n                        .'|e52b/([^/]++)/([^/]++)/([^/]++)/f0e52b(*:31440)'\n                        .'|adc8/([^/]++)/([^/]++)/([^/]++)/f0adc8(*:31488)'\n                    .')'\n                    .'|de926/([^/]++)/([^/]++)/([^/]++)/fde926(*:31538)'\n                    .'|5(?'\n                        .'|deae/([^/]++)/([^/]++)/([^/]++)/f5deae(*:31590)'\n                        .'|7a2f/([^/]++)/([^/]++)/([^/]++)/f57a2f(*:31638)'\n                    .')'\n                    .'|7(?'\n                        .'|6a89/([^/]++)/([^/]++)/([^/]++)/f76a89(*:31691)'\n                        .'|9921/([^/]++)/([^/]++)/([^/]++)/f79921(*:31739)'\n                        .'|e905/([^/]++)/([^/]++)/([^/]++)/f7e905(*:31787)'\n                    .')'\n                    .'|2(?'\n                        .'|9c21/([^/]++)/([^/]++)/([^/]++)/f29c21(*:31840)'\n                        .'|201f/([^/]++)/([^/]++)/([^/]++)/f2201f(*:31888)'\n                    .')'\n                    .'|a(?'\n                        .'|e0b2/([^/]++)/([^/]++)/([^/]++)/fae0b2(*:31941)'\n                        .'|14d4/([^/]++)/([^/]++)/([^/]++)/fa14d4(*:31989)'\n                        .'|3a3c/([^/]++)/([^/]++)/([^/]++)/fa3a3c(*:32037)'\n                        .'|83a1/([^/]++)/([^/]++)/([^/]++)/fa83a1(*:32085)'\n                    .')'\n                    .'|c(?'\n                        .'|cb3c/([^/]++)/([^/]++)/([^/]++)/fccb3c(*:32138)'\n                        .'|8001/([^/]++)/([^/]++)/([^/]++)/fc8001(*:32186)'\n                        .'|3cf4/([^/]++)/([^/]++)/([^/]++)/fc3cf4(*:32234)'\n                        .'|4930/([^/]++)/([^/]++)/([^/]++)/fc4930(*:32282)'\n                    .')'\n                    .'|64eac/([^/]++)/([^/]++)/([^/]++)/f64eac(*:32332)'\n                    .'|b8970/([^/]++)/([^/]++)/([^/]++)/fb8970(*:32381)'\n                    .'|1c159/([^/]++)/([^/]++)/([^/]++)/f1c159(*:32430)'\n                    .'|9(?'\n                        .'|028f/([^/]++)/([^/]++)/([^/]++)/f9028f(*:32482)'\n                        .'|a40a/([^/]++)/([^/]++)/([^/]++)/f9a40a(*:32530)'\n                    .')'\n                    .'|e(?'\n                        .'|8c15/([^/]++)/([^/]++)/([^/]++)/fe8c15(*:32583)'\n                        .'|c8d4/([^/]++)/([^/]++)/([^/]++)/fec8d4(*:32631)'\n                        .'|7ee8/([^/]++)/([^/]++)/([^/]++)/fe7ee8(*:32679)'\n                    .')'\n                .')'\n                .'|/3(?'\n                    .'|8(?'\n                        .'|9(?'\n                            .'|bc7/([^/]++)/([^/]++)/([^/]++)/389bc7(*:32741)'\n                            .'|13e/([^/]++)/([^/]++)/([^/]++)/38913e(*:32788)'\n                        .')'\n                        .'|71bd/([^/]++)/([^/]++)/([^/]++)/3871bd(*:32837)'\n                    .')'\n                    .'|d(?'\n                        .'|c487/([^/]++)/([^/]++)/([^/]++)/3dc487(*:32890)'\n                        .'|2d8c/([^/]++)/([^/]++)/([^/]++)/3d2d8c(*:32938)'\n                        .'|8e28/([^/]++)/([^/]++)/([^/]++)/3d8e28(*:32986)'\n                        .'|f1d4/([^/]++)/([^/]++)/([^/]++)/3df1d4(*:33034)'\n                    .')'\n                    .'|7f0e8/([^/]++)/([^/]++)/([^/]++)/37f0e8(*:33084)'\n                    .'|3(?'\n                        .'|e807/([^/]++)/([^/]++)/([^/]++)/33e807(*:33136)'\n                        .'|28bd/([^/]++)/([^/]++)/([^/]++)/3328bd(*:33184)'\n                    .')'\n                    .'|a(?'\n                        .'|0(?'\n                            .'|772/([^/]++)/([^/]++)/([^/]++)/3a0772(*:33240)'\n                            .'|66b/([^/]++)/([^/]++)/([^/]++)/3a066b(*:33287)'\n                        .')'\n                        .'|835d/([^/]++)/([^/]++)/([^/]++)/3a835d(*:33336)'\n                    .')'\n                    .'|0(?'\n                        .'|bb38/([^/]++)/([^/]++)/([^/]++)/30bb38(*:33389)'\n                        .'|3ed4/([^/]++)/([^/]++)/([^/]++)/303ed4(*:33437)'\n                        .'|ef30/([^/]++)/([^/]++)/([^/]++)/30ef30(*:33485)'\n                        .'|1ad0/([^/]++)/([^/]++)/([^/]++)/301ad0(*:33533)'\n                    .')'\n                    .'|4(?'\n                        .'|9389/([^/]++)/([^/]++)/([^/]++)/349389(*:33586)'\n                        .'|35c3/([^/]++)/([^/]++)/([^/]++)/3435c3(*:33634)'\n                    .')'\n                    .'|62(?'\n                        .'|1f1/([^/]++)/([^/]++)/([^/]++)/3621f1(*:33687)'\n                        .'|e80/([^/]++)/([^/]++)/([^/]++)/362e80(*:33734)'\n                    .')'\n                    .'|5(?'\n                        .'|cf86/([^/]++)/([^/]++)/([^/]++)/35cf86(*:33787)'\n                        .'|2407/([^/]++)/([^/]++)/([^/]++)/352407(*:33835)'\n                    .')'\n                    .'|2b30a/([^/]++)/([^/]++)/([^/]++)/32b30a(*:33885)'\n                    .'|1839b/([^/]++)/([^/]++)/([^/]++)/31839b(*:33934)'\n                    .'|b(?'\n                        .'|5dca/([^/]++)/([^/]++)/([^/]++)/3b5dca(*:33986)'\n                        .'|3dba/([^/]++)/([^/]++)/([^/]++)/3b3dba(*:34034)'\n                    .')'\n                    .'|e89eb/([^/]++)/([^/]++)/([^/]++)/3e89eb(*:34084)'\n                    .'|cef96/([^/]++)/([^/]++)/([^/]++)/3cef96(*:34133)'\n                .')'\n                .'|/0(?'\n                    .'|8(?'\n                        .'|7408/([^/]++)/([^/]++)/([^/]++)/087408(*:34191)'\n                        .'|b255/([^/]++)/([^/]++)/([^/]++)/08b255(*:34239)'\n                        .'|c543/([^/]++)/([^/]++)/([^/]++)/08c543(*:34287)'\n                        .'|d986/([^/]++)/([^/]++)/([^/]++)/08d986(*:34335)'\n                        .'|419b/([^/]++)/([^/]++)/([^/]++)/08419b(*:34383)'\n                    .')'\n                    .'|7(?'\n                        .'|563a/([^/]++)/([^/]++)/([^/]++)/07563a(*:34436)'\n                        .'|6a0c/([^/]++)/([^/]++)/([^/]++)/076a0c(*:34484)'\n                        .'|a96b/([^/]++)/([^/]++)/([^/]++)/07a96b(*:34532)'\n                        .'|c580/([^/]++)/([^/]++)/([^/]++)/07c580(*:34580)'\n                        .'|8719/([^/]++)/([^/]++)/([^/]++)/078719(*:34628)'\n                    .')'\n                    .'|f(?'\n                        .'|cbc6/([^/]++)/([^/]++)/([^/]++)/0fcbc6(*:34681)'\n                        .'|9661/([^/]++)/([^/]++)/([^/]++)/0f9661(*:34729)'\n                        .'|f(?'\n                            .'|39b/([^/]++)/([^/]++)/([^/]++)/0ff39b(*:34780)'\n                            .'|803/([^/]++)/([^/]++)/([^/]++)/0ff803(*:34827)'\n                        .')'\n                        .'|840b/([^/]++)/([^/]++)/([^/]++)/0f840b(*:34876)'\n                    .')'\n                    .'|1(?'\n                        .'|f78b/([^/]++)/([^/]++)/([^/]++)/01f78b(*:34929)'\n                        .'|3a00/([^/]++)/([^/]++)/([^/]++)/013a00(*:34977)'\n                        .'|8825/([^/]++)/([^/]++)/([^/]++)/018825(*:35025)'\n                    .')'\n                    .'|6(?'\n                        .'|9(?'\n                            .'|d3b/([^/]++)/([^/]++)/([^/]++)/069d3b(*:35081)'\n                            .'|97f/([^/]++)/([^/]++)/([^/]++)/06997f(*:35128)'\n                        .')'\n                        .'|1412/([^/]++)/([^/]++)/([^/]++)/061412(*:35177)'\n                    .')'\n                    .'|4(?'\n                        .'|ecb1/([^/]++)/([^/]++)/([^/]++)/04ecb1(*:35230)'\n                        .'|3c3d/([^/]++)/([^/]++)/([^/]++)/043c3d(*:35278)'\n                    .')'\n                    .'|0ac8e/([^/]++)/([^/]++)/([^/]++)/00ac8e(*:35328)'\n                    .'|5(?'\n                        .'|1e4e/([^/]++)/([^/]++)/([^/]++)/051e4e(*:35380)'\n                        .'|37fb/([^/]++)/([^/]++)/([^/]++)/0537fb(*:35428)'\n                    .')'\n                    .'|d(?'\n                        .'|7de1/([^/]++)/([^/]++)/([^/]++)/0d7de1(*:35481)'\n                        .'|3180/([^/]++)/([^/]++)/([^/]++)/0d3180(*:35529)'\n                        .'|0871/([^/]++)/([^/]++)/([^/]++)/0d0871(*:35577)'\n                    .')'\n                    .'|cb929/([^/]++)/([^/]++)/([^/]++)/0cb929(*:35627)'\n                    .'|2(?'\n                        .'|a32a/([^/]++)/([^/]++)/([^/]++)/02a32a(*:35679)'\n                        .'|4d7f/([^/]++)/([^/]++)/([^/]++)/024d7f(*:35727)'\n                    .')'\n                    .'|efe32/([^/]++)/([^/]++)/([^/]++)/0efe32(*:35777)'\n                    .'|a113e/([^/]++)/([^/]++)/([^/]++)/0a113e(*:35826)'\n                    .'|b8aff/([^/]++)/([^/]++)/([^/]++)/0b8aff(*:35875)'\n                .')'\n                .'|/a(?'\n                    .'|7(?'\n                        .'|6088/([^/]++)/([^/]++)/([^/]++)/a76088(*:35933)'\n                        .'|aeed/([^/]++)/([^/]++)/([^/]++)/a7aeed(*:35981)'\n                        .'|33fa/([^/]++)/([^/]++)/([^/]++)/a733fa(*:36029)'\n                    .')'\n                    .'|9a(?'\n                        .'|665/([^/]++)/([^/]++)/([^/]++)/a9a665(*:36082)'\n                        .'|1d5/([^/]++)/([^/]++)/([^/]++)/a9a1d5(*:36129)'\n                    .')'\n                    .'|8(?'\n                        .'|6c45/([^/]++)/([^/]++)/([^/]++)/a86c45(*:36182)'\n                        .'|849b/([^/]++)/([^/]++)/([^/]++)/a8849b(*:36230)'\n                        .'|e(?'\n                            .'|864/([^/]++)/([^/]++)/([^/]++)/a8e864(*:36281)'\n                            .'|cba/([^/]++)/([^/]++)/([^/]++)/a8ecba(*:36328)'\n                        .')'\n                    .')'\n                    .'|c(?'\n                        .'|c3e0/([^/]++)/([^/]++)/([^/]++)/acc3e0(*:36382)'\n                        .'|f4b8/([^/]++)/([^/]++)/([^/]++)/acf4b8(*:36430)'\n                    .')'\n                    .'|b(?'\n                        .'|d815/([^/]++)/([^/]++)/([^/]++)/abd815(*:36483)'\n                        .'|233b/([^/]++)/([^/]++)/([^/]++)/ab233b(*:36531)'\n                        .'|a3b6/([^/]++)/([^/]++)/([^/]++)/aba3b6(*:36579)'\n                        .'|88b1/([^/]++)/([^/]++)/([^/]++)/ab88b1(*:36627)'\n                    .')'\n                    .'|5(?'\n                        .'|3240/([^/]++)/([^/]++)/([^/]++)/a53240(*:36680)'\n                        .'|cdd4/([^/]++)/([^/]++)/([^/]++)/a5cdd4(*:36728)'\n                    .')'\n                    .'|f(?'\n                        .'|d(?'\n                            .'|483/([^/]++)/([^/]++)/([^/]++)/afd483(*:36784)'\n                            .'|a33/([^/]++)/([^/]++)/([^/]++)/afda33(*:36831)'\n                        .')'\n                        .'|f162/([^/]++)/([^/]++)/([^/]++)/aff162(*:36880)'\n                    .')'\n                    .'|e(?'\n                        .'|0eb3/([^/]++)/([^/]++)/([^/]++)/ae0eb3(*:36933)'\n                        .'|b313/([^/]++)/([^/]++)/([^/]++)/aeb313(*:36981)'\n                    .')'\n                    .'|1(?'\n                        .'|d33d/([^/]++)/([^/]++)/([^/]++)/a1d33d(*:37034)'\n                        .'|140a/([^/]++)/([^/]++)/([^/]++)/a1140a(*:37082)'\n                    .')'\n                    .'|ddfa9/([^/]++)/([^/]++)/([^/]++)/addfa9(*:37132)'\n                    .'|6(?'\n                        .'|7f09/([^/]++)/([^/]++)/([^/]++)/a67f09(*:37184)'\n                        .'|4c94/([^/]++)/([^/]++)/([^/]++)/a64c94(*:37232)'\n                    .')'\n                    .'|a169b/([^/]++)/([^/]++)/([^/]++)/aa169b(*:37282)'\n                    .'|4300b/([^/]++)/([^/]++)/([^/]++)/a4300b(*:37331)'\n                    .'|3d68b/([^/]++)/([^/]++)/([^/]++)/a3d68b(*:37380)'\n                .')'\n                .'|/1(?'\n                    .'|0(?'\n                        .'|a(?'\n                            .'|7cd/([^/]++)/([^/]++)/([^/]++)/10a7cd(*:37441)'\n                            .'|5ab/([^/]++)/([^/]++)/([^/]++)/10a5ab(*:37488)'\n                        .')'\n                        .'|9a0c/([^/]++)/([^/]++)/([^/]++)/109a0c(*:37537)'\n                    .')'\n                    .'|3f320/([^/]++)/([^/]++)/([^/]++)/13f320(*:37587)'\n                    .'|6(?'\n                        .'|c222/([^/]++)/([^/]++)/([^/]++)/16c222(*:37639)'\n                        .'|8908/([^/]++)/([^/]++)/([^/]++)/168908(*:37687)'\n                    .')'\n                    .'|5(?'\n                        .'|de21/([^/]++)/([^/]++)/([^/]++)/15de21(*:37740)'\n                        .'|95af/([^/]++)/([^/]++)/([^/]++)/1595af(*:37788)'\n                    .')'\n                    .'|1(?'\n                        .'|b921/([^/]++)/([^/]++)/([^/]++)/11b921(*:37841)'\n                        .'|4193/([^/]++)/([^/]++)/([^/]++)/114193(*:37889)'\n                    .')'\n                    .'|bb91f/([^/]++)/([^/]++)/([^/]++)/1bb91f(*:37939)'\n                    .'|7(?'\n                        .'|28ef/([^/]++)/([^/]++)/([^/]++)/1728ef(*:37991)'\n                        .'|c276/([^/]++)/([^/]++)/([^/]++)/17c276(*:38039)'\n                        .'|0c94/([^/]++)/([^/]++)/([^/]++)/170c94(*:38087)'\n                    .')'\n                    .'|85(?'\n                        .'|c29/([^/]++)/([^/]++)/([^/]++)/185c29(*:38140)'\n                        .'|e65/([^/]++)/([^/]++)/([^/]++)/185e65(*:38187)'\n                    .')'\n                    .'|9(?'\n                        .'|2fc0/([^/]++)/([^/]++)/([^/]++)/192fc0(*:38240)'\n                        .'|b(?'\n                            .'|c91/([^/]++)/([^/]++)/([^/]++)/19bc91(*:38291)'\n                            .'|650/([^/]++)/([^/]++)/([^/]++)/19b650(*:38338)'\n                        .')'\n                        .'|05ae/([^/]++)/([^/]++)/([^/]++)/1905ae(*:38387)'\n                    .')'\n                    .'|e(?'\n                        .'|cfb4/([^/]++)/([^/]++)/([^/]++)/1ecfb4(*:38440)'\n                        .'|fa39/([^/]++)/([^/]++)/([^/]++)/1efa39(*:38488)'\n                        .'|056d/([^/]++)/([^/]++)/([^/]++)/1e056d(*:38536)'\n                    .')'\n                    .'|aa48f/([^/]++)/([^/]++)/([^/]++)/1aa48f(*:38586)'\n                    .'|f(?'\n                        .'|c214/([^/]++)/([^/]++)/([^/]++)/1fc214(*:38638)'\n                        .'|5089/([^/]++)/([^/]++)/([^/]++)/1f5089(*:38686)'\n                        .'|4477/([^/]++)/([^/]++)/([^/]++)/1f4477(*:38734)'\n                    .')'\n                    .'|c(?'\n                        .'|c363/([^/]++)/([^/]++)/([^/]++)/1cc363(*:38787)'\n                        .'|1d4d/([^/]++)/([^/]++)/([^/]++)/1c1d4d(*:38835)'\n                        .'|e927/([^/]++)/([^/]++)/([^/]++)/1ce927(*:38883)'\n                    .')'\n                .')'\n                .'|/6(?'\n                    .'|3(?'\n                        .'|538f/([^/]++)/([^/]++)/([^/]++)/63538f(*:38942)'\n                        .'|2cee/([^/]++)/([^/]++)/([^/]++)/632cee(*:38990)'\n                        .'|95eb/([^/]++)/([^/]++)/([^/]++)/6395eb(*:39038)'\n                    .')'\n                    .'|9(?'\n                        .'|421f/([^/]++)/([^/]++)/([^/]++)/69421f(*:39091)'\n                        .'|2f93/([^/]++)/([^/]++)/([^/]++)/692f93(*:39139)'\n                    .')'\n                    .'|5658f/([^/]++)/([^/]++)/([^/]++)/65658f(*:39189)'\n                    .'|4(?'\n                        .'|7bba/([^/]++)/([^/]++)/([^/]++)/647bba(*:39241)'\n                        .'|223c/([^/]++)/([^/]++)/([^/]++)/64223c(*:39289)'\n                    .')'\n                    .'|e(?'\n                        .'|2713/([^/]++)/([^/]++)/([^/]++)/6e2713(*:39342)'\n                        .'|0721/([^/]++)/([^/]++)/([^/]++)/6e0721(*:39390)'\n                        .'|7b33/([^/]++)/([^/]++)/([^/]++)/6e7b33(*:39438)'\n                    .')'\n                    .'|0(?'\n                        .'|5ff7/([^/]++)/([^/]++)/([^/]++)/605ff7(*:39491)'\n                        .'|8159/([^/]++)/([^/]++)/([^/]++)/608159(*:39539)'\n                    .')'\n                    .'|a(?'\n                        .'|ca97/([^/]++)/([^/]++)/([^/]++)/6aca97(*:39592)'\n                        .'|10bb/([^/]++)/([^/]++)/([^/]++)/6a10bb(*:39640)'\n                        .'|ab12/([^/]++)/([^/]++)/([^/]++)/6aab12(*:39688)'\n                    .')'\n                    .'|7(?'\n                        .'|66aa/([^/]++)/([^/]++)/([^/]++)/6766aa(*:39741)'\n                        .'|e103/([^/]++)/([^/]++)/([^/]++)/67e103(*:39789)'\n                        .'|d(?'\n                            .'|96d/([^/]++)/([^/]++)/([^/]++)/67d96d(*:39840)'\n                            .'|16d/([^/]++)/([^/]++)/([^/]++)/67d16d(*:39887)'\n                        .')'\n                        .'|0e8a/([^/]++)/([^/]++)/([^/]++)/670e8a(*:39936)'\n                        .'|7e09/([^/]++)/([^/]++)/([^/]++)/677e09(*:39984)'\n                    .')'\n                    .'|8(?'\n                        .'|264b/([^/]++)/([^/]++)/([^/]++)/68264b(*:40037)'\n                        .'|053a/([^/]++)/([^/]++)/([^/]++)/68053a(*:40085)'\n                    .')'\n                    .'|c(?'\n                        .'|2979/([^/]++)/([^/]++)/([^/]++)/6c2979(*:40138)'\n                        .'|d67d/([^/]++)/([^/]++)/([^/]++)/6cd67d(*:40186)'\n                        .'|3cf7/([^/]++)/([^/]++)/([^/]++)/6c3cf7(*:40234)'\n                        .'|fe0e/([^/]++)/([^/]++)/([^/]++)/6cfe0e(*:40282)'\n                    .')'\n                    .'|bc24f/([^/]++)/([^/]++)/([^/]++)/6bc24f(*:40332)'\n                    .'|f2268/([^/]++)/([^/]++)/([^/]++)/6f2268(*:40381)'\n                    .'|1b4a6/([^/]++)/([^/]++)/([^/]++)/61b4a6(*:40430)'\n                    .'|21461/([^/]++)/([^/]++)/([^/]++)/621461(*:40479)'\n                    .'|d0f84/([^/]++)/([^/]++)/([^/]++)/6d0f84(*:40528)'\n                    .'|60229/([^/]++)/([^/]++)/([^/]++)/660229(*:40577)'\n                .')'\n                .'|/c(?'\n                    .'|f(?'\n                        .'|6735/([^/]++)/([^/]++)/([^/]++)/cf6735(*:40635)'\n                        .'|bce4/([^/]++)/([^/]++)/([^/]++)/cfbce4(*:40683)'\n                    .')'\n                    .'|3(?'\n                        .'|99(?'\n                            .'|86/([^/]++)/([^/]++)/([^/]++)/c39986(*:40739)'\n                            .'|2e/([^/]++)/([^/]++)/([^/]++)/c3992e(*:40785)'\n                        .')'\n                        .'|61bc/([^/]++)/([^/]++)/([^/]++)/c361bc(*:40834)'\n                        .'|2d9b/([^/]++)/([^/]++)/([^/]++)/c32d9b(*:40882)'\n                    .')'\n                    .'|75b6f/([^/]++)/([^/]++)/([^/]++)/c75b6f(*:40932)'\n                    .'|c(?'\n                        .'|b(?'\n                            .'|1d4/([^/]++)/([^/]++)/([^/]++)/ccb1d4(*:40987)'\n                            .'|098/([^/]++)/([^/]++)/([^/]++)/ccb098(*:41034)'\n                        .')'\n                        .'|c0aa/([^/]++)/([^/]++)/([^/]++)/ccc0aa(*:41083)'\n                        .'|1aa4/([^/]++)/([^/]++)/([^/]++)/cc1aa4(*:41131)'\n                    .')'\n                    .'|b(?'\n                        .'|cb58/([^/]++)/([^/]++)/([^/]++)/cbcb58(*:41184)'\n                        .'|b6a3/([^/]++)/([^/]++)/([^/]++)/cbb6a3(*:41232)'\n                    .')'\n                    .'|9892a/([^/]++)/([^/]++)/([^/]++)/c9892a(*:41282)'\n                    .'|6e19e/([^/]++)/([^/]++)/([^/]++)/c6e19e(*:41331)'\n                    .'|dc0d6/([^/]++)/([^/]++)/([^/]++)/cdc0d6(*:41380)'\n                    .'|5ab0b/([^/]++)/([^/]++)/([^/]++)/c5ab0b(*:41429)'\n                    .'|a(?'\n                        .'|9c26/([^/]++)/([^/]++)/([^/]++)/ca9c26(*:41481)'\n                        .'|8155/([^/]++)/([^/]++)/([^/]++)/ca8155(*:41529)'\n                        .'|7591/([^/]++)/([^/]++)/([^/]++)/ca7591(*:41577)'\n                    .')'\n                    .'|0(?'\n                        .'|6d06/([^/]++)/([^/]++)/([^/]++)/c06d06(*:41630)'\n                        .'|f168/([^/]++)/([^/]++)/([^/]++)/c0f168(*:41678)'\n                    .')'\n                    .'|8(?'\n                        .'|ed21/([^/]++)/([^/]++)/([^/]++)/c8ed21(*:41731)'\n                        .'|fbbc/([^/]++)/([^/]++)/([^/]++)/c8fbbc(*:41779)'\n                        .'|c41c/([^/]++)/([^/]++)/([^/]++)/c8c41c(*:41827)'\n                    .')'\n                    .'|15da1/([^/]++)/([^/]++)/([^/]++)/c15da1(*:41877)'\n                    .'|2(?'\n                        .'|626d/([^/]++)/([^/]++)/([^/]++)/c2626d(*:41929)'\n                        .'|aee8/([^/]++)/([^/]++)/([^/]++)/c2aee8(*:41977)'\n                        .'|2abf/([^/]++)/([^/]++)/([^/]++)/c22abf(*:42025)'\n                    .')'\n                    .'|e78d1/([^/]++)/([^/]++)/([^/]++)/ce78d1(*:42075)'\n                    .'|4(?'\n                        .'|015b/([^/]++)/([^/]++)/([^/]++)/c4015b(*:42127)'\n                        .'|b31c/([^/]++)/([^/]++)/([^/]++)/c4b31c(*:42175)'\n                    .')'\n                .')'\n                .'|/8(?'\n                    .'|5(?'\n                        .'|422a/([^/]++)/([^/]++)/([^/]++)/85422a(*:42234)'\n                        .'|1ddf/([^/]++)/([^/]++)/([^/]++)/851ddf(*:42282)'\n                        .'|fc37/([^/]++)/([^/]++)/([^/]++)/85fc37(*:42330)'\n                    .')'\n                    .'|1(?'\n                        .'|4481/([^/]++)/([^/]++)/([^/]++)/814481(*:42383)'\n                        .'|e74d/([^/]++)/([^/]++)/([^/]++)/81e74d(*:42431)'\n                    .')'\n                    .'|d(?'\n                        .'|3(?'\n                            .'|420/([^/]++)/([^/]++)/([^/]++)/8d3420(*:42487)'\n                            .'|17b/([^/]++)/([^/]++)/([^/]++)/8d317b(*:42534)'\n                        .')'\n                        .'|f707/([^/]++)/([^/]++)/([^/]++)/8df707(*:42583)'\n                        .'|6dc3/([^/]++)/([^/]++)/([^/]++)/8d6dc3(*:42631)'\n                    .')'\n                    .'|e(?'\n                        .'|efcf/([^/]++)/([^/]++)/([^/]++)/8eefcf(*:42684)'\n                        .'|bda5/([^/]++)/([^/]++)/([^/]++)/8ebda5(*:42732)'\n                        .'|82ab/([^/]++)/([^/]++)/([^/]++)/8e82ab(*:42780)'\n                    .')'\n                    .'|b(?'\n                        .'|16eb/([^/]++)/([^/]++)/([^/]++)/8b16eb(*:42833)'\n                        .'|6dd7/([^/]++)/([^/]++)/([^/]++)/8b6dd7(*:42881)'\n                        .'|5040/([^/]++)/([^/]++)/([^/]++)/8b5040(*:42929)'\n                    .')'\n                    .'|c(?'\n                        .'|7bbb/([^/]++)/([^/]++)/([^/]++)/8c7bbb(*:42982)'\n                        .'|6744/([^/]++)/([^/]++)/([^/]++)/8c6744(*:43030)'\n                        .'|235f/([^/]++)/([^/]++)/([^/]++)/8c235f(*:43078)'\n                    .')'\n                    .'|8(?'\n                        .'|4d24/([^/]++)/([^/]++)/([^/]++)/884d24(*:43131)'\n                        .'|ae63/([^/]++)/([^/]++)/([^/]++)/88ae63(*:43179)'\n                    .')'\n                    .'|7(?'\n                        .'|5715/([^/]++)/([^/]++)/([^/]++)/875715(*:43232)'\n                        .'|2488/([^/]++)/([^/]++)/([^/]++)/872488(*:43280)'\n                    .')'\n                    .'|4(?'\n                        .'|1172/([^/]++)/([^/]++)/([^/]++)/841172(*:43333)'\n                        .'|6c26/([^/]++)/([^/]++)/([^/]++)/846c26(*:43381)'\n                        .'|f7e6/([^/]++)/([^/]++)/([^/]++)/84f7e6(*:43429)'\n                        .'|7cc5/([^/]++)/([^/]++)/([^/]++)/847cc5(*:43477)'\n                    .')'\n                    .'|f(?'\n                        .'|ecb2/([^/]++)/([^/]++)/([^/]++)/8fecb2(*:43530)'\n                        .'|7d80/([^/]++)/([^/]++)/([^/]++)/8f7d80(*:43578)'\n                        .'|468c/([^/]++)/([^/]++)/([^/]++)/8f468c(*:43626)'\n                    .')'\n                    .'|a0e11/([^/]++)/([^/]++)/([^/]++)/8a0e11(*:43676)'\n                    .'|2(?'\n                        .'|f2b3/([^/]++)/([^/]++)/([^/]++)/82f2b3(*:43728)'\n                        .'|489c/([^/]++)/([^/]++)/([^/]++)/82489c(*:43776)'\n                    .')'\n                    .'|6(?'\n                        .'|b122/([^/]++)/([^/]++)/([^/]++)/86b122(*:43829)'\n                        .'|0320/([^/]++)/([^/]++)/([^/]++)/860320(*:43877)'\n                    .')'\n                    .'|9(?'\n                        .'|2c91/([^/]++)/([^/]++)/([^/]++)/892c91(*:43930)'\n                        .'|fcd0/([^/]++)/([^/]++)/([^/]++)/89fcd0(*:43978)'\n                    .')'\n                    .'|065d0/([^/]++)/([^/]++)/([^/]++)/8065d0(*:44028)'\n                .')'\n                .'|/d(?'\n                    .'|6(?'\n                        .'|4a34/([^/]++)/([^/]++)/([^/]++)/d64a34(*:44086)'\n                        .'|c651/([^/]++)/([^/]++)/([^/]++)/d6c651(*:44134)'\n                    .')'\n                    .'|f(?'\n                        .'|877f/([^/]++)/([^/]++)/([^/]++)/df877f(*:44187)'\n                        .'|263d/([^/]++)/([^/]++)/([^/]++)/df263d(*:44235)'\n                        .'|7f28/([^/]++)/([^/]++)/([^/]++)/df7f28(*:44283)'\n                        .'|6d23/([^/]++)/([^/]++)/([^/]++)/df6d23(*:44331)'\n                    .')'\n                    .'|b(?'\n                        .'|85e2/([^/]++)/([^/]++)/([^/]++)/db85e2(*:44384)'\n                        .'|e272/([^/]++)/([^/]++)/([^/]++)/dbe272(*:44432)'\n                    .')'\n                    .'|d(?'\n                        .'|45(?'\n                            .'|85/([^/]++)/([^/]++)/([^/]++)/dd4585(*:44488)'\n                            .'|04/([^/]++)/([^/]++)/([^/]++)/dd4504(*:44534)'\n                        .')'\n                        .'|8eb9/([^/]++)/([^/]++)/([^/]++)/dd8eb9(*:44583)'\n                    .')'\n                    .'|a(?'\n                        .'|ca41/([^/]++)/([^/]++)/([^/]++)/daca41(*:44636)'\n                        .'|8ce5/([^/]++)/([^/]++)/([^/]++)/da8ce5(*:44684)'\n                        .'|0d11/([^/]++)/([^/]++)/([^/]++)/da0d11(*:44732)'\n                    .')'\n                    .'|4(?'\n                        .'|90d7/([^/]++)/([^/]++)/([^/]++)/d490d7(*:44785)'\n                        .'|c2e4/([^/]++)/([^/]++)/([^/]++)/d4c2e4(*:44833)'\n                    .')'\n                    .'|8(?'\n                        .'|6ea6/([^/]++)/([^/]++)/([^/]++)/d86ea6(*:44886)'\n                        .'|40cc/([^/]++)/([^/]++)/([^/]++)/d840cc(*:44934)'\n                    .')'\n                    .'|c(?'\n                        .'|82d6/([^/]++)/([^/]++)/([^/]++)/dc82d6(*:44987)'\n                        .'|6a70/([^/]++)/([^/]++)/([^/]++)/dc6a70(*:45035)'\n                        .'|5689/([^/]++)/([^/]++)/([^/]++)/dc5689(*:45083)'\n                    .')'\n                    .'|7(?'\n                        .'|a728/([^/]++)/([^/]++)/([^/]++)/d7a728(*:45136)'\n                        .'|0732/([^/]++)/([^/]++)/([^/]++)/d70732(*:45184)'\n                        .'|9aac/([^/]++)/([^/]++)/([^/]++)/d79aac(*:45232)'\n                    .')'\n                    .'|14220/([^/]++)/([^/]++)/([^/]++)/d14220(*:45282)'\n                    .'|5(?'\n                        .'|cfea/([^/]++)/([^/]++)/([^/]++)/d5cfea(*:45334)'\n                        .'|8072/([^/]++)/([^/]++)/([^/]++)/d58072(*:45382)'\n                        .'|54f7/([^/]++)/([^/]++)/([^/]++)/d554f7(*:45430)'\n                        .'|16b1/([^/]++)/([^/]++)/([^/]++)/d516b1(*:45478)'\n                        .'|6b9f/([^/]++)/([^/]++)/([^/]++)/d56b9f(*:45526)'\n                    .')'\n                    .'|045c5/([^/]++)/([^/]++)/([^/]++)/d045c5(*:45576)'\n                    .'|2(?'\n                        .'|ed45/([^/]++)/([^/]++)/([^/]++)/d2ed45(*:45628)'\n                        .'|40e3/([^/]++)/([^/]++)/([^/]++)/d240e3(*:45676)'\n                    .')'\n                    .'|93ed5/([^/]++)/([^/]++)/([^/]++)/d93ed5(*:45726)'\n                .')'\n                .'|/7(?'\n                    .'|b(?'\n                        .'|cdf7/([^/]++)/([^/]++)/([^/]++)/7bcdf7(*:45784)'\n                        .'|13b2/([^/]++)/([^/]++)/([^/]++)/7b13b2(*:45832)'\n                    .')'\n                    .'|dcd34/([^/]++)/([^/]++)/([^/]++)/7dcd34(*:45882)'\n                    .'|f(?'\n                        .'|24d2/([^/]++)/([^/]++)/([^/]++)/7f24d2(*:45934)'\n                        .'|5d04/([^/]++)/([^/]++)/([^/]++)/7f5d04(*:45982)'\n                        .'|1171/([^/]++)/([^/]++)/([^/]++)/7f1171(*:46030)'\n                        .'|a732/([^/]++)/([^/]++)/([^/]++)/7fa732(*:46078)'\n                    .')'\n                    .'|6(?'\n                        .'|6ebc/([^/]++)/([^/]++)/([^/]++)/766ebc(*:46131)'\n                        .'|34ea/([^/]++)/([^/]++)/([^/]++)/7634ea(*:46179)'\n                    .')'\n                    .'|750ca/([^/]++)/([^/]++)/([^/]++)/7750ca(*:46229)'\n                    .'|1(?'\n                        .'|a(?'\n                            .'|3cb/([^/]++)/([^/]++)/([^/]++)/71a3cb(*:46284)'\n                            .'|d16/([^/]++)/([^/]++)/([^/]++)/71ad16(*:46331)'\n                        .')'\n                        .'|43d7/([^/]++)/([^/]++)/([^/]++)/7143d7(*:46380)'\n                    .')'\n                    .'|88d98/([^/]++)/([^/]++)/([^/]++)/788d98(*:46430)'\n                    .'|2(?'\n                        .'|da7f/([^/]++)/([^/]++)/([^/]++)/72da7f(*:46482)'\n                        .'|50eb/([^/]++)/([^/]++)/([^/]++)/7250eb(*:46530)'\n                    .')'\n                    .'|c(?'\n                        .'|590f/([^/]++)/([^/]++)/([^/]++)/7c590f(*:46583)'\n                        .'|e328/([^/]++)/([^/]++)/([^/]++)/7ce328(*:46631)'\n                    .')'\n                    .'|a5392/([^/]++)/([^/]++)/([^/]++)/7a5392(*:46681)'\n                    .'|95c7a/([^/]++)/([^/]++)/([^/]++)/795c7a(*:46730)'\n                    .'|504ad/([^/]++)/([^/]++)/([^/]++)/7504ad(*:46779)'\n                    .'|04afe/([^/]++)/([^/]++)/([^/]++)/704afe(*:46828)'\n                    .'|4bba2/([^/]++)/([^/]++)/([^/]++)/74bba2(*:46877)'\n                .')'\n                .'|/9(?'\n                    .'|b(?'\n                        .'|72e3/([^/]++)/([^/]++)/([^/]++)/9b72e3(*:46935)'\n                        .'|698e/([^/]++)/([^/]++)/([^/]++)/9b698e(*:46983)'\n                    .')'\n                    .'|7e852/([^/]++)/([^/]++)/([^/]++)/97e852(*:47033)'\n                    .'|4c7bb/([^/]++)/([^/]++)/([^/]++)/94c7bb(*:47082)'\n                    .'|9(?'\n                        .'|c5e0/([^/]++)/([^/]++)/([^/]++)/99c5e0(*:47134)'\n                        .'|6a7f/([^/]++)/([^/]++)/([^/]++)/996a7f(*:47182)'\n                        .'|bcfc/([^/]++)/([^/]++)/([^/]++)/99bcfc(*:47230)'\n                        .'|0827/([^/]++)/([^/]++)/([^/]++)/990827(*:47278)'\n                    .')'\n                    .'|a(?'\n                        .'|d6aa/([^/]++)/([^/]++)/([^/]++)/9ad6aa(*:47331)'\n                        .'|b0d8/([^/]++)/([^/]++)/([^/]++)/9ab0d8(*:47379)'\n                    .')'\n                    .'|c(?'\n                        .'|f81d/([^/]++)/([^/]++)/([^/]++)/9cf81d(*:47432)'\n                        .'|c138/([^/]++)/([^/]++)/([^/]++)/9cc138(*:47480)'\n                        .'|82c7/([^/]++)/([^/]++)/([^/]++)/9c82c7(*:47528)'\n                        .'|0180/([^/]++)/([^/]++)/([^/]++)/9c0180(*:47576)'\n                    .')'\n                    .'|f(?'\n                        .'|396f/([^/]++)/([^/]++)/([^/]++)/9f396f(*:47629)'\n                        .'|e859/([^/]++)/([^/]++)/([^/]++)/9fe859(*:47677)'\n                        .'|53d8/([^/]++)/([^/]++)/([^/]++)/9f53d8(*:47725)'\n                    .')'\n                    .'|12d2b/([^/]++)/([^/]++)/([^/]++)/912d2b(*:47775)'\n                    .'|59a55/([^/]++)/([^/]++)/([^/]++)/959a55(*:47824)'\n                    .'|6(?'\n                        .'|ea64/([^/]++)/([^/]++)/([^/]++)/96ea64(*:47876)'\n                        .'|b9bf/([^/]++)/([^/]++)/([^/]++)/96b9bf(*:47924)'\n                    .')'\n                    .'|e3cfc/([^/]++)/([^/]++)/([^/]++)/9e3cfc(*:47974)'\n                    .'|2(?'\n                        .'|fb0c/([^/]++)/([^/]++)/([^/]++)/92fb0c(*:48026)'\n                        .'|262b/([^/]++)/([^/]++)/([^/]++)/92262b(*:48074)'\n                        .'|32fe/([^/]++)/([^/]++)/([^/]++)/9232fe(*:48122)'\n                        .'|977a/([^/]++)/([^/]++)/([^/]++)/92977a(*:48170)'\n                    .')'\n                    .'|8d6f5/([^/]++)/([^/]++)/([^/]++)/98d6f5(*:48220)'\n                    .'|0794e/([^/]++)/([^/]++)/([^/]++)/90794e(*:48269)'\n                    .'|34815/([^/]++)/([^/]++)/([^/]++)/934815(*:48318)'\n                .')'\n                .'|/4(?'\n                    .'|e(?'\n                        .'|4b5f/([^/]++)/([^/]++)/([^/]++)/4e4b5f(*:48376)'\n                        .'|a06f/([^/]++)/([^/]++)/([^/]++)/4ea06f(*:48424)'\n                        .'|0(?'\n                            .'|928/([^/]++)/([^/]++)/([^/]++)/4e0928(*:48475)'\n                            .'|cb6/([^/]++)/([^/]++)/([^/]++)/4e0cb6(*:48522)'\n                        .')'\n                    .')'\n                    .'|6922a/([^/]++)/([^/]++)/([^/]++)/46922a(*:48573)'\n                    .'|4(?'\n                        .'|c4c1/([^/]++)/([^/]++)/([^/]++)/44c4c1(*:48625)'\n                        .'|3cb0/([^/]++)/([^/]++)/([^/]++)/443cb0(*:48673)'\n                    .')'\n                    .'|8ab2f/([^/]++)/([^/]++)/([^/]++)/48ab2f(*:48723)'\n                    .'|5(?'\n                        .'|645a/([^/]++)/([^/]++)/([^/]++)/45645a(*:48775)'\n                        .'|58db/([^/]++)/([^/]++)/([^/]++)/4558db(*:48823)'\n                    .')'\n                    .'|2e77b/([^/]++)/([^/]++)/([^/]++)/42e77b(*:48873)'\n                    .'|c27ce/([^/]++)/([^/]++)/([^/]++)/4c27ce(*:48922)'\n                    .'|f(?'\n                        .'|fce0/([^/]++)/([^/]++)/([^/]++)/4ffce0(*:48974)'\n                        .'|ac9b/([^/]++)/([^/]++)/([^/]++)/4fac9b(*:49022)'\n                    .')'\n                    .'|a47d2/([^/]++)/([^/]++)/([^/]++)/4a47d2(*:49072)'\n                    .'|70e7a/([^/]++)/([^/]++)/([^/]++)/470e7a(*:49121)'\n                    .'|b(?'\n                        .'|0(?'\n                            .'|4a6/([^/]++)/([^/]++)/([^/]++)/4b04a6(*:49176)'\n                            .'|a59/([^/]++)/([^/]++)/([^/]++)/4b0a59(*:49223)'\n                            .'|250/([^/]++)/([^/]++)/([^/]++)/4b0250(*:49270)'\n                        .')'\n                        .'|6538/([^/]++)/([^/]++)/([^/]++)/4b6538(*:49319)'\n                    .')'\n                    .'|3(?'\n                        .'|f(?'\n                            .'|a7f/([^/]++)/([^/]++)/([^/]++)/43fa7f(*:49375)'\n                            .'|eae/([^/]++)/([^/]++)/([^/]++)/43feae(*:49422)'\n                        .')'\n                        .'|0c36/([^/]++)/([^/]++)/([^/]++)/430c36(*:49471)'\n                        .'|7d7d/([^/]++)/([^/]++)/([^/]++)/437d7d(*:49519)'\n                        .'|1135/([^/]++)/([^/]++)/([^/]++)/431135(*:49567)'\n                    .')'\n                    .'|d(?'\n                        .'|5b99/([^/]++)/([^/]++)/([^/]++)/4d5b99(*:49620)'\n                        .'|aa3d/([^/]++)/([^/]++)/([^/]++)/4daa3d(*:49668)'\n                    .')'\n                    .'|9c9ad/([^/]++)/([^/]++)/([^/]++)/49c9ad(*:49718)'\n                .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        54 => [[['_route' => '_0'], ['a', 'b', 'c'], null, null, false, false, null]],\n        102 => [[['_route' => '_190'], ['a', 'b', 'c'], null, null, false, false, null]],\n        147 => [[['_route' => '_478'], ['a', 'b', 'c'], null, null, false, false, null]],\n        194 => [[['_route' => '_259'], ['a', 'b', 'c'], null, null, false, false, null]],\n        240 => [[['_route' => '_368'], ['a', 'b', 'c'], null, null, false, false, null]],\n        291 => [[['_route' => '_1'], ['a', 'b', 'c'], null, null, false, false, null]],\n        337 => [[['_route' => '_116'], ['a', 'b', 'c'], null, null, false, false, null]],\n        383 => [[['_route' => '_490'], ['a', 'b', 'c'], null, null, false, false, null]],\n        434 => [[['_route' => '_2'], ['a', 'b', 'c'], null, null, false, false, null]],\n        480 => [[['_route' => '_124'], ['a', 'b', 'c'], null, null, false, false, null]],\n        526 => [[['_route' => '_389'], ['a', 'b', 'c'], null, null, false, false, null]],\n        577 => [[['_route' => '_8'], ['a', 'b', 'c'], null, null, false, false, null]],\n        623 => [[['_route' => '_104'], ['a', 'b', 'c'], null, null, false, false, null]],\n        677 => [[['_route' => '_12'], ['a', 'b', 'c'], null, null, false, false, null]],\n        722 => [[['_route' => '_442'], ['a', 'b', 'c'], null, null, false, false, null]],\n        769 => [[['_route' => '_253'], ['a', 'b', 'c'], null, null, false, false, null]],\n        820 => [[['_route' => '_13'], ['a', 'b', 'c'], null, null, false, false, null]],\n        866 => [[['_route' => '_254'], ['a', 'b', 'c'], null, null, false, false, null]],\n        912 => [[['_route' => '_347'], ['a', 'b', 'c'], null, null, false, false, null]],\n        963 => [[['_route' => '_16'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1009 => [[['_route' => '_87'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1058 => [[['_route' => '_31'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1109 => [[['_route' => '_50'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1156 => [[['_route' => '_219'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1203 => [[['_route' => '_332'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1250 => [[['_route' => '_359'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1302 => [[['_route' => '_183'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1349 => [[['_route' => '_500'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1401 => [[['_route' => '_214'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1448 => [[['_route' => '_321'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1497 => [[['_route' => '_243'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1545 => [[['_route' => '_328'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1596 => [[['_route' => '_362'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1643 => [[['_route' => '_488'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1701 => [[['_route' => '_3'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1751 => [[['_route' => '_102'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1797 => [[['_route' => '_220'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1845 => [[['_route' => '_127'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1897 => [[['_route' => '_5'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1944 => [[['_route' => '_242'], ['a', 'b', 'c'], null, null, false, false, null]],\n        1991 => [[['_route' => '_397'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2038 => [[['_route' => '_454'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2090 => [[['_route' => '_34'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2137 => [[['_route' => '_281'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2189 => [[['_route' => '_64'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2236 => [[['_route' => '_205'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2291 => [[['_route' => '_71'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2337 => [[['_route' => '_203'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2385 => [[['_route' => '_97'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2437 => [[['_route' => '_98'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2484 => [[['_route' => '_267'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2531 => [[['_route' => '_309'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2586 => [[['_route' => '_117'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2631 => [[['_route' => '_211'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2679 => [[['_route' => '_484'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2731 => [[['_route' => '_139'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2778 => [[['_route' => '_421'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2830 => [[['_route' => '_185'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2877 => [[['_route' => '_439'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2926 => [[['_route' => '_218'], ['a', 'b', 'c'], null, null, false, false, null]],\n        2977 => [[['_route' => '_233'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3024 => [[['_route' => '_483'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3073 => [[['_route' => '_265'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3124 => [[['_route' => '_299'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3171 => [[['_route' => '_351'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3218 => [[['_route' => '_472'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3267 => [[['_route' => '_360'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3315 => [[['_route' => '_466'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3372 => [[['_route' => '_4'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3419 => [[['_route' => '_142'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3466 => [[['_route' => '_151'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3513 => [[['_route' => '_308'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3560 => [[['_route' => '_440'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3612 => [[['_route' => '_14'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3659 => [[['_route' => '_358'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3711 => [[['_route' => '_37'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3758 => [[['_route' => '_38'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3805 => [[['_route' => '_146'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3852 => [[['_route' => '_194'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3899 => [[['_route' => '_487'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3948 => [[['_route' => '_42'], ['a', 'b', 'c'], null, null, false, false, null]],\n        3999 => [[['_route' => '_54'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4046 => [[['_route' => '_326'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4098 => [[['_route' => '_68'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4145 => [[['_route' => '_108'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4197 => [[['_route' => '_74'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4244 => [[['_route' => '_315'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4291 => [[['_route' => '_374'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4343 => [[['_route' => '_99'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4390 => [[['_route' => '_238'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4442 => [[['_route' => '_107'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4489 => [[['_route' => '_409'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4541 => [[['_route' => '_122'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4588 => [[['_route' => '_379'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4635 => [[['_route' => '_390'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4687 => [[['_route' => '_171'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4734 => [[['_route' => '_260'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4781 => [[['_route' => '_434'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4830 => [[['_route' => '_189'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4878 => [[['_route' => '_467'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4935 => [[['_route' => '_6'], ['a', 'b', 'c'], null, null, false, false, null]],\n        4982 => [[['_route' => '_286'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5029 => [[['_route' => '_438'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5081 => [[['_route' => '_19'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5131 => [[['_route' => '_24'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5177 => [[['_route' => '_172'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5230 => [[['_route' => '_33'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5277 => [[['_route' => '_400'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5324 => [[['_route' => '_427'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5376 => [[['_route' => '_35'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5423 => [[['_route' => '_156'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5475 => [[['_route' => '_36'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5522 => [[['_route' => '_251'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5574 => [[['_route' => '_43'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5621 => [[['_route' => '_292'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5668 => [[['_route' => '_411'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5720 => [[['_route' => '_69'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5767 => [[['_route' => '_159'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5814 => [[['_route' => '_170'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5861 => [[['_route' => '_376'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5913 => [[['_route' => '_131'], ['a', 'b', 'c'], null, null, false, false, null]],\n        5960 => [[['_route' => '_446'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6015 => [[['_route' => '_140'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6061 => [[['_route' => '_353'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6112 => [[['_route' => '_224'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6158 => [[['_route' => '_346'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6204 => [[['_route' => '_443'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6254 => [[['_route' => '_154'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6305 => [[['_route' => '_212'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6352 => [[['_route' => '_313'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6399 => [[['_route' => '_395'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6446 => [[['_route' => '_441'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6498 => [[['_route' => '_223'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6545 => [[['_route' => '_303'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6594 => [[['_route' => '_410'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6642 => [[['_route' => '_494'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6702 => [[['_route' => '_7'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6748 => [[['_route' => '_268'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6796 => [[['_route' => '_178'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6843 => [[['_route' => '_179'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6890 => [[['_route' => '_416'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6942 => [[['_route' => '_25'], ['a', 'b', 'c'], null, null, false, false, null]],\n        6989 => [[['_route' => '_307'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7036 => [[['_route' => '_387'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7083 => [[['_route' => '_471'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7132 => [[['_route' => '_90'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7183 => [[['_route' => '_95'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7230 => [[['_route' => '_338'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7277 => [[['_route' => '_401'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7329 => [[['_route' => '_147'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7376 => [[['_route' => '_319'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7423 => [[['_route' => '_354'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7470 => [[['_route' => '_428'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7522 => [[['_route' => '_162'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7572 => [[['_route' => '_175'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7618 => [[['_route' => '_455'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7666 => [[['_route' => '_355'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7718 => [[['_route' => '_197'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7768 => [[['_route' => '_202'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7813 => [[['_route' => '_489'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7863 => [[['_route' => '_199'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7914 => [[['_route' => '_263'], ['a', 'b', 'c'], null, null, false, false, null]],\n        7961 => [[['_route' => '_406'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8010 => [[['_route' => '_289'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8058 => [[['_route' => '_325'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8106 => [[['_route' => '_378'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8154 => [[['_route' => '_468'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8211 => [[['_route' => '_9'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8258 => [[['_route' => '_216'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8307 => [[['_route' => '_26'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8355 => [[['_route' => '_62'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8406 => [[['_route' => '_81'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8453 => [[['_route' => '_318'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8505 => [[['_route' => '_121'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8551 => [[['_route' => '_182'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8603 => [[['_route' => '_136'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8650 => [[['_route' => '_415'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8697 => [[['_route' => '_457'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8744 => [[['_route' => '_463'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8796 => [[['_route' => '_148'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8843 => [[['_route' => '_273'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8892 => [[['_route' => '_284'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8940 => [[['_route' => '_288'], ['a', 'b', 'c'], null, null, false, false, null]],\n        8991 => [[['_route' => '_295'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9038 => [[['_route' => '_305'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9085 => [[['_route' => '_453'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9134 => [[['_route' => '_340'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9185 => [[['_route' => '_371'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9232 => [[['_route' => '_417'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9284 => [[['_route' => '_382'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9331 => [[['_route' => '_404'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9389 => [[['_route' => '_10'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9436 => [[['_route' => '_279'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9483 => [[['_route' => '_377'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9535 => [[['_route' => '_39'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9582 => [[['_route' => '_40'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9629 => [[['_route' => '_264'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9676 => [[['_route' => '_449'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9728 => [[['_route' => '_46'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9775 => [[['_route' => '_257'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9822 => [[['_route' => '_274'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9869 => [[['_route' => '_388'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9921 => [[['_route' => '_53'], ['a', 'b', 'c'], null, null, false, false, null]],\n        9968 => [[['_route' => '_345'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10020 => [[['_route' => '_73'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10068 => [[['_route' => '_296'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10121 => [[['_route' => '_75'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10169 => [[['_route' => '_458'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10225 => [[['_route' => '_79'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10272 => [[['_route' => '_129'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10319 => [[['_route' => '_418'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10368 => [[['_route' => '_225'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10416 => [[['_route' => '_479'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10466 => [[['_route' => '_120'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10515 => [[['_route' => '_276'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10564 => [[['_route' => '_370'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10616 => [[['_route' => '_385'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10664 => [[['_route' => '_469'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10714 => [[['_route' => '_435'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10772 => [[['_route' => '_11'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10820 => [[['_route' => '_105'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10868 => [[['_route' => '_132'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10921 => [[['_route' => '_18'], ['a', 'b', 'c'], null, null, false, false, null]],\n        10969 => [[['_route' => '_210'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11017 => [[['_route' => '_329'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11073 => [[['_route' => '_29'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11120 => [[['_route' => '_480'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11169 => [[['_route' => '_426'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11222 => [[['_route' => '_32'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11270 => [[['_route' => '_217'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11318 => [[['_route' => '_275'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11371 => [[['_route' => '_45'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11419 => [[['_route' => '_157'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11467 => [[['_route' => '_184'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11515 => [[['_route' => '_250'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11563 => [[['_route' => '_356'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11616 => [[['_route' => '_47'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11664 => [[['_route' => '_445'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11714 => [[['_route' => '_48'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11766 => [[['_route' => '_58'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11814 => [[['_route' => '_414'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11862 => [[['_route' => '_431'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11915 => [[['_route' => '_84'], ['a', 'b', 'c'], null, null, false, false, null]],\n        11963 => [[['_route' => '_294'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12011 => [[['_route' => '_336'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12059 => [[['_route' => '_465'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12112 => [[['_route' => '_103'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12160 => [[['_route' => '_111'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12208 => [[['_route' => '_207'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12256 => [[['_route' => '_402'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12309 => [[['_route' => '_230'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12356 => [[['_route' => '_331'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12406 => [[['_route' => '_248'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12455 => [[['_route' => '_282'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12513 => [[['_route' => '_15'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12561 => [[['_route' => '_130'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12609 => [[['_route' => '_231'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12657 => [[['_route' => '_365'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12705 => [[['_route' => '_448'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12758 => [[['_route' => '_20'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12806 => [[['_route' => '_93'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12854 => [[['_route' => '_186'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12902 => [[['_route' => '_460'], ['a', 'b', 'c'], null, null, false, false, null]],\n        12955 => [[['_route' => '_52'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13003 => [[['_route' => '_447'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13056 => [[['_route' => '_56'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13104 => [[['_route' => '_133'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13152 => [[['_route' => '_297'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13205 => [[['_route' => '_82'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13253 => [[['_route' => '_165'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13301 => [[['_route' => '_213'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13351 => [[['_route' => '_86'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13403 => [[['_route' => '_92'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13450 => [[['_route' => '_280'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13500 => [[['_route' => '_143'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13549 => [[['_route' => '_177'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13601 => [[['_route' => '_188'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13649 => [[['_route' => '_311'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13697 => [[['_route' => '_350'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13750 => [[['_route' => '_226'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13798 => [[['_route' => '_291'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13851 => [[['_route' => '_244'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13898 => [[['_route' => '_287'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13951 => [[['_route' => '_300'], ['a', 'b', 'c'], null, null, false, false, null]],\n        13999 => [[['_route' => '_451'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14047 => [[['_route' => '_452'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14095 => [[['_route' => '_481'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14145 => [[['_route' => '_312'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14203 => [[['_route' => '_17'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14251 => [[['_route' => '_227'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14299 => [[['_route' => '_393'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14349 => [[['_route' => '_57'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14401 => [[['_route' => '_61'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14449 => [[['_route' => '_112'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14500 => [[['_route' => '_135'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14547 => [[['_route' => '_271'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14596 => [[['_route' => '_459'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14649 => [[['_route' => '_67'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14697 => [[['_route' => '_113'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14745 => [[['_route' => '_497'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14795 => [[['_route' => '_70'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14847 => [[['_route' => '_89'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14895 => [[['_route' => '_128'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14948 => [[['_route' => '_150'], ['a', 'b', 'c'], null, null, false, false, null]],\n        14996 => [[['_route' => '_166'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15047 => [[['_route' => '_206'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15094 => [[['_route' => '_419'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15148 => [[['_route' => '_201'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15196 => [[['_route' => '_314'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15244 => [[['_route' => '_429'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15297 => [[['_route' => '_228'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15345 => [[['_route' => '_477'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15395 => [[['_route' => '_272'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15444 => [[['_route' => '_486'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15502 => [[['_route' => '_21'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15550 => [[['_route' => '_247'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15598 => [[['_route' => '_424'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15646 => [[['_route' => '_499'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15699 => [[['_route' => '_23'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15747 => [[['_route' => '_152'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15795 => [[['_route' => '_304'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15843 => [[['_route' => '_352'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15896 => [[['_route' => '_28'], ['a', 'b', 'c'], null, null, false, false, null]],\n        15944 => [[['_route' => '_240'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16000 => [[['_route' => '_30'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16047 => [[['_route' => '_41'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16096 => [[['_route' => '_301'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16149 => [[['_route' => '_66'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16197 => [[['_route' => '_72'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16245 => [[['_route' => '_320'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16298 => [[['_route' => '_78'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16346 => [[['_route' => '_337'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16394 => [[['_route' => '_399'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16442 => [[['_route' => '_495'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16492 => [[['_route' => '_85'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16544 => [[['_route' => '_101'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16592 => [[['_route' => '_176'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16640 => [[['_route' => '_246'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16693 => [[['_route' => '_125'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16741 => [[['_route' => '_341'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16794 => [[['_route' => '_137'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16842 => [[['_route' => '_270'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16890 => [[['_route' => '_386'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16943 => [[['_route' => '_169'], ['a', 'b', 'c'], null, null, false, false, null]],\n        16991 => [[['_route' => '_200'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17039 => [[['_route' => '_262'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17092 => [[['_route' => '_187'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17140 => [[['_route' => '_333'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17190 => [[['_route' => '_215'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17239 => [[['_route' => '_316'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17288 => [[['_route' => '_343'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17346 => [[['_route' => '_22'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17394 => [[['_route' => '_420'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17447 => [[['_route' => '_55'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17494 => [[['_route' => '_496'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17547 => [[['_route' => '_153'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17595 => [[['_route' => '_344'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17648 => [[['_route' => '_160'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17696 => [[['_route' => '_398'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17749 => [[['_route' => '_161'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17797 => [[['_route' => '_193'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17847 => [[['_route' => '_174'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17899 => [[['_route' => '_209'], ['a', 'b', 'c'], null, null, false, false, null]],\n        17947 => [[['_route' => '_261'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18000 => [[['_route' => '_222'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18048 => [[['_route' => '_323'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18096 => [[['_route' => '_380'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18149 => [[['_route' => '_232'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18197 => [[['_route' => '_383'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18247 => [[['_route' => '_306'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18296 => [[['_route' => '_327'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18345 => [[['_route' => '_364'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18397 => [[['_route' => '_403'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18445 => [[['_route' => '_405'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18495 => [[['_route' => '_412'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18553 => [[['_route' => '_27'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18601 => [[['_route' => '_134'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18649 => [[['_route' => '_245'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18702 => [[['_route' => '_59'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18750 => [[['_route' => '_208'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18803 => [[['_route' => '_60'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18851 => [[['_route' => '_119'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18902 => [[['_route' => '_163'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18949 => [[['_route' => '_249'], ['a', 'b', 'c'], null, null, false, false, null]],\n        18998 => [[['_route' => '_278'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19051 => [[['_route' => '_63'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19099 => [[['_route' => '_195'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19147 => [[['_route' => '_252'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19195 => [[['_route' => '_461'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19248 => [[['_route' => '_126'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19296 => [[['_route' => '_158'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19344 => [[['_route' => '_221'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19392 => [[['_route' => '_269'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19440 => [[['_route' => '_310'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19496 => [[['_route' => '_138'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19543 => [[['_route' => '_348'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19592 => [[['_route' => '_236'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19640 => [[['_route' => '_433'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19693 => [[['_route' => '_141'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19741 => [[['_route' => '_283'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19794 => [[['_route' => '_144'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19842 => [[['_route' => '_191'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19895 => [[['_route' => '_168'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19943 => [[['_route' => '_363'], ['a', 'b', 'c'], null, null, false, false, null]],\n        19991 => [[['_route' => '_381'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20044 => [[['_route' => '_180'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20092 => [[['_route' => '_339'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20142 => [[['_route' => '_196'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20194 => [[['_route' => '_198'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20242 => [[['_route' => '_285'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20292 => [[['_route' => '_349'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20344 => [[['_route' => '_367'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20392 => [[['_route' => '_384'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20440 => [[['_route' => '_498'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20490 => [[['_route' => '_369'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20542 => [[['_route' => '_408'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20590 => [[['_route' => '_413'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20652 => [[['_route' => '_44'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20699 => [[['_route' => '_256'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20748 => [[['_route' => '_173'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20796 => [[['_route' => '_266'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20844 => [[['_route' => '_392'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20892 => [[['_route' => '_430'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20940 => [[['_route' => '_482'], ['a', 'b', 'c'], null, null, false, false, null]],\n        20993 => [[['_route' => '_49'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21041 => [[['_route' => '_94'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21089 => [[['_route' => '_407'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21142 => [[['_route' => '_65'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21190 => [[['_route' => '_181'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21238 => [[['_route' => '_437'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21291 => [[['_route' => '_76'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21339 => [[['_route' => '_357'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21392 => [[['_route' => '_80'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21440 => [[['_route' => '_106'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21493 => [[['_route' => '_83'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21541 => [[['_route' => '_255'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21589 => [[['_route' => '_330'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21642 => [[['_route' => '_100'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21690 => [[['_route' => '_396'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21738 => [[['_route' => '_422'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21791 => [[['_route' => '_149'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21839 => [[['_route' => '_324'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21892 => [[['_route' => '_164'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21940 => [[['_route' => '_423'], ['a', 'b', 'c'], null, null, false, false, null]],\n        21990 => [[['_route' => '_241'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22042 => [[['_route' => '_290'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22090 => [[['_route' => '_335'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22140 => [[['_route' => '_373'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22189 => [[['_route' => '_375'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22238 => [[['_route' => '_450'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22287 => [[['_route' => '_464'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22345 => [[['_route' => '_51'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22393 => [[['_route' => '_77'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22441 => [[['_route' => '_234'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22489 => [[['_route' => '_394'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22542 => [[['_route' => '_88'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22590 => [[['_route' => '_155'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22643 => [[['_route' => '_96'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22691 => [[['_route' => '_298'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22739 => [[['_route' => '_470'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22792 => [[['_route' => '_109'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22840 => [[['_route' => '_204'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22893 => [[['_route' => '_115'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22941 => [[['_route' => '_145'], ['a', 'b', 'c'], null, null, false, false, null]],\n        22994 => [[['_route' => '_123'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23042 => [[['_route' => '_277'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23090 => [[['_route' => '_473'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23143 => [[['_route' => '_334'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23191 => [[['_route' => '_493'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23244 => [[['_route' => '_372'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23292 => [[['_route' => '_432'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23340 => [[['_route' => '_436'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23393 => [[['_route' => '_425'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23441 => [[['_route' => '_456'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23489 => [[['_route' => '_474'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23539 => [[['_route' => '_485'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23594 => [[['_route' => '_91'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23646 => [[['_route' => '_110'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23694 => [[['_route' => '_114'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23750 => [[['_route' => '_118'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23796 => [[['_route' => '_475'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23844 => [[['_route' => '_366'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23897 => [[['_route' => '_167'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23945 => [[['_route' => '_192'], ['a', 'b', 'c'], null, null, false, false, null]],\n        23993 => [[['_route' => '_342'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24046 => [[['_route' => '_229'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24097 => [[['_route' => '_235'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24144 => [[['_route' => '_302'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24193 => [[['_route' => '_322'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24246 => [[['_route' => '_237'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24294 => [[['_route' => '_293'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24347 => [[['_route' => '_239'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24395 => [[['_route' => '_444'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24443 => [[['_route' => '_491'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24491 => [[['_route' => '_492'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24541 => [[['_route' => '_258'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24590 => [[['_route' => '_317'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24639 => [[['_route' => '_361'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24688 => [[['_route' => '_391'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24737 => [[['_route' => '_462'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24786 => [[['_route' => '_476'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24837 => [[['_route' => '_501'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24889 => [[['_route' => '_514'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24937 => [[['_route' => '_731'], ['a', 'b', 'c'], null, null, false, false, null]],\n        24990 => [[['_route' => '_522'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25038 => [[['_route' => '_693'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25091 => [[['_route' => '_537'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25139 => [[['_route' => '_554'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25187 => [[['_route' => '_645'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25235 => [[['_route' => '_862'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25288 => [[['_route' => '_539'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25336 => [[['_route' => '_729'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25384 => [[['_route' => '_897'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25437 => [[['_route' => '_561'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25485 => [[['_route' => '_615'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25533 => [[['_route' => '_764'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25581 => [[['_route' => '_948'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25634 => [[['_route' => '_617'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25682 => [[['_route' => '_671'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25735 => [[['_route' => '_649'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25783 => [[['_route' => '_651'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25831 => [[['_route' => '_684'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25884 => [[['_route' => '_669'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25932 => [[['_route' => '_743'], ['a', 'b', 'c'], null, null, false, false, null]],\n        25980 => [[['_route' => '_962'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26033 => [[['_route' => '_694'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26081 => [[['_route' => '_985'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26134 => [[['_route' => '_707'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26182 => [[['_route' => '_718'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26235 => [[['_route' => '_720'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26283 => [[['_route' => '_745'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26333 => [[['_route' => '_874'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26391 => [[['_route' => '_502'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26439 => [[['_route' => '_667'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26487 => [[['_route' => '_911'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26535 => [[['_route' => '_942'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26585 => [[['_route' => '_504'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26637 => [[['_route' => '_524'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26685 => [[['_route' => '_732'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26738 => [[['_route' => '_596'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26786 => [[['_route' => '_601'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26839 => [[['_route' => '_620'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26887 => [[['_route' => '_631'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26935 => [[['_route' => '_771'], ['a', 'b', 'c'], null, null, false, false, null]],\n        26983 => [[['_route' => '_937'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27031 => [[['_route' => '_999'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27084 => [[['_route' => '_657'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27132 => [[['_route' => '_701'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27185 => [[['_route' => '_662'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27233 => [[['_route' => '_797'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27281 => [[['_route' => '_924'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27334 => [[['_route' => '_702'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27382 => [[['_route' => '_750'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27435 => [[['_route' => '_749'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27483 => [[['_route' => '_837'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27533 => [[['_route' => '_758'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27585 => [[['_route' => '_810'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27633 => [[['_route' => '_902'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27683 => [[['_route' => '_845'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27741 => [[['_route' => '_503'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27792 => [[['_route' => '_756'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27839 => [[['_route' => '_799'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27888 => [[['_route' => '_769'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27936 => [[['_route' => '_981'], ['a', 'b', 'c'], null, null, false, false, null]],\n        27989 => [[['_route' => '_507'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28037 => [[['_route' => '_672'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28085 => [[['_route' => '_790'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28138 => [[['_route' => '_515'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28186 => [[['_route' => '_523'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28234 => [[['_route' => '_957'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28282 => [[['_route' => '_995'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28335 => [[['_route' => '_532'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28383 => [[['_route' => '_642'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28433 => [[['_route' => '_579'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28485 => [[['_route' => '_625'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28533 => [[['_route' => '_916'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28586 => [[['_route' => '_633'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28634 => [[['_route' => '_656'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28687 => [[['_route' => '_658'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28735 => [[['_route' => '_943'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28788 => [[['_route' => '_664'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28836 => [[['_route' => '_852'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28884 => [[['_route' => '_870'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28937 => [[['_route' => '_683'], ['a', 'b', 'c'], null, null, false, false, null]],\n        28985 => [[['_route' => '_915'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29038 => [[['_route' => '_719'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29086 => [[['_route' => '_859'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29134 => [[['_route' => '_912'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29182 => [[['_route' => '_978'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29235 => [[['_route' => '_738'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29283 => [[['_route' => '_883'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29333 => [[['_route' => '_741'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29382 => [[['_route' => '_760'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29431 => [[['_route' => '_895'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29489 => [[['_route' => '_505'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29537 => [[['_route' => '_935'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29590 => [[['_route' => '_509'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29638 => [[['_route' => '_820'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29686 => [[['_route' => '_910'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29739 => [[['_route' => '_518'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29787 => [[['_route' => '_618'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29840 => [[['_route' => '_546'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29888 => [[['_route' => '_740'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29936 => [[['_route' => '_867'], ['a', 'b', 'c'], null, null, false, false, null]],\n        29989 => [[['_route' => '_572'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30037 => [[['_route' => '_952'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30090 => [[['_route' => '_573'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30138 => [[['_route' => '_692'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30186 => [[['_route' => '_700'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30234 => [[['_route' => '_772'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30284 => [[['_route' => '_653'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30336 => [[['_route' => '_695'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30384 => [[['_route' => '_748'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30437 => [[['_route' => '_710'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30485 => [[['_route' => '_716'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30533 => [[['_route' => '_969'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30586 => [[['_route' => '_734'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30634 => [[['_route' => '_742'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30682 => [[['_route' => '_844'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30735 => [[['_route' => '_763'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30783 => [[['_route' => '_965'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30836 => [[['_route' => '_778'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30884 => [[['_route' => '_813'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30932 => [[['_route' => '_831'], ['a', 'b', 'c'], null, null, false, false, null]],\n        30982 => [[['_route' => '_955'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31031 => [[['_route' => '_997'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31089 => [[['_route' => '_506'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31137 => [[['_route' => '_575'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31190 => [[['_route' => '_516'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31238 => [[['_route' => '_553'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31291 => [[['_route' => '_528'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31339 => [[['_route' => '_847'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31387 => [[['_route' => '_904'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31440 => [[['_route' => '_574'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31488 => [[['_route' => '_818'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31538 => [[['_route' => '_577'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31590 => [[['_route' => '_584'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31638 => [[['_route' => '_905'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31691 => [[['_route' => '_612'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31739 => [[['_route' => '_688'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31787 => [[['_route' => '_854'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31840 => [[['_route' => '_613'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31888 => [[['_route' => '_767'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31941 => [[['_route' => '_666'], ['a', 'b', 'c'], null, null, false, false, null]],\n        31989 => [[['_route' => '_759'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32037 => [[['_route' => '_827'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32085 => [[['_route' => '_840'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32138 => [[['_route' => '_680'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32186 => [[['_route' => '_784'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32234 => [[['_route' => '_842'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32282 => [[['_route' => '_860'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32332 => [[['_route' => '_704'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32381 => [[['_route' => '_727'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32430 => [[['_route' => '_777'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32482 => [[['_route' => '_838'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32530 => [[['_route' => '_861'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32583 => [[['_route' => '_849'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32631 => [[['_route' => '_982'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32679 => [[['_route' => '_986'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32741 => [[['_route' => '_508'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32788 => [[['_route' => '_517'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32837 => [[['_route' => '_622'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32890 => [[['_route' => '_513'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32938 => [[['_route' => '_655'], ['a', 'b', 'c'], null, null, false, false, null]],\n        32986 => [[['_route' => '_843'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33034 => [[['_route' => '_939'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33084 => [[['_route' => '_529'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33136 => [[['_route' => '_535'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33184 => [[['_route' => '_685'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33240 => [[['_route' => '_559'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33287 => [[['_route' => '_661'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33336 => [[['_route' => '_768'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33389 => [[['_route' => '_589'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33437 => [[['_route' => '_647'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33485 => [[['_route' => '_652'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33533 => [[['_route' => '_834'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33586 => [[['_route' => '_591'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33634 => [[['_route' => '_599'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33687 => [[['_route' => '_787'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33734 => [[['_route' => '_848'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33787 => [[['_route' => '_796'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33835 => [[['_route' => '_877'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33885 => [[['_route' => '_809'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33934 => [[['_route' => '_817'], ['a', 'b', 'c'], null, null, false, false, null]],\n        33986 => [[['_route' => '_819'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34034 => [[['_route' => '_865'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34084 => [[['_route' => '_919'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34133 => [[['_route' => '_949'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34191 => [[['_route' => '_510'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34239 => [[['_route' => '_590'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34287 => [[['_route' => '_597'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34335 => [[['_route' => '_682'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34383 => [[['_route' => '_723'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34436 => [[['_route' => '_521'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34484 => [[['_route' => '_594'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34532 => [[['_route' => '_689'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34580 => [[['_route' => '_713'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34628 => [[['_route' => '_889'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34681 => [[['_route' => '_531'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34729 => [[['_route' => '_639'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34780 => [[['_route' => '_646'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34827 => [[['_route' => '_659'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34876 => [[['_route' => '_959'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34929 => [[['_route' => '_550'], ['a', 'b', 'c'], null, null, false, false, null]],\n        34977 => [[['_route' => '_833'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35025 => [[['_route' => '_899'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35081 => [[['_route' => '_580'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35128 => [[['_route' => '_762'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35177 => [[['_route' => '_896'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35230 => [[['_route' => '_595'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35278 => [[['_route' => '_933'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35328 => [[['_route' => '_610'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35380 => [[['_route' => '_629'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35428 => [[['_route' => '_744'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35481 => [[['_route' => '_674'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35529 => [[['_route' => '_726'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35577 => [[['_route' => '_929'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35627 => [[['_route' => '_696'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35679 => [[['_route' => '_841'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35727 => [[['_route' => '_890'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35777 => [[['_route' => '_885'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35826 => [[['_route' => '_888'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35875 => [[['_route' => '_996'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35933 => [[['_route' => '_511'], ['a', 'b', 'c'], null, null, false, false, null]],\n        35981 => [[['_route' => '_576'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36029 => [[['_route' => '_623'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36082 => [[['_route' => '_560'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36129 => [[['_route' => '_585'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36182 => [[['_route' => '_570'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36230 => [[['_route' => '_578'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36281 => [[['_route' => '_780'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36328 => [[['_route' => '_808'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36382 => [[['_route' => '_593'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36430 => [[['_route' => '_900'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36483 => [[['_route' => '_632'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36531 => [[['_route' => '_654'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36579 => [[['_route' => '_721'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36627 => [[['_route' => '_836'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36680 => [[['_route' => '_637'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36728 => [[['_route' => '_737'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36784 => [[['_route' => '_699'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36831 => [[['_route' => '_822'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36880 => [[['_route' => '_853'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36933 => [[['_route' => '_708'], ['a', 'b', 'c'], null, null, false, false, null]],\n        36981 => [[['_route' => '_871'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37034 => [[['_route' => '_752'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37082 => [[['_route' => '_989'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37132 => [[['_route' => '_855'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37184 => [[['_route' => '_858'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37232 => [[['_route' => '_898'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37282 => [[['_route' => '_903'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37331 => [[['_route' => '_909'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37380 => [[['_route' => '_950'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37441 => [[['_route' => '_512'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37488 => [[['_route' => '_691'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37537 => [[['_route' => '_686'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37587 => [[['_route' => '_527'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37639 => [[['_route' => '_541'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37687 => [[['_route' => '_956'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37740 => [[['_route' => '_555'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37788 => [[['_route' => '_681'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37841 => [[['_route' => '_556'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37889 => [[['_route' => '_802'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37939 => [[['_route' => '_558'], ['a', 'b', 'c'], null, null, false, false, null]],\n        37991 => [[['_route' => '_564'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38039 => [[['_route' => '_670'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38087 => [[['_route' => '_884'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38140 => [[['_route' => '_627'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38187 => [[['_route' => '_746'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38240 => [[['_route' => '_668'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38291 => [[['_route' => '_712'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38338 => [[['_route' => '_863'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38387 => [[['_route' => '_801'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38440 => [[['_route' => '_709'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38488 => [[['_route' => '_850'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38536 => [[['_route' => '_918'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38586 => [[['_route' => '_803'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38638 => [[['_route' => '_864'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38686 => [[['_route' => '_880'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38734 => [[['_route' => '_927'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38787 => [[['_route' => '_930'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38835 => [[['_route' => '_951'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38883 => [[['_route' => '_963'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38942 => [[['_route' => '_519'], ['a', 'b', 'c'], null, null, false, false, null]],\n        38990 => [[['_route' => '_823'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39038 => [[['_route' => '_954'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39091 => [[['_route' => '_525'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39139 => [[['_route' => '_991'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39189 => [[['_route' => '_536'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39241 => [[['_route' => '_545'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39289 => [[['_route' => '_944'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39342 => [[['_route' => '_557'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39390 => [[['_route' => '_783'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39438 => [[['_route' => '_807'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39491 => [[['_route' => '_586'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39539 => [[['_route' => '_711'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39592 => [[['_route' => '_598'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39640 => [[['_route' => '_635'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39688 => [[['_route' => '_983'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39741 => [[['_route' => '_634'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39789 => [[['_route' => '_641'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39840 => [[['_route' => '_779'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39887 => [[['_route' => '_876'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39936 => [[['_route' => '_811'], ['a', 'b', 'c'], null, null, false, false, null]],\n        39984 => [[['_route' => '_824'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40037 => [[['_route' => '_660'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40085 => [[['_route' => '_789'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40138 => [[['_route' => '_733'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40186 => [[['_route' => '_735'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40234 => [[['_route' => '_882'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40282 => [[['_route' => '_967'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40332 => [[['_route' => '_736'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40381 => [[['_route' => '_753'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40430 => [[['_route' => '_786'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40479 => [[['_route' => '_907'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40528 => [[['_route' => '_920'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40577 => [[['_route' => '_971'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40635 => [[['_route' => '_520'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40683 => [[['_route' => '_891'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40739 => [[['_route' => '_534'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40785 => [[['_route' => '_602'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40834 => [[['_route' => '_605'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40882 => [[['_route' => '_979'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40932 => [[['_route' => '_547'], ['a', 'b', 'c'], null, null, false, false, null]],\n        40987 => [[['_route' => '_549'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41034 => [[['_route' => '_755'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41083 => [[['_route' => '_922'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41131 => [[['_route' => '_977'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41184 => [[['_route' => '_565'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41232 => [[['_route' => '_926'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41282 => [[['_route' => '_571'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41331 => [[['_route' => '_581'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41380 => [[['_route' => '_619'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41429 => [[['_route' => '_636'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41481 => [[['_route' => '_679'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41529 => [[['_route' => '_866'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41577 => [[['_route' => '_973'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41630 => [[['_route' => '_690'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41678 => [[['_route' => '_775'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41731 => [[['_route' => '_722'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41779 => [[['_route' => '_906'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41827 => [[['_route' => '_946'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41877 => [[['_route' => '_788'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41929 => [[['_route' => '_828'], ['a', 'b', 'c'], null, null, false, false, null]],\n        41977 => [[['_route' => '_892'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42025 => [[['_route' => '_972'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42075 => [[['_route' => '_829'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42127 => [[['_route' => '_923'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42175 => [[['_route' => '_947'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42234 => [[['_route' => '_526'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42282 => [[['_route' => '_614'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42330 => [[['_route' => '_621'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42383 => [[['_route' => '_543'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42431 => [[['_route' => '_812'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42487 => [[['_route' => '_548'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42534 => [[['_route' => '_747'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42583 => [[['_route' => '_715'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42631 => [[['_route' => '_940'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42684 => [[['_route' => '_563'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42732 => [[['_route' => '_611'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42780 => [[['_route' => '_830'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42833 => [[['_route' => '_569'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42881 => [[['_route' => '_908'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42929 => [[['_route' => '_913'], ['a', 'b', 'c'], null, null, false, false, null]],\n        42982 => [[['_route' => '_644'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43030 => [[['_route' => '_776'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43078 => [[['_route' => '_856'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43131 => [[['_route' => '_650'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43179 => [[['_route' => '_761'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43232 => [[['_route' => '_663'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43280 => [[['_route' => '_754'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43333 => [[['_route' => '_665'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43381 => [[['_route' => '_805'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43429 => [[['_route' => '_846'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43477 => [[['_route' => '_857'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43530 => [[['_route' => '_675'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43578 => [[['_route' => '_839'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43626 => [[['_route' => '_968'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43676 => [[['_route' => '_697'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43728 => [[['_route' => '_725'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43776 => [[['_route' => '_794'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43829 => [[['_route' => '_773'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43877 => [[['_route' => '_992'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43930 => [[['_route' => '_901'], ['a', 'b', 'c'], null, null, false, false, null]],\n        43978 => [[['_route' => '_970'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44028 => [[['_route' => '_964'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44086 => [[['_route' => '_530'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44134 => [[['_route' => '_703'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44187 => [[['_route' => '_533'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44235 => [[['_route' => '_739'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44283 => [[['_route' => '_791'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44331 => [[['_route' => '_987'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44384 => [[['_route' => '_566'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44432 => [[['_route' => '_592'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44488 => [[['_route' => '_568'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44534 => [[['_route' => '_868'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44583 => [[['_route' => '_878'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44636 => [[['_route' => '_588'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44684 => [[['_route' => '_793'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44732 => [[['_route' => '_917'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44785 => [[['_route' => '_600'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44833 => [[['_route' => '_728'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44886 => [[['_route' => '_603'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44934 => [[['_route' => '_765'], ['a', 'b', 'c'], null, null, false, false, null]],\n        44987 => [[['_route' => '_607'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45035 => [[['_route' => '_676'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45083 => [[['_route' => '_804'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45136 => [[['_route' => '_609'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45184 => [[['_route' => '_961'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45232 => [[['_route' => '_980'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45282 => [[['_route' => '_714'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45334 => [[['_route' => '_730'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45382 => [[['_route' => '_806'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45430 => [[['_route' => '_825'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45478 => [[['_route' => '_879'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45526 => [[['_route' => '_893'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45576 => [[['_route' => '_928'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45628 => [[['_route' => '_932'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45676 => [[['_route' => '_958'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45726 => [[['_route' => '_984'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45784 => [[['_route' => '_538'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45832 => [[['_route' => '_993'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45882 => [[['_route' => '_542'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45934 => [[['_route' => '_551'], ['a', 'b', 'c'], null, null, false, false, null]],\n        45982 => [[['_route' => '_687'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46030 => [[['_route' => '_724'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46078 => [[['_route' => '_925'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46131 => [[['_route' => '_587'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46179 => [[['_route' => '_914'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46229 => [[['_route' => '_616'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46284 => [[['_route' => '_677'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46331 => [[['_route' => '_815'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46380 => [[['_route' => '_781'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46430 => [[['_route' => '_717'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46482 => [[['_route' => '_782'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46530 => [[['_route' => '_832'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46583 => [[['_route' => '_795'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46631 => [[['_route' => '_887'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46681 => [[['_route' => '_800'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46730 => [[['_route' => '_826'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46779 => [[['_route' => '_881'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46828 => [[['_route' => '_886'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46877 => [[['_route' => '_938'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46935 => [[['_route' => '_540'], ['a', 'b', 'c'], null, null, false, false, null]],\n        46983 => [[['_route' => '_643'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47033 => [[['_route' => '_544'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47082 => [[['_route' => '_552'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47134 => [[['_route' => '_567'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47182 => [[['_route' => '_608'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47230 => [[['_route' => '_698'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47278 => [[['_route' => '_988'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47331 => [[['_route' => '_583'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47379 => [[['_route' => '_998'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47432 => [[['_route' => '_604'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47480 => [[['_route' => '_630'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47528 => [[['_route' => '_706'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47576 => [[['_route' => '_976'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47629 => [[['_route' => '_673'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47677 => [[['_route' => '_678'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47725 => [[['_route' => '_931'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47775 => [[['_route' => '_751'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47824 => [[['_route' => '_766'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47876 => [[['_route' => '_792'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47924 => [[['_route' => '_814'], ['a', 'b', 'c'], null, null, false, false, null]],\n        47974 => [[['_route' => '_798'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48026 => [[['_route' => '_851'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48074 => [[['_route' => '_941'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48122 => [[['_route' => '_953'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48170 => [[['_route' => '_975'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48220 => [[['_route' => '_873'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48269 => [[['_route' => '_936'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48318 => [[['_route' => '_994'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48376 => [[['_route' => '_562'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48424 => [[['_route' => '_770'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48475 => [[['_route' => '_774'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48522 => [[['_route' => '_966'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48573 => [[['_route' => '_582'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48625 => [[['_route' => '_606'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48673 => [[['_route' => '_648'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48723 => [[['_route' => '_624'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48775 => [[['_route' => '_626'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48823 => [[['_route' => '_821'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48873 => [[['_route' => '_628'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48922 => [[['_route' => '_638'], ['a', 'b', 'c'], null, null, false, false, null]],\n        48974 => [[['_route' => '_640'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49022 => [[['_route' => '_990'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49072 => [[['_route' => '_705'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49121 => [[['_route' => '_757'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49176 => [[['_route' => '_785'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49223 => [[['_route' => '_875'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49270 => [[['_route' => '_894'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49319 => [[['_route' => '_945'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49375 => [[['_route' => '_816'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49422 => [[['_route' => '_872'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49471 => [[['_route' => '_921'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49519 => [[['_route' => '_960'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49567 => [[['_route' => '_974'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49620 => [[['_route' => '_835'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49668 => [[['_route' => '_934'], ['a', 'b', 'c'], null, null, false, false, null]],\n        49718 => [\n            [['_route' => '_869'], ['a', 'b', 'c'], null, null, false, false, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher11.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/(en|fr)/(?'\n                    .'|admin/post(?'\n                        .'|(*:32)'\n                        .'|/(?'\n                            .'|new(*:46)'\n                            .'|(\\\\d+)(*:58)'\n                            .'|(\\\\d+)/edit(*:75)'\n                            .'|(\\\\d+)/delete(*:94)'\n                        .')'\n                    .')'\n                    .'|blog(?'\n                        .'|(*:110)'\n                        .'|/(?'\n                            .'|rss\\\\.xml(*:130)'\n                            .'|p(?'\n                                .'|age/([^/]++)(*:154)'\n                                .'|osts/([^/]++)(*:175)'\n                            .')'\n                            .'|comments/(\\\\d+)/new(*:202)'\n                            .'|search(*:216)'\n                        .')'\n                    .')'\n                    .'|log(?'\n                        .'|in(*:234)'\n                        .'|out(*:245)'\n                    .')'\n                .')'\n                .'|/(en|fr)?(*:264)'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        32 => [[['_route' => 'a', '_locale' => 'en'], ['_locale'], null, null, true, false, null]],\n        46 => [[['_route' => 'b', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],\n        58 => [[['_route' => 'c', '_locale' => 'en'], ['_locale', 'id'], null, null, false, true, null]],\n        75 => [[['_route' => 'd', '_locale' => 'en'], ['_locale', 'id'], null, null, false, false, null]],\n        94 => [[['_route' => 'e', '_locale' => 'en'], ['_locale', 'id'], null, null, false, false, null]],\n        110 => [[['_route' => 'f', '_locale' => 'en'], ['_locale'], null, null, true, false, null]],\n        130 => [[['_route' => 'g', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],\n        154 => [[['_route' => 'h', '_locale' => 'en'], ['_locale', 'page'], null, null, false, true, null]],\n        175 => [[['_route' => 'i', '_locale' => 'en'], ['_locale', 'page'], null, null, false, true, null]],\n        202 => [[['_route' => 'j', '_locale' => 'en'], ['_locale', 'id'], null, null, false, false, null]],\n        216 => [[['_route' => 'k', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],\n        234 => [[['_route' => 'l', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],\n        245 => [[['_route' => 'm', '_locale' => 'en'], ['_locale'], null, null, false, false, null]],\n        264 => [\n            [['_route' => 'n', '_locale' => 'en'], ['_locale'], null, null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher12.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/abc([^/]++)/(?'\n                    .'|1(?'\n                        .'|(*:27)'\n                        .'|0(?'\n                            .'|(*:38)'\n                            .'|0(*:46)'\n                        .')'\n                    .')'\n                    .'|2(?'\n                        .'|(*:59)'\n                        .'|0(?'\n                            .'|(*:70)'\n                            .'|0(*:78)'\n                        .')'\n                    .')'\n                .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        27 => [[['_route' => 'r1'], ['foo'], null, null, false, false, null]],\n        38 => [[['_route' => 'r10'], ['foo'], null, null, false, false, null]],\n        46 => [[['_route' => 'r100'], ['foo'], null, null, false, false, null]],\n        59 => [[['_route' => 'r2'], ['foo'], null, null, false, false, null]],\n        70 => [[['_route' => 'r20'], ['foo'], null, null, false, false, null]],\n        78 => [\n            [['_route' => 'r200'], ['foo'], null, null, false, false, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher13.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    true, // $matchHost\n    [ // $staticRoutes\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n            .'|(?i:([^\\\\.]++)\\\\.example\\\\.com)\\\\.(?'\n                .'|/abc([^/]++)(?'\n                    .'|(*:55)'\n                .')'\n            .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        55 => [\n            [['_route' => 'r1'], ['foo', 'foo'], null, null, false, true, null],\n            [['_route' => 'r2'], ['foo', 'foo'], null, null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher14.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n        '/fr/accueil' => [[['_route' => 'home', '_locale' => 'fr'], null, null, null, false, false, null]],\n        '/en/home' => [[['_route' => 'home', '_locale' => 'en'], null, null, null, false, false, null]],\n    ],\n    [ // $regexpList\n    ],\n    [ // $dynamicRoutes\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher2.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    true, // $matchHost\n    [ // $staticRoutes\n        '/test/baz' => [[['_route' => 'baz'], null, null, null, false, false, null]],\n        '/test/baz.html' => [[['_route' => 'baz2'], null, null, null, false, false, null]],\n        '/test/baz3' => [[['_route' => 'baz3'], null, null, null, true, false, null]],\n        '/foofoo' => [[['_route' => 'foofoo', 'def' => 'test'], null, null, null, false, false, null]],\n        '/spa ce' => [[['_route' => 'space'], null, null, null, false, false, null]],\n        '/multi/new' => [[['_route' => 'overridden2'], null, null, null, false, false, null]],\n        '/multi/hey' => [[['_route' => 'hey'], null, null, null, true, false, null]],\n        '/ababa' => [[['_route' => 'ababa'], null, null, null, false, false, null]],\n        '/route1' => [[['_route' => 'route1'], 'a.example.com', null, null, false, false, null]],\n        '/c2/route2' => [[['_route' => 'route2'], 'a.example.com', null, null, false, false, null]],\n        '/route4' => [[['_route' => 'route4'], 'a.example.com', null, null, false, false, null]],\n        '/c2/route3' => [[['_route' => 'route3'], 'b.example.com', null, null, false, false, null]],\n        '/route5' => [[['_route' => 'route5'], 'c.example.com', null, null, false, false, null]],\n        '/route6' => [[['_route' => 'route6'], null, null, null, false, false, null]],\n        '/route11' => [[['_route' => 'route11'], '{^(?P<var1>[^\\\\.]++)\\\\.example\\\\.com$}sDi', null, null, false, false, null]],\n        '/route12' => [[['_route' => 'route12', 'var1' => 'val'], '{^(?P<var1>[^\\\\.]++)\\\\.example\\\\.com$}sDi', null, null, false, false, null]],\n        '/route17' => [[['_route' => 'route17'], null, null, null, false, false, null]],\n        '/secure' => [[['_route' => 'secure'], null, null, ['https' => 0], false, false, null]],\n        '/nonsecure' => [[['_route' => 'nonsecure'], null, null, ['http' => 0], false, false, null]],\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n            .'|(?:(?:[^./]*+\\\\.)++)(?'\n                .'|/foo/(baz|symfony)(*:47)'\n                .'|/bar(?'\n                    .'|/([^/]++)(*:70)'\n                    .'|head/([^/]++)(*:90)'\n                .')'\n                .'|/test/([^/]++)(?'\n                    .'|(*:115)'\n                .')'\n                .'|/([\\']+)(*:131)'\n                .'|/a/(?'\n                    .'|b\\'b/([^/]++)(?'\n                        .'|(*:160)'\n                        .'|(*:168)'\n                    .')'\n                    .'|(.*)(*:181)'\n                    .'|b\\'b/([^/]++)(?'\n                        .'|(*:204)'\n                        .'|(*:212)'\n                    .')'\n                .')'\n                .'|/multi/hello(?:/([^/]++))?(*:248)'\n                .'|/([^/]++)/b/([^/]++)(?'\n                    .'|(*:279)'\n                    .'|(*:287)'\n                .')'\n                .'|/aba/([^/]++)(*:309)'\n            .')|(?i:([^\\\\.]++)\\\\.example\\\\.com)\\\\.(?'\n                .'|/route1(?'\n                    .'|3/([^/]++)(*:371)'\n                    .'|4/([^/]++)(*:389)'\n                .')'\n            .')|(?i:c\\\\.example\\\\.com)\\\\.(?'\n                .'|/route15/([^/]++)(*:441)'\n            .')|(?:(?:[^./]*+\\\\.)++)(?'\n                .'|/route16/([^/]++)(*:489)'\n                .'|/a/(?'\n                    .'|a\\\\.\\\\.\\\\.(*:510)'\n                    .'|b/(?'\n                        .'|([^/]++)(*:531)'\n                        .'|c/([^/]++)(*:549)'\n                    .')'\n                .')'\n            .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        47 => [[['_route' => 'foo', 'def' => 'test'], ['bar'], null, null, false, true, null]],\n        70 => [[['_route' => 'bar'], ['foo'], ['GET' => 0, 'HEAD' => 1], null, false, true, null]],\n        90 => [[['_route' => 'barhead'], ['foo'], ['GET' => 0], null, false, true, null]],\n        115 => [\n            [['_route' => 'baz4'], ['foo'], null, null, true, true, null],\n            [['_route' => 'baz5'], ['foo'], ['POST' => 0], null, true, true, null],\n            [['_route' => 'baz.baz6'], ['foo'], ['PUT' => 0], null, true, true, null],\n        ],\n        131 => [[['_route' => 'quoter'], ['quoter'], null, null, false, true, null]],\n        160 => [[['_route' => 'foo1'], ['foo'], ['PUT' => 0], null, false, true, null]],\n        168 => [[['_route' => 'bar1'], ['bar'], null, null, false, true, null]],\n        181 => [[['_route' => 'overridden'], ['var'], null, null, false, true, null]],\n        204 => [[['_route' => 'foo2'], ['foo1'], null, null, false, true, null]],\n        212 => [[['_route' => 'bar2'], ['bar1'], null, null, false, true, null]],\n        248 => [[['_route' => 'helloWorld', 'who' => 'World!'], ['who'], null, null, false, true, null]],\n        279 => [[['_route' => 'foo3'], ['_locale', 'foo'], null, null, false, true, null]],\n        287 => [[['_route' => 'bar3'], ['_locale', 'bar'], null, null, false, true, null]],\n        309 => [[['_route' => 'foo4'], ['foo'], null, null, false, true, null]],\n        371 => [[['_route' => 'route13'], ['var1', 'name'], null, null, false, true, null]],\n        389 => [[['_route' => 'route14', 'var1' => 'val'], ['var1', 'name'], null, null, false, true, null]],\n        441 => [[['_route' => 'route15'], ['name'], null, null, false, true, null]],\n        489 => [[['_route' => 'route16', 'var1' => 'val'], ['name'], null, null, false, true, null]],\n        510 => [[['_route' => 'a'], [], null, null, false, false, null]],\n        531 => [[['_route' => 'b'], ['var'], null, null, false, true, null]],\n        549 => [\n            [['_route' => 'c'], ['var'], null, null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher3.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n        '/rootprefix/test' => [[['_route' => 'static'], null, null, null, false, false, null]],\n        '/with-condition' => [[['_route' => 'with-condition'], null, null, null, false, false, -1]],\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/rootprefix/([^/]++)(*:27)'\n                .'|/with\\\\-condition/(\\\\d+)(*:56)'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        27 => [[['_route' => 'dynamic'], ['var'], null, null, false, true, null]],\n        56 => [\n            [['_route' => 'with-condition-dynamic'], ['id'], null, null, false, true, -2],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    static function ($condition, $context, $request, $params) { // $checkCondition\n        switch ($condition) {\n            case -1: return ($context->getMethod() == \"GET\");\n            case -2: return ($params[\"id\"] < 100);\n        }\n    },\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher4.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n        '/just_head' => [[['_route' => 'just_head'], null, ['HEAD' => 0], null, false, false, null]],\n        '/head_and_get' => [[['_route' => 'head_and_get'], null, ['HEAD' => 0, 'GET' => 1], null, false, false, null]],\n        '/get_and_head' => [[['_route' => 'get_and_head'], null, ['GET' => 0, 'HEAD' => 1], null, false, false, null]],\n        '/post_and_head' => [[['_route' => 'post_and_head'], null, ['POST' => 0, 'HEAD' => 1], null, false, false, null]],\n        '/put_and_post' => [\n            [['_route' => 'put_and_post'], null, ['PUT' => 0, 'POST' => 1], null, false, false, null],\n            [['_route' => 'put_and_get_and_head'], null, ['PUT' => 0, 'GET' => 1, 'HEAD' => 2], null, false, false, null],\n        ],\n    ],\n    [ // $regexpList\n    ],\n    [ // $dynamicRoutes\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher5.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n        '/a/11' => [[['_route' => 'a_first'], null, null, null, false, false, null]],\n        '/a/22' => [[['_route' => 'a_second'], null, null, null, false, false, null]],\n        '/a/333' => [[['_route' => 'a_third'], null, null, null, false, false, null]],\n        '/a/44' => [[['_route' => 'a_fourth'], null, null, null, true, false, null]],\n        '/a/55' => [[['_route' => 'a_fifth'], null, null, null, true, false, null]],\n        '/a/66' => [[['_route' => 'a_sixth'], null, null, null, true, false, null]],\n        '/nested/group/a' => [[['_route' => 'nested_a'], null, null, null, true, false, null]],\n        '/nested/group/b' => [[['_route' => 'nested_b'], null, null, null, true, false, null]],\n        '/nested/group/c' => [[['_route' => 'nested_c'], null, null, null, true, false, null]],\n        '/slashed/group' => [[['_route' => 'slashed_a'], null, null, null, true, false, null]],\n        '/slashed/group/b' => [[['_route' => 'slashed_b'], null, null, null, true, false, null]],\n        '/slashed/group/c' => [[['_route' => 'slashed_c'], null, null, null, true, false, null]],\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/([^/]++)(*:16)'\n                .'|/nested/([^/]++)(*:39)'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        16 => [[['_route' => 'a_wildcard'], ['param'], null, null, false, true, null]],\n        39 => [\n            [['_route' => 'nested_wildcard'], ['param'], null, null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher6.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n        '/trailing/simple/no-methods' => [[['_route' => 'simple_trailing_slash_no_methods'], null, null, null, true, false, null]],\n        '/trailing/simple/get-method' => [[['_route' => 'simple_trailing_slash_GET_method'], null, ['GET' => 0], null, true, false, null]],\n        '/trailing/simple/head-method' => [[['_route' => 'simple_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, true, false, null]],\n        '/trailing/simple/post-method' => [[['_route' => 'simple_trailing_slash_POST_method'], null, ['POST' => 0], null, true, false, null]],\n        '/not-trailing/simple/no-methods' => [[['_route' => 'simple_not_trailing_slash_no_methods'], null, null, null, false, false, null]],\n        '/not-trailing/simple/get-method' => [[['_route' => 'simple_not_trailing_slash_GET_method'], null, ['GET' => 0], null, false, false, null]],\n        '/not-trailing/simple/head-method' => [[['_route' => 'simple_not_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, false, false, null]],\n        '/not-trailing/simple/post-method' => [[['_route' => 'simple_not_trailing_slash_POST_method'], null, ['POST' => 0], null, false, false, null]],\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/trailing/regex/(?'\n                    .'|no\\\\-methods/([^/]++)(*:46)'\n                    .'|get\\\\-method/([^/]++)(*:73)'\n                    .'|head\\\\-method/([^/]++)(*:101)'\n                    .'|post\\\\-method/([^/]++)(*:130)'\n                .')'\n                .'|/not\\\\-trailing/regex/(?'\n                    .'|no\\\\-methods/([^/]++)(*:183)'\n                    .'|get\\\\-method/([^/]++)(*:211)'\n                    .'|head\\\\-method/([^/]++)(*:240)'\n                    .'|post\\\\-method/([^/]++)(*:269)'\n                .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        46 => [[['_route' => 'regex_trailing_slash_no_methods'], ['param'], null, null, true, true, null]],\n        73 => [[['_route' => 'regex_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, true, true, null]],\n        101 => [[['_route' => 'regex_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, true, true, null]],\n        130 => [[['_route' => 'regex_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, true, true, null]],\n        183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],\n        211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],\n        240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],\n        269 => [\n            [['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher7.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n        '/trailing/simple/no-methods' => [[['_route' => 'simple_trailing_slash_no_methods'], null, null, null, true, false, null]],\n        '/trailing/simple/get-method' => [[['_route' => 'simple_trailing_slash_GET_method'], null, ['GET' => 0], null, true, false, null]],\n        '/trailing/simple/head-method' => [[['_route' => 'simple_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, true, false, null]],\n        '/trailing/simple/post-method' => [[['_route' => 'simple_trailing_slash_POST_method'], null, ['POST' => 0], null, true, false, null]],\n        '/not-trailing/simple/no-methods' => [[['_route' => 'simple_not_trailing_slash_no_methods'], null, null, null, false, false, null]],\n        '/not-trailing/simple/get-method' => [[['_route' => 'simple_not_trailing_slash_GET_method'], null, ['GET' => 0], null, false, false, null]],\n        '/not-trailing/simple/head-method' => [[['_route' => 'simple_not_trailing_slash_HEAD_method'], null, ['HEAD' => 0], null, false, false, null]],\n        '/not-trailing/simple/post-method' => [[['_route' => 'simple_not_trailing_slash_POST_method'], null, ['POST' => 0], null, false, false, null]],\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/trailing/regex/(?'\n                    .'|no\\\\-methods/([^/]++)(*:46)'\n                    .'|get\\\\-method/([^/]++)(*:73)'\n                    .'|head\\\\-method/([^/]++)(*:101)'\n                    .'|post\\\\-method/([^/]++)(*:130)'\n                .')'\n                .'|/not\\\\-trailing/regex/(?'\n                    .'|no\\\\-methods/([^/]++)(*:183)'\n                    .'|get\\\\-method/([^/]++)(*:211)'\n                    .'|head\\\\-method/([^/]++)(*:240)'\n                    .'|post\\\\-method/([^/]++)(*:269)'\n                .')'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        46 => [[['_route' => 'regex_trailing_slash_no_methods'], ['param'], null, null, true, true, null]],\n        73 => [[['_route' => 'regex_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, true, true, null]],\n        101 => [[['_route' => 'regex_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, true, true, null]],\n        130 => [[['_route' => 'regex_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, true, true, null]],\n        183 => [[['_route' => 'regex_not_trailing_slash_no_methods'], ['param'], null, null, false, true, null]],\n        211 => [[['_route' => 'regex_not_trailing_slash_GET_method'], ['param'], ['GET' => 0], null, false, true, null]],\n        240 => [[['_route' => 'regex_not_trailing_slash_HEAD_method'], ['param'], ['HEAD' => 0], null, false, true, null]],\n        269 => [\n            [['_route' => 'regex_not_trailing_slash_POST_method'], ['param'], ['POST' => 0], null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher8.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    false, // $matchHost\n    [ // $staticRoutes\n    ],\n    [ // $regexpList\n        0 => '{^(?'\n                .'|/(a)(*:11)'\n            .')/?$}sD',\n        11 => '{^(?'\n                .'|/(.)(*:22)'\n            .')/?$}sDu',\n        22 => '{^(?'\n                .'|/(.)(*:33)'\n            .')/?$}sD',\n    ],\n    [ // $dynamicRoutes\n        11 => [[['_route' => 'a'], ['a'], null, null, false, true, null]],\n        22 => [[['_route' => 'b'], ['a'], null, null, false, true, null]],\n        33 => [\n            [['_route' => 'c'], ['a'], null, null, false, true, null],\n            [null, null, null, null, false, false, 0],\n        ],\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/dumper/compiled_url_matcher9.php",
    "content": "<?php\n\n/**\n * This file has been auto-generated\n * by the Symfony Routing Component.\n */\n\nreturn [\n    true, // $matchHost\n    [ // $staticRoutes\n        '/' => [\n            [['_route' => 'a'], '{^(?P<d>[^\\\\.]++)\\\\.e\\\\.c\\\\.b\\\\.a$}sDi', null, null, false, false, null],\n            [['_route' => 'c'], '{^(?P<e>[^\\\\.]++)\\\\.e\\\\.c\\\\.b\\\\.a$}sDi', null, null, false, false, null],\n            [['_route' => 'b'], 'd.c.b.a', null, null, false, false, null],\n        ],\n    ],\n    [ // $regexpList\n    ],\n    [ // $dynamicRoutes\n    ],\n    null, // $checkCondition\n];\n"
  },
  {
    "path": "Tests/Fixtures/empty.yml",
    "content": ""
  },
  {
    "path": "Tests/Fixtures/file_resource.yml",
    "content": ""
  },
  {
    "path": "Tests/Fixtures/glob/bar.yml",
    "content": "bar_route:\n    path: /bar\n    defaults:\n        _controller: AppBundle:Bar:view\n"
  },
  {
    "path": "Tests/Fixtures/glob/baz.yml",
    "content": "baz_route:\n    path: /baz\n    defaults:\n        _controller: AppBundle:Baz:view\n"
  },
  {
    "path": "Tests/Fixtures/glob/import_multiple.yml",
    "content": "_static:\n    resource: ba?.yml\n"
  },
  {
    "path": "Tests/Fixtures/glob/import_single.yml",
    "content": "_static:\n    resource: b?r.yml\n"
  },
  {
    "path": "Tests/Fixtures/glob/php_dsl.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn fn (RoutingConfigurator $routes) => $routes->import('php_dsl_ba?.php');\n"
  },
  {
    "path": "Tests/Fixtures/glob/php_dsl_bar.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $collection = $routes->collection();\n\n    $collection->add('bar_route', '/bar')\n        ->defaults(['_controller' => 'AppBundle:Bar:view']);\n\n    return $collection;\n};\n"
  },
  {
    "path": "Tests/Fixtures/glob/php_dsl_baz.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $collection = $routes->collection();\n\n    $collection->add('baz_route', '/baz')\n        ->defaults(['_controller' => 'AppBundle:Baz:view']);\n\n    return $collection;\n};\n"
  },
  {
    "path": "Tests/Fixtures/import_with_name_prefix/routing.yml",
    "content": "app:\n    resource: ../controller/routing.yml\n\napi:\n    resource: ../controller/routing.yml\n    name_prefix: api_\n    prefix: /api\n\nempty_wildcard:\n    resource: ../controller/empty_wildcard/*\n    prefix: /empty_wildcard\n"
  },
  {
    "path": "Tests/Fixtures/import_with_no_trailing_slash/routing.yml",
    "content": "app:\n    resource: ../controller/routing.yml\n    name_prefix: a_\n    prefix: /slash\n\napi:\n    resource: ../controller/routing.yml\n    name_prefix: b_\n    prefix: /no-slash\n    trailing_slash_on_root: false\n"
  },
  {
    "path": "Tests/Fixtures/imported-with-defaults.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes\n        ->add('one', '/one')\n        ->add('two', '/two')->defaults(['specific' => 'imported'])\n    ;\n};\n"
  },
  {
    "path": "Tests/Fixtures/imported-with-defaults.yml",
    "content": "one:\n  path: /one\n\ntwo:\n  path: /two\n  defaults:\n    specific: imported\n"
  },
  {
    "path": "Tests/Fixtures/importer-php-returns-array-with-import.yml",
    "content": "routes_from_php:\n    resource: validpattern.php\n    type: php\n"
  },
  {
    "path": "Tests/Fixtures/importer-php-returns-array.php",
    "content": "<?php\n\nreturn [\n    'blog_show' => [\n        'resource' => 'importer-php-returns-array-with-import.yml',\n    ],\n    'direct' => [\n        'path' => '/direct',\n    ],\n];\n"
  },
  {
    "path": "Tests/Fixtures/importer-with-defaults.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->import('imported-with-defaults.php')\n        ->prefix('/defaults')\n        ->locale('g_locale')\n        ->format('g_format')\n        ->stateless(true)\n    ;\n};\n"
  },
  {
    "path": "Tests/Fixtures/importer-with-defaults.yml",
    "content": "defaults:\n  resource: imported-with-defaults.yml\n  prefix: /defaults\n  locale: g_locale\n  format: g_format\n  stateless: true\n"
  },
  {
    "path": "Tests/Fixtures/incomplete.yml",
    "content": "blog_show:\n    defaults:  { _controller: MyBlogBundle:Blog:show }\n"
  },
  {
    "path": "Tests/Fixtures/legacy_internal_scope.php",
    "content": "<?php\n\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n// access the loader's internal scope to trigger deprecation\n$loader->callConfigurator(static fn () => [], 'dummy.php', 'dummy.php');\n\nreturn new RouteCollection();\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/import-with-host-expected-collection.php",
    "content": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nreturn function (string $format) {\n    $expectedRoutes = new RouteCollection();\n    $expectedRoutes->add('imported.en', $route = new Route('/example'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported.nl', $route = new Route('/voorbeeld'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_not_localized.en', $route = new Route('/here'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported_not_localized');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_not_localized.nl', $route = new Route('/here'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported_not_localized');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_single_host.en', $route = new Route('/here_again'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported_single_host');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_single_host.nl', $route = new Route('/here_again'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported_single_host');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/imported.$format\"));\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/importer-with-host.$format\"));\n\n    return $expectedRoutes;\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/import-with-locale-and-host-expected-collection.php",
    "content": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nreturn function (string $format) {\n    $expectedRoutes = new RouteCollection();\n    $expectedRoutes->add('imported.en', $route = new Route('/en/example'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported.nl', $route = new Route('/nl/voorbeeld'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_not_localized.en', $route = new Route('/en/here'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported_not_localized');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_not_localized.nl', $route = new Route('/nl/here'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported_not_localized');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_single_host.en', $route = new Route('/en/here_again'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported_single_host');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_single_host.nl', $route = new Route('/nl/here_again'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported_single_host');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/imported.$format\"));\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/importer-with-locale-and-host.$format\"));\n\n    return $expectedRoutes;\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/import-with-single-host-expected-collection.php",
    "content": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nreturn function (string $format) {\n    $expectedRoutes = new RouteCollection();\n    $expectedRoutes->add('imported.en', $route = new Route('/example'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported.nl', $route = new Route('/voorbeeld'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_not_localized', $route = new Route('/here'));\n    $route->setHost('www.example.com');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_single_host', $route = new Route('/here_again'));\n    $route->setHost('www.example.com');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/imported.$format\"));\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/importer-with-single-host.$format\"));\n\n    return $expectedRoutes;\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/import-without-host-expected-collection.php",
    "content": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nreturn function (string $format) {\n    $expectedRoutes = new RouteCollection();\n    $expectedRoutes->add('imported.en', $route = new Route('/example'));\n    $route->setHost('www.custom.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported.nl', $route = new Route('/voorbeeld'));\n    $route->setHost('www.custom.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'imported');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_not_localized', $route = new Route('/here'));\n    $route->setDefault('_controller', 'ImportedController::someAction');\n    $expectedRoutes->add('imported_single_host', $route = new Route('/here_again'));\n    $route->setHost('www.custom.com');\n    $route->setDefault('_controller', 'ImportedController::someAction');\n\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/imported.$format\"));\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/importer-without-host.$format\"));\n\n    return $expectedRoutes;\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/imported.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes\n        ->add('imported', ['nl' => '/voorbeeld', 'en' => '/example'])\n            ->controller('ImportedController::someAction')\n            ->host([\n                'nl' => 'www.custom.nl',\n                'en' => 'www.custom.com',\n            ])\n        ->add('imported_not_localized', '/here')\n            ->controller('ImportedController::someAction')\n        ->add('imported_single_host', '/here_again')\n            ->controller('ImportedController::someAction')\n            ->host('www.custom.com')\n    ;\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/imported.yml",
    "content": "---\nimported:\n    controller: ImportedController::someAction\n    path:\n        nl: /voorbeeld\n        en: /example\n    host:\n        nl: www.custom.nl\n        en: www.custom.com\n\nimported_not_localized:\n    controller: ImportedController::someAction\n    path: /here\n\nimported_single_host:\n    controller: ImportedController::someAction\n    path: /here_again\n    host: www.custom.com\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-with-host.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->import('imported.php')->host([\n        'nl' => 'www.example.nl',\n        'en' => 'www.example.com',\n    ]);\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-with-host.yml",
    "content": "---\ni_need:\n    resource: ./imported.yml\n    host:\n        nl: www.example.nl\n        en: www.example.com\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-with-locale-and-host.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->import('imported.php')->host([\n        'nl' => 'www.example.nl',\n        'en' => 'www.example.com',\n    ])->prefix([\n        'nl' => '/nl',\n        'en' => '/en',\n    ]);\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-with-locale-and-host.yml",
    "content": "---\ni_need:\n    resource: ./imported.yml\n    prefix:\n        nl: /nl\n        en: /en\n    host:\n        nl: www.example.nl\n        en: www.example.com\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-with-single-host.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->import('imported.php')->host('www.example.com');\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-with-single-host.yml",
    "content": "---\ni_need:\n    resource: ./imported.yml\n    host: www.example.com\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-without-host.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->import('imported.php');\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/importer-without-host.yml",
    "content": "---\ni_need:\n    resource: ./imported.yml\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/priorized-host.yml",
    "content": "controllers:\n  resource: Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\RouteWithPriorityController\n  type: attribute\n  host:\n    cs: www.domain.cs\n    en: www.domain.com\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/route-with-hosts-expected-collection.php",
    "content": "<?php\n\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nreturn function (string $format) {\n    $expectedRoutes = new RouteCollection();\n    $expectedRoutes->add('static.en', $route = new Route('/example'));\n    $route->setHost('www.example.com');\n    $route->setRequirement('_locale', 'en');\n    $route->setDefault('_locale', 'en');\n    $route->setDefault('_canonical_route', 'static');\n    $expectedRoutes->add('static.nl', $route = new Route('/example'));\n    $route->setHost('www.example.nl');\n    $route->setRequirement('_locale', 'nl');\n    $route->setDefault('_locale', 'nl');\n    $route->setDefault('_canonical_route', 'static');\n\n    $expectedRoutes->addResource(new FileResource(__DIR__.\"/route-with-hosts.$format\"));\n\n    return $expectedRoutes;\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/route-with-hosts.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->add('static', '/example')->host([\n        'nl' => 'www.example.nl',\n        'en' => 'www.example.com',\n    ]);\n};\n"
  },
  {
    "path": "Tests/Fixtures/locale_and_host/route-with-hosts.yml",
    "content": "---\nstatic:\n    path: /example\n    host:\n        nl: www.example.nl\n        en: www.example.com\n"
  },
  {
    "path": "Tests/Fixtures/localized/imported-with-locale-but-not-localized.yml",
    "content": "---\nimported:\n    controller: ImportedController::someAction\n    path: /imported\n"
  },
  {
    "path": "Tests/Fixtures/localized/imported-with-locale.yml",
    "content": "---\nimported:\n    controller: ImportedController::someAction\n    path:\n        nl: /voorbeeld\n        en: /example\n"
  },
  {
    "path": "Tests/Fixtures/localized/imported-with-utf8.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes\n        ->add('utf8_one', '/one')\n        ->add('utf8_two', '/two')\n    ;\n};\n"
  },
  {
    "path": "Tests/Fixtures/localized/imported-with-utf8.yml",
    "content": "utf8_one:\n    path: /one\n\nutf8_two:\n    path: /two\n"
  },
  {
    "path": "Tests/Fixtures/localized/importer-with-controller-default.yml",
    "content": "---\ni_need:\n    defaults:\n        _controller: DefaultController::defaultAction\n    resource: ./localized-route.yml\n"
  },
  {
    "path": "Tests/Fixtures/localized/importer-with-locale-imports-non-localized-route.yml",
    "content": "---\ni_need:\n    resource: ./imported-with-locale-but-not-localized.yml\n    prefix:\n        nl: /nl\n        en: /en\n"
  },
  {
    "path": "Tests/Fixtures/localized/importer-with-locale.yml",
    "content": "---\ni_need:\n    resource: ./imported-with-locale.yml\n    prefix:\n        nl: /nl\n        en: /en\n"
  },
  {
    "path": "Tests/Fixtures/localized/importer-with-utf8.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes->import('imported-with-utf8.php')->utf8();\n};\n"
  },
  {
    "path": "Tests/Fixtures/localized/importer-with-utf8.yml",
    "content": "utf8_routes:\n    resource: imported-with-utf8.yml\n    utf8: true\n"
  },
  {
    "path": "Tests/Fixtures/localized/importing-localized-route.yml",
    "content": "---\ni_need:\n    resource: ./localized-route.yml\n"
  },
  {
    "path": "Tests/Fixtures/localized/localized-prefix.yml",
    "content": "important_controllers:\n  resource: Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\RouteWithPriorityController\n  type: attribute\n  prefix:\n    cs: /cs\n    en: /en\n"
  },
  {
    "path": "Tests/Fixtures/localized/localized-route.yml",
    "content": "---\nhome:\n    path:\n        nl: /nl\n        en: /en\n\nnot_localized:\n    controller: HomeController::otherAction\n    path: /here\n"
  },
  {
    "path": "Tests/Fixtures/localized/missing-locale-in-importer.yml",
    "content": "---\nimporting_with_missing_prefix:\n    resource: ./localized-route.yml\n    prefix:\n    nl: /prefix\n"
  },
  {
    "path": "Tests/Fixtures/localized/not-localized.yml",
    "content": "---\nnot_localized:\n    controller: string\n    path: /here\n"
  },
  {
    "path": "Tests/Fixtures/localized/officially_formatted_locales.yml",
    "content": "---\nofficial:\n    controller: HomeController::someAction\n    path:\n        fr.UTF-8: /omelette-au-fromage\n        pt-PT: /eu-não-sou-espanhol\n        pt_BR: /churrasco\n"
  },
  {
    "path": "Tests/Fixtures/localized/route-without-path-or-locales.yml",
    "content": "---\nroutename:\n    controller: Here::here\n"
  },
  {
    "path": "Tests/Fixtures/localized/utf8.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes\n        ->add('some_route', '/')\n        ->add('some_utf8_route', '/utf8')->utf8()\n    ;\n};\n"
  },
  {
    "path": "Tests/Fixtures/localized/utf8.yml",
    "content": "some_route:\n    path: /\n\nsome_utf8_route:\n    path: /utf8\n    utf8: true\n"
  },
  {
    "path": "Tests/Fixtures/nonesense_resource_plus_path.yml",
    "content": "blog_show:\n    resource: validpattern.yml\n    path:     /test\n"
  },
  {
    "path": "Tests/Fixtures/nonesense_type_without_resource.yml",
    "content": "blog_show:\n    path:    /blog/{slug}\n    type:    custom\n"
  },
  {
    "path": "Tests/Fixtures/nonvalid.yml",
    "content": "foo\n"
  },
  {
    "path": "Tests/Fixtures/nonvalid2.yml",
    "content": "route: string\n"
  },
  {
    "path": "Tests/Fixtures/nonvalidkeys.yml",
    "content": "someroute:\n  resource: path/to/some.yml\n  not_valid_key: test_\n"
  },
  {
    "path": "Tests/Fixtures/php_dsl.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes\n        ->collection()\n        ->add('foo', '/foo')\n            ->condition('abc')\n            ->options(['utf8' => true])\n        ->add('buz', 'zub')\n            ->controller('foo:act')\n            ->stateless(true)\n        ->add('controller_class', '/controller')\n            ->controller(['Acme\\MyApp\\MyController', 'myAction']);\n\n    $routes->import('php_dsl_sub.php')\n        ->prefix('/sub')\n        ->requirements(['id' => '\\d+']);\n\n    $routes->import('php_dsl_sub.php')\n        ->namePrefix('z_')\n        ->prefix('/zub');\n\n    $routes->import('php_dsl_sub_root.php')\n        ->prefix('/bus', false);\n\n    $routes->add('ouf', '/ouf')\n        ->schemes(['https'])\n        ->methods(['GET'])\n        ->defaults(['id' => 0]);\n};\n"
  },
  {
    "path": "Tests/Fixtures/php_dsl_i18n.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $routes\n        ->collection()\n        ->prefix(['en' => '/glish'])\n        ->add('foo', '/foo')\n        ->add('bar', ['en' => '/bar']);\n\n    $routes\n        ->add('baz', ['en' => '/baz']);\n\n    $routes->import('php_dsl_sub_i18n.php')\n        ->prefix(['fr' => '/ench']);\n};\n"
  },
  {
    "path": "Tests/Fixtures/php_dsl_sub.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $add = $routes->collection('c_')\n        ->prefix('pub');\n\n    $add('root', '/');\n    $add('bar', '/bar');\n\n    $add->collection('pub_')\n        ->host('host')\n        ->add('buz', 'buz');\n};\n"
  },
  {
    "path": "Tests/Fixtures/php_dsl_sub_i18n.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $add = $routes->collection('c_')\n        ->prefix('pub');\n\n    $add('foo', ['fr' => '/foo']);\n    $add('bar', ['fr' => '/bar']);\n\n    $routes->add('non_localized', '/non-localized');\n};\n"
  },
  {
    "path": "Tests/Fixtures/php_dsl_sub_root.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes) {\n    $add = $routes->collection('r_');\n\n    $add('root', '/');\n    $add('bar', '/bar/');\n};\n"
  },
  {
    "path": "Tests/Fixtures/php_object_dsl.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn new class {\n    public function __invoke(RoutingConfigurator $routes)\n    {\n        $routes\n            ->collection()\n            ->add('foo', '/foo')\n            ->condition('abc')\n            ->options(['utf8' => true])\n            ->add('buz', 'zub')\n            ->controller('foo:act')\n            ->stateless(true)\n            ->add('controller_class', '/controller')\n            ->controller(['Acme\\MyApp\\MyController', 'myAction']);\n\n        $routes->import('php_dsl_sub.php')\n            ->prefix('/sub')\n            ->requirements(['id' => '\\d+']);\n\n        $routes->import('php_dsl_sub.php')\n            ->namePrefix('z_')\n            ->prefix('/zub');\n\n        $routes->import('php_dsl_sub_root.php')\n            ->prefix('/bus', false);\n\n        $routes->add('ouf', '/ouf')\n            ->schemes(['https'])\n            ->methods(['GET'])\n            ->defaults(['id' => 0]);\n    }\n};\n"
  },
  {
    "path": "Tests/Fixtures/psr4-attributes.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes): void {\n    $routes\n        ->import(\n            resource: [\n                'path' => './Psr4Controllers',\n                'namespace' => 'Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers',\n            ],\n            type: 'attribute',\n        )\n        ->prefix('/my-prefix');\n};\n"
  },
  {
    "path": "Tests/Fixtures/psr4-attributes.yaml",
    "content": "my_controllers:\n    resource:\n        path: ./Psr4Controllers\n        namespace: Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\n    type: attribute\n    prefix: /my-prefix\n"
  },
  {
    "path": "Tests/Fixtures/psr4-controllers-redirection/psr4-attributes.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes): void {\n    $routes\n        ->import(\n            resource: [\n                'path' => '../Psr4Controllers',\n                'namespace' => 'Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers',\n            ],\n            type: 'attribute',\n        )\n        ->prefix('/my-prefix');\n};\n"
  },
  {
    "path": "Tests/Fixtures/psr4-controllers-redirection/psr4-attributes.yaml",
    "content": "my_controllers:\n    resource:\n        path: ../Psr4Controllers\n        namespace: Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\n    type: attribute\n    prefix: /my-prefix\n"
  },
  {
    "path": "Tests/Fixtures/psr4-controllers-redirection.php",
    "content": "<?php\n\nnamespace Symfony\\Component\\Routing\\Loader\\Configurator;\n\nreturn function (RoutingConfigurator $routes): void {\n    $routes->import('psr4-controllers-redirection/psr4-attributes.php');\n};\n"
  },
  {
    "path": "Tests/Fixtures/psr4-controllers-redirection.yaml",
    "content": "controllers:\n    resource: psr4-controllers-redirection/psr4-attributes.yaml\n"
  },
  {
    "path": "Tests/Fixtures/requirements_without_placeholder_name.yml",
    "content": "foo:\n    path: '/{foo}'\n    requirements:\n        - '\\d+'\n"
  },
  {
    "path": "Tests/Fixtures/special_route_name.yml",
    "content": "\"#$péß^a|\":\n    path: \"true\"\n"
  },
  {
    "path": "Tests/Fixtures/validpattern.php",
    "content": "<?php\n\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\n$collection = new RouteCollection();\n$collection->add('blog_show', new Route(\n    '/blog/{slug}',\n    ['_controller' => 'MyBlogBundle:Blog:show', '_stateless' => true],\n    ['locale' => '\\w+'],\n    ['compiler_class' => 'RouteCompiler'],\n    '{locale}.example.com',\n    ['https'],\n    ['GET', 'POST', 'put', 'OpTiOnS'],\n    'context.getMethod() == \"GET\"'\n));\n\nreturn $collection;\n"
  },
  {
    "path": "Tests/Fixtures/validpattern.yml",
    "content": "blog_show:\n    path:         /blog/{slug}\n    defaults:     { _controller: \"MyBundle:Blog:show\", _stateless: true }\n    host:         \"{locale}.example.com\"\n    requirements: { 'locale': '\\w+' }\n    methods:      ['GET','POST','put','OpTiOnS']\n    schemes:      ['https']\n    condition:    'context.getMethod() == \"GET\"'\n    options:\n        compiler_class: RouteCompiler\n\nblog_show_inherited:\n    path:      /blog/{slug}\n"
  },
  {
    "path": "Tests/Fixtures/validresource.php",
    "content": "<?php\n\n/** @var \\Symfony\\Component\\Routing\\Loader\\PhpFileLoader $loader */\n/** @var \\Symfony\\Component\\Routing\\RouteCollection $collection */\n$collection = $loader->import('validpattern.php');\n$collection->addDefaults([\n    'foo' => 123,\n]);\n$collection->addRequirements([\n    'foo' => '\\d+',\n]);\n$collection->addOptions([\n    'foo' => 'bar',\n]);\n$collection->setCondition('context.getMethod() == \"POST\"');\n$collection->addPrefix('/prefix');\n\nreturn $collection;\n"
  },
  {
    "path": "Tests/Fixtures/validresource.yml",
    "content": "_blog:\n    resource:     validpattern.yml\n    prefix:       /{foo}\n    defaults:     { 'foo': '123' }\n    requirements: { 'foo': '\\d+' }\n    options:      { 'foo': 'bar' }\n    host:         \"\"\n    condition:    'context.getMethod() == \"POST\"'\n"
  },
  {
    "path": "Tests/Fixtures/when-env.php",
    "content": "<?php\n\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RoutingConfigurator;\n\nreturn static function (RoutingConfigurator $routes): void {\n    if ('some-env' === $routes->env()) {\n        $routes->add('b', '/b');\n        $routes->add('a', '/a2');\n    } elseif ('some-other-env' === $routes->env()) {\n        $routes->add('a', '/a3');\n        $routes->add('c', '/c');\n    }\n\n    $routes->add('a', '/a1');\n};\n"
  },
  {
    "path": "Tests/Fixtures/when-env.yml",
    "content": "when@some-env:\n    a: {path: /a2}\n    b: {path: /b}\n\nwhen@some-other-env:\n    a: {path: /a3}\n    c: {path: /c}\n\na: {path: /a1}\n"
  },
  {
    "path": "Tests/Fixtures/with_define_path_variable.php",
    "content": "<?php\n\n$path = '/1/2/3';\n\nreturn new \\Symfony\\Component\\Routing\\RouteCollection();\n"
  },
  {
    "path": "Tests/Generator/Dumper/CompiledUrlGeneratorDumperTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Generator\\Dumper;\n\nuse PHPUnit\\Framework\\Attributes\\IgnoreDeprecations;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Exception\\RouteCircularReferenceException;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\nuse Symfony\\Component\\Routing\\Generator\\CompiledUrlGenerator;\nuse Symfony\\Component\\Routing\\Generator\\Dumper\\CompiledUrlGeneratorDumper;\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass CompiledUrlGeneratorDumperTest extends TestCase\n{\n    private RouteCollection $routeCollection;\n    private CompiledUrlGeneratorDumper $generatorDumper;\n    private string $testTmpFilepath;\n    private string $largeTestTmpFilepath;\n\n    protected function setUp(): void\n    {\n        $this->routeCollection = new RouteCollection();\n        $this->generatorDumper = new CompiledUrlGeneratorDumper($this->routeCollection);\n        $this->testTmpFilepath = sys_get_temp_dir().'/php_generator.php';\n        $this->largeTestTmpFilepath = sys_get_temp_dir().'/php_generator.large.php';\n        @unlink($this->testTmpFilepath);\n        @unlink($this->largeTestTmpFilepath);\n    }\n\n    protected function tearDown(): void\n    {\n        @unlink($this->testTmpFilepath);\n        @unlink($this->largeTestTmpFilepath);\n    }\n\n    public function testDumpWithRoutes()\n    {\n        $this->routeCollection->add('Test', new Route('/testing/{foo}'));\n        $this->routeCollection->add('Test2', new Route('/testing2'));\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'));\n\n        $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL);\n        $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_URL);\n        $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH);\n        $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);\n        $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);\n        $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);\n        $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);\n    }\n\n    public function testDumpWithSimpleLocalizedRoutes()\n    {\n        $this->routeCollection->add('test', new Route('/foo'));\n        $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test')->setRequirement('_locale', 'en'));\n        $this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl')->setDefault('_canonical_route', 'test')->setRequirement('_locale', 'nl'));\n\n        $code = $this->generatorDumper->dump();\n        file_put_contents($this->testTmpFilepath, $code);\n\n        $context = new RequestContext('/app.php');\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $context, null, 'en');\n\n        $urlWithDefaultLocale = $projectUrlGenerator->generate('test');\n        $urlWithSpecifiedLocale = $projectUrlGenerator->generate('test', ['_locale' => 'nl']);\n        $context->setParameter('_locale', 'en');\n        $urlWithEnglishContext = $projectUrlGenerator->generate('test');\n        $context->setParameter('_locale', 'nl');\n        $urlWithDutchContext = $projectUrlGenerator->generate('test');\n\n        $this->assertEquals('/app.php/testing/is/fun', $urlWithDefaultLocale);\n        $this->assertEquals('/app.php/testen/is/leuk', $urlWithSpecifiedLocale);\n        $this->assertEquals('/app.php/testing/is/fun', $urlWithEnglishContext);\n        $this->assertEquals('/app.php/testen/is/leuk', $urlWithDutchContext);\n\n        // test with full route name\n        $this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test.en'));\n\n        $context->setParameter('_locale', 'de_DE');\n        // test that it fall backs to another route when there is no matching localized route\n        $this->assertEquals('/app.php/foo', $projectUrlGenerator->generate('test'));\n    }\n\n    public function testDumpWithRouteNotFoundLocalizedRoutes()\n    {\n        $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test')->setRequirement('_locale', 'en'));\n\n        $code = $this->generatorDumper->dump();\n        file_put_contents($this->testTmpFilepath, $code);\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'), null, 'pl_PL');\n\n        $this->expectException(RouteNotFoundException::class);\n        $this->expectExceptionMessage('Unable to generate a URL for the named route \"test\" as such route does not exist.');\n\n        $projectUrlGenerator->generate('test');\n    }\n\n    public function testDumpWithFallbackLocaleLocalizedRoutes()\n    {\n        $this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test')->setRequirement('_locale', 'en'));\n        $this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl')->setDefault('_canonical_route', 'test')->setRequirement('_locale', 'nl'));\n        $this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'test')->setRequirement('_locale', 'fr'));\n\n        $code = $this->generatorDumper->dump();\n        file_put_contents($this->testTmpFilepath, $code);\n\n        $context = new RequestContext('/app.php');\n        $context->setParameter('_locale', 'en_GB');\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $context, null, null);\n\n        // test with context _locale\n        $this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test'));\n        // test with parameters _locale\n        $this->assertEquals('/app.php/testen/is/leuk', $projectUrlGenerator->generate('test', ['_locale' => 'nl_BE']));\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'), null, 'fr_CA');\n        // test with default locale\n        $this->assertEquals('/app.php/tester/est/amusant', $projectUrlGenerator->generate('test'));\n    }\n\n    public function testDumpWithTooManyRoutes()\n    {\n        $this->routeCollection->add('Test', new Route('/testing/{foo}'));\n        for ($i = 0; $i < 32769; ++$i) {\n            $this->routeCollection->add('route_'.$i, new Route('/route_'.$i));\n        }\n        $this->routeCollection->add('Test2', new Route('/testing2'));\n\n        file_put_contents($this->largeTestTmpFilepath, $this->generatorDumper->dump());\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->largeTestTmpFilepath, new RequestContext('/app.php'));\n\n        $absoluteUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL);\n        $absoluteUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_URL);\n        $relativeUrlWithParameter = $projectUrlGenerator->generate('Test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH);\n        $relativeUrlWithoutParameter = $projectUrlGenerator->generate('Test2', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('http://localhost/app.php/testing/bar', $absoluteUrlWithParameter);\n        $this->assertEquals('http://localhost/app.php/testing2', $absoluteUrlWithoutParameter);\n        $this->assertEquals('/app.php/testing/bar', $relativeUrlWithParameter);\n        $this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);\n    }\n\n    public function testDumpWithoutRoutes()\n    {\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'));\n\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $projectUrlGenerator->generate('Test', []);\n    }\n\n    public function testGenerateNonExistingRoute()\n    {\n        $this->routeCollection->add('Test', new Route('/test'));\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());\n\n        $this->expectException(RouteNotFoundException::class);\n\n        $projectUrlGenerator->generate('NonExisting', []);\n    }\n\n    public function testDumpForRouteWithDefaults()\n    {\n        $this->routeCollection->add('Test', new Route('/testing/{foo}', ['foo' => 'bar']));\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());\n        $url = $projectUrlGenerator->generate('Test', []);\n\n        $this->assertEquals('/testing', $url);\n    }\n\n    public function testDumpWithSchemeRequirement()\n    {\n        $this->routeCollection->add('Test1', new Route('/testing', [], [], [], '', ['ftp', 'https']));\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php'));\n\n        $absoluteUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_URL);\n        $relativeUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('ftp://localhost/app.php/testing', $absoluteUrl);\n        $this->assertEquals('ftp://localhost/app.php/testing', $relativeUrl);\n\n        $projectUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext('/app.php', 'GET', 'localhost', 'https'));\n\n        $absoluteUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_URL);\n        $relativeUrl = $projectUrlGenerator->generate('Test1', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);\n        $this->assertEquals('/app.php/testing', $relativeUrl);\n    }\n\n    public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl()\n    {\n        $this->routeCollection->add('foo.en', (new Route('/{_locale}/fork'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en'));\n        $this->routeCollection->add('foo.fr', (new Route('/{_locale}/fourchette'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'fr'));\n        $this->routeCollection->add('fun.en', (new Route('/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'fun')->setRequirement('_locale', 'en'));\n        $this->routeCollection->add('fun.fr', (new Route('/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'fun')->setRequirement('_locale', 'fr'));\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $requestContext = new RequestContext();\n        $requestContext->setParameter('_locale', 'fr');\n\n        $compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $requestContext, null, null);\n\n        $this->assertSame('/fr/fourchette', $compiledUrlGenerator->generate('foo'));\n        $this->assertSame('/en/fork', $compiledUrlGenerator->generate('foo.en'));\n        $this->assertSame('/en/fork', $compiledUrlGenerator->generate('foo', ['_locale' => 'en']));\n        $this->assertSame('/fr/fourchette', $compiledUrlGenerator->generate('foo.fr', ['_locale' => 'en']));\n\n        $this->assertSame('/amusant', $compiledUrlGenerator->generate('fun'));\n        $this->assertSame('/fun', $compiledUrlGenerator->generate('fun.en'));\n        $this->assertSame('/fun', $compiledUrlGenerator->generate('fun', ['_locale' => 'en']));\n        $this->assertSame('/amusant', $compiledUrlGenerator->generate('fun.fr', ['_locale' => 'en']));\n    }\n\n    public function testLocalizedAliasRouteGeneratesCorrectUrlPerLocale()\n    {\n        $this->routeCollection->add('foo.en', (new Route('/en/fork'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en'));\n        $this->routeCollection->add('foo.fr', (new Route('/fr/fourchette'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'fr'));\n        $this->routeCollection->addAlias('bar.en', 'foo.en');\n        $this->routeCollection->addAlias('bar.fr', 'foo.fr');\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $requestContext = new RequestContext();\n        $requestContext->setParameter('_locale', 'fr');\n\n        $compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $requestContext, null, null);\n\n        $this->assertSame('/fr/fourchette', $compiledUrlGenerator->generate('bar'));\n        $this->assertSame('/en/fork', $compiledUrlGenerator->generate('bar', ['_locale' => 'en']));\n        $this->assertSame('/fr/fourchette', $compiledUrlGenerator->generate('bar', ['_locale' => 'fr']));\n    }\n\n    public function testAliases()\n    {\n        $subCollection = new RouteCollection();\n        $subCollection->add('a', new Route('/sub'));\n        $subCollection->addAlias('b', 'a');\n        $subCollection->addAlias('c', 'b');\n        $subCollection->addNamePrefix('sub_');\n\n        $this->routeCollection->add('a', new Route('/foo'));\n        $this->routeCollection->addAlias('b', 'a');\n        $this->routeCollection->addAlias('c', 'b');\n        $this->routeCollection->addCollection($subCollection);\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());\n\n        $this->assertSame('/foo', $compiledUrlGenerator->generate('b'));\n        $this->assertSame('/foo', $compiledUrlGenerator->generate('c'));\n        $this->assertSame('/sub', $compiledUrlGenerator->generate('sub_b'));\n        $this->assertSame('/sub', $compiledUrlGenerator->generate('sub_c'));\n    }\n\n    public function testTargetAliasNotExisting()\n    {\n        $this->routeCollection->add('not-existing', new Route('/not-existing'));\n        $this->routeCollection->addAlias('alias', 'not-existing');\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $compiledRoutes = require $this->testTmpFilepath;\n        unset($compiledRoutes['alias']);\n\n        $this->expectException(RouteNotFoundException::class);\n\n        $compiledUrlGenerator = new CompiledUrlGenerator($compiledRoutes, new RequestContext());\n        $compiledUrlGenerator->generate('a');\n    }\n\n    public function testTargetAliasWithNamePrefixNotExisting()\n    {\n        $subCollection = new RouteCollection();\n        $subCollection->add('not-existing', new Route('/not-existing'));\n        $subCollection->addAlias('alias', 'not-existing');\n        $subCollection->addNamePrefix('sub_');\n\n        $this->routeCollection->addCollection($subCollection);\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $compiledRoutes = require $this->testTmpFilepath;\n        unset($compiledRoutes['sub_alias']);\n\n        $this->expectException(RouteNotFoundException::class);\n\n        $compiledUrlGenerator = new CompiledUrlGenerator($compiledRoutes, new RequestContext());\n        $compiledUrlGenerator->generate('sub_alias');\n    }\n\n    public function testCircularReferenceShouldThrowAnException()\n    {\n        $this->routeCollection->addAlias('a', 'b');\n        $this->routeCollection->addAlias('b', 'a');\n\n        $this->expectException(RouteCircularReferenceException::class);\n        $this->expectExceptionMessage('Circular reference detected for route \"b\", path: \"b -> a -> b\".');\n\n        $this->generatorDumper->dump();\n    }\n\n    public function testDeepCircularReferenceShouldThrowAnException()\n    {\n        $this->routeCollection->addAlias('a', 'b');\n        $this->routeCollection->addAlias('b', 'c');\n        $this->routeCollection->addAlias('c', 'b');\n\n        $this->expectException(RouteCircularReferenceException::class);\n        $this->expectExceptionMessage('Circular reference detected for route \"b\", path: \"b -> c -> b\".');\n\n        $this->generatorDumper->dump();\n    }\n\n    public function testIndirectCircularReferenceShouldThrowAnException()\n    {\n        $this->routeCollection->addAlias('a', 'b');\n        $this->routeCollection->addAlias('b', 'c');\n        $this->routeCollection->addAlias('c', 'a');\n\n        $this->expectException(RouteCircularReferenceException::class);\n        $this->expectExceptionMessage('Circular reference detected for route \"b\", path: \"b -> c -> a -> b\".');\n\n        $this->generatorDumper->dump();\n    }\n\n    #[IgnoreDeprecations]\n    public function testDeprecatedAlias()\n    {\n        $this->expectUserDeprecationMessage('Since foo/bar 1.0.0: The \"b\" route alias is deprecated. You should stop using it, as it will be removed in the future.');\n\n        $this->routeCollection->add('a', new Route('/foo'));\n        $this->routeCollection->addAlias('b', 'a')\n            ->setDeprecated('foo/bar', '1.0.0', '');\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());\n\n        $compiledUrlGenerator->generate('b');\n    }\n\n    #[IgnoreDeprecations]\n    public function testDeprecatedAliasWithCustomMessage()\n    {\n        $this->expectUserDeprecationMessage('Since foo/bar 1.0.0: foo b.');\n\n        $this->routeCollection->add('a', new Route('/foo'));\n        $this->routeCollection->addAlias('b', 'a')\n            ->setDeprecated('foo/bar', '1.0.0', 'foo %alias_id%.');\n\n        file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump());\n\n        $compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, new RequestContext());\n\n        $compiledUrlGenerator->generate('b');\n    }\n\n    #[IgnoreDeprecations]\n    public function testTargettingADeprecatedAliasShouldTriggerDeprecation()\n    {\n        $this->expectUserDeprecationMessage('Since foo/bar 1.0.0: foo b.');\n\n        $this->routeCollection->add('a', new Route('/foo'));\n        $this->routeCollection->addAlias('b', 'a')\n            ->setDeprecated('foo/bar', '1.0.0', 'foo %alias_id%.');\n        $this->routeCollection->addAlias('c', 'b');\n\n        $this->generatorDumper->dump();\n    }\n}\n"
  },
  {
    "path": "Tests/Generator/UrlGeneratorTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Generator;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\IgnoreDeprecations;\nuse PHPUnit\\Framework\\TestCase;\nuse Psr\\Log\\LoggerInterface;\nuse Symfony\\Component\\Routing\\Exception\\InvalidParameterException;\nuse Symfony\\Component\\Routing\\Exception\\MissingMandatoryParametersException;\nuse Symfony\\Component\\Routing\\Exception\\RouteCircularReferenceException;\nuse Symfony\\Component\\Routing\\Exception\\RouteNotFoundException;\nuse Symfony\\Component\\Routing\\Generator\\UrlGenerator;\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass UrlGeneratorTest extends TestCase\n{\n    public function testAbsoluteUrlWithPort80()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);\n\n        $this->assertEquals('http://localhost/app.php/testing', $url);\n    }\n\n    public function testAbsoluteSecureUrlWithPort443()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes, ['scheme' => 'https'])->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);\n\n        $this->assertEquals('https://localhost/app.php/testing', $url);\n    }\n\n    public function testAbsoluteUrlWithNonStandardPort()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes, ['httpPort' => 8080])->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);\n\n        $this->assertEquals('http://localhost:8080/app.php/testing', $url);\n    }\n\n    public function testAbsoluteSecureUrlWithNonStandardPort()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes, ['httpsPort' => 8080, 'scheme' => 'https'])->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);\n\n        $this->assertEquals('https://localhost:8080/app.php/testing', $url);\n    }\n\n    public function testRelativeUrlWithoutParameters()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('/app.php/testing', $url);\n    }\n\n    public function testRelativeUrlWithParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}'));\n        $url = $this->getGenerator($routes)->generate('test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('/app.php/testing/bar', $url);\n    }\n\n    public function testRelativeUrlWithNullParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing.{format}', ['format' => null]));\n        $url = $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('/app.php/testing', $url);\n    }\n\n    public function testRelativeUrlWithNullParameterButNotOptional()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}/bar', ['foo' => null]));\n\n        $this->expectException(InvalidParameterException::class);\n\n        // This must raise an exception because the default requirement for \"foo\" is \"[^/]+\" which is not met with these params.\n        // Generating path \"/testing//bar\" would be wrong as matching this route would fail.\n        $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n    }\n\n    public function testRelativeUrlWithOptionalZeroParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{page}'));\n        $url = $this->getGenerator($routes)->generate('test', ['page' => 0], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('/app.php/testing/0', $url);\n    }\n\n    public function testNotPassedOptionalParameterInBetween()\n    {\n        $routes = $this->getRoutes('test', new Route('/{slug}/{page}', ['slug' => 'index', 'page' => 0]));\n        $this->assertSame('/app.php/index/1', $this->getGenerator($routes)->generate('test', ['page' => 1]));\n        $this->assertSame('/app.php/', $this->getGenerator($routes)->generate('test'));\n    }\n\n    #[DataProvider('valuesProvider')]\n    public function testRelativeUrlWithExtraParameters(string $expectedQueryString, string $parameter, $value)\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes)->generate('test', [$parameter => $value], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertSame('/app.php/testing'.$expectedQueryString, $url);\n    }\n\n    #[DataProvider('valuesProvider')]\n    public function testAbsoluteUrlWithExtraParameters(string $expectedQueryString, string $parameter, $value)\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes)->generate('test', [$parameter => $value], UrlGeneratorInterface::ABSOLUTE_URL);\n\n        $this->assertSame('http://localhost/app.php/testing'.$expectedQueryString, $url);\n    }\n\n    public static function valuesProvider(): array\n    {\n        $stdClass = new \\stdClass();\n        $stdClass->baz = 'bar';\n\n        $nestedStdClass = new \\stdClass();\n        $nestedStdClass->nested = $stdClass;\n\n        return [\n            'null' => ['', 'foo', null],\n            'string' => ['?foo=bar', 'foo', 'bar'],\n            'boolean-false' => ['?foo=0', 'foo', false],\n            'boolean-true' => ['?foo=1', 'foo', true],\n            'object implementing __toString()' => ['?foo=bar', 'foo', new StringableObject()],\n            'object implementing __toString() but has public property' => ['?foo%5Bfoo%5D=property', 'foo', new StringableObjectWithPublicProperty()],\n            'object implementing __toString() in nested array' => ['?foo%5Bbaz%5D=bar', 'foo', ['baz' => new StringableObject()]],\n            'object implementing __toString() in nested array but has public property' => ['?foo%5Bbaz%5D%5Bfoo%5D=property', 'foo', ['baz' => new StringableObjectWithPublicProperty()]],\n            'stdClass' => ['?foo%5Bbaz%5D=bar', 'foo', $stdClass],\n            'stdClass in nested stdClass' => ['?foo%5Bnested%5D%5Bbaz%5D=bar', 'foo', $nestedStdClass],\n            'non stringable object' => ['', 'foo', new NonStringableObject()],\n            'non stringable object but has public property' => ['?foo%5Bfoo%5D=property', 'foo', new NonStringableObjectWithPublicProperty()],\n            'numeric key' => ['?123=foo', '123', 'foo'],\n        ];\n    }\n\n    public function testUrlWithExtraParametersFromGlobals()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $generator = $this->getGenerator($routes);\n        $context = new RequestContext('/app.php');\n        $context->setParameter('bar', 'bar');\n        $generator->setContext($context);\n        $url = $generator->generate('test', ['foo' => 'bar']);\n\n        $this->assertEquals('/app.php/testing?foo=bar', $url);\n    }\n\n    public function testUrlWithGlobalParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}'));\n        $generator = $this->getGenerator($routes);\n        $context = new RequestContext('/app.php');\n        $context->setParameter('foo', 'bar');\n        $generator->setContext($context);\n        $url = $generator->generate('test', []);\n\n        $this->assertEquals('/app.php/testing/bar', $url);\n    }\n\n    public function testGlobalParameterHasHigherPriorityThanDefault()\n    {\n        $routes = $this->getRoutes('test', new Route('/{_locale}', ['_locale' => 'en']));\n        $generator = $this->getGenerator($routes);\n        $context = new RequestContext('/app.php');\n        $context->setParameter('_locale', 'de');\n        $generator->setContext($context);\n        $url = $generator->generate('test', []);\n\n        $this->assertSame('/app.php/de', $url);\n    }\n\n    public function testGenerateWithDefaultLocale()\n    {\n        $routes = new RouteCollection();\n\n        $route = new Route('');\n\n        $name = 'test';\n\n        foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {\n            $localizedRoute = clone $route;\n            $localizedRoute->setDefault('_locale', $locale);\n            $localizedRoute->setRequirement('_locale', $locale);\n            $localizedRoute->setDefault('_canonical_route', $name);\n            $localizedRoute->setPath($path);\n            $routes->add($name.'.'.$locale, $localizedRoute);\n        }\n\n        $generator = $this->getGenerator($routes, [], null, 'hr');\n\n        $this->assertSame(\n            'http://localhost/app.php/foo',\n            $generator->generate($name, [], UrlGeneratorInterface::ABSOLUTE_URL)\n        );\n    }\n\n    public function testGenerateWithOverriddenParameterLocale()\n    {\n        $routes = new RouteCollection();\n\n        $route = new Route('');\n\n        $name = 'test';\n\n        foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {\n            $localizedRoute = clone $route;\n            $localizedRoute->setDefault('_locale', $locale);\n            $localizedRoute->setRequirement('_locale', $locale);\n            $localizedRoute->setDefault('_canonical_route', $name);\n            $localizedRoute->setPath($path);\n            $routes->add($name.'.'.$locale, $localizedRoute);\n        }\n\n        $generator = $this->getGenerator($routes, [], null, 'hr');\n\n        $this->assertSame(\n            'http://localhost/app.php/bar',\n            $generator->generate($name, ['_locale' => 'en'], UrlGeneratorInterface::ABSOLUTE_URL)\n        );\n    }\n\n    public function testGenerateWithOverriddenParameterLocaleFromRequestContext()\n    {\n        $routes = new RouteCollection();\n\n        $route = new Route('');\n\n        $name = 'test';\n\n        foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {\n            $localizedRoute = clone $route;\n            $localizedRoute->setDefault('_locale', $locale);\n            $localizedRoute->setRequirement('_locale', $locale);\n            $localizedRoute->setDefault('_canonical_route', $name);\n            $localizedRoute->setPath($path);\n            $routes->add($name.'.'.$locale, $localizedRoute);\n        }\n\n        $generator = $this->getGenerator($routes, [], null, 'hr');\n\n        $context = new RequestContext('/app.php');\n        $context->setParameter('_locale', 'en');\n        $generator->setContext($context);\n\n        $this->assertSame(\n            'http://localhost/app.php/bar',\n            $generator->generate($name, [], UrlGeneratorInterface::ABSOLUTE_URL)\n        );\n    }\n\n    public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl()\n    {\n        $routeCollection = new RouteCollection();\n\n        $routeCollection->add('foo.en', (new Route('/{_locale}/fork'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en'));\n        $routeCollection->add('foo.fr', (new Route('/{_locale}/fourchette'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'fr'));\n        $routeCollection->add('fun.en', (new Route('/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'fun')->setRequirement('_locale', 'en'));\n        $routeCollection->add('fun.fr', (new Route('/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'fun')->setRequirement('_locale', 'fr'));\n\n        $urlGenerator = $this->getGenerator($routeCollection);\n        $urlGenerator->getContext()->setParameter('_locale', 'fr');\n\n        $this->assertSame('/app.php/fr/fourchette', $urlGenerator->generate('foo'));\n        $this->assertSame('/app.php/en/fork', $urlGenerator->generate('foo.en'));\n        $this->assertSame('/app.php/en/fork', $urlGenerator->generate('foo', ['_locale' => 'en']));\n        $this->assertSame('/app.php/fr/fourchette', $urlGenerator->generate('foo.fr', ['_locale' => 'en']));\n\n        $this->assertSame('/app.php/amusant', $urlGenerator->generate('fun'));\n        $this->assertSame('/app.php/fun', $urlGenerator->generate('fun.en'));\n        $this->assertSame('/app.php/fun', $urlGenerator->generate('fun', ['_locale' => 'en']));\n        $this->assertSame('/app.php/amusant', $urlGenerator->generate('fun.fr', ['_locale' => 'en']));\n    }\n\n    public function testLocalizedAliasRouteGeneratesCorrectUrlPerLocale()\n    {\n        $routeCollection = new RouteCollection();\n\n        $routeCollection->add('foo.en', (new Route('/en/fork'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en'));\n        $routeCollection->add('foo.fr', (new Route('/fr/fourchette'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'fr'));\n        $routeCollection->addAlias('bar.en', 'foo.en');\n        $routeCollection->addAlias('bar.fr', 'foo.fr');\n\n        $urlGenerator = $this->getGenerator($routeCollection);\n        $urlGenerator->getContext()->setParameter('_locale', 'fr');\n\n        $this->assertSame('/app.php/fr/fourchette', $urlGenerator->generate('bar'));\n        $this->assertSame('/app.php/en/fork', $urlGenerator->generate('bar', ['_locale' => 'en']));\n        $this->assertSame('/app.php/fr/fourchette', $urlGenerator->generate('bar', ['_locale' => 'fr']));\n    }\n\n    public function testGenerateWithoutRoutes()\n    {\n        $routes = $this->getRoutes('foo', new Route('/testing/{foo}'));\n\n        $this->expectException(RouteNotFoundException::class);\n\n        $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n\n    public function testGenerateWithInvalidLocale()\n    {\n        $routes = new RouteCollection();\n        $route = new Route('');\n        $name = 'test';\n\n        foreach (['hr' => '/foo', 'en' => '/bar'] as $locale => $path) {\n            $localizedRoute = clone $route;\n            $localizedRoute->setDefault('_locale', $locale);\n            $localizedRoute->setRequirement('_locale', $locale);\n            $localizedRoute->setDefault('_canonical_route', $name);\n            $localizedRoute->setPath($path);\n            $routes->add($name.'.'.$locale, $localizedRoute);\n        }\n\n        $generator = $this->getGenerator($routes, [], null, 'fr');\n\n        $this->expectException(RouteNotFoundException::class);\n\n        $generator->generate($name);\n    }\n\n    public function testGenerateForRouteWithoutMandatoryParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}'));\n\n        $this->expectException(MissingMandatoryParametersException::class);\n        $this->expectExceptionMessage('Some mandatory parameters are missing (\"foo\") to generate a URL for route \"test\".');\n\n        $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n\n    public function testGenerateForRouteWithInvalidOptionalParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', ['foo' => '1'], ['foo' => 'd+']));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n\n    public function testGenerateForRouteWithInvalidParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', [], ['foo' => '1|2']));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => '0'], UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n\n    public function testGenerateForRouteWithInvalidOptionalParameterNonStrict()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', ['foo' => '1'], ['foo' => 'd+']));\n        $generator = $this->getGenerator($routes);\n        $generator->setStrictRequirements(false);\n        $this->assertSame('', $generator->generate('test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testGenerateForRouteWithInvalidOptionalParameterNonStrictWithLogger()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', ['foo' => '1'], ['foo' => 'd+']));\n        $logger = $this->createMock(LoggerInterface::class);\n        $logger->expects($this->once())\n            ->method('error');\n        $generator = $this->getGenerator($routes, [], $logger);\n        $generator->setStrictRequirements(false);\n        $this->assertSame('', $generator->generate('test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testGenerateForRouteWithInvalidParameterButDisabledRequirementsCheck()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', ['foo' => '1'], ['foo' => 'd+']));\n        $generator = $this->getGenerator($routes);\n        $generator->setStrictRequirements(null);\n        $this->assertSame('/app.php/testing/bar', $generator->generate('test', ['foo' => 'bar']));\n    }\n\n    public function testGenerateForRouteWithInvalidMandatoryParameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', [], ['foo' => 'd+']));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => 'bar'], UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n\n    public function testGenerateForRouteWithInvalidUtf8Parameter()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing/{foo}', [], ['foo' => '\\pL+'], ['utf8' => true]));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => 'abc123'], UrlGeneratorInterface::ABSOLUTE_URL);\n    }\n\n    public function testRequiredParamAndEmptyPassed()\n    {\n        $routes = $this->getRoutes('test', new Route('/{slug}', [], ['slug' => '.+']));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['slug' => '']);\n    }\n\n    public function testSchemeRequirementDoesNothingIfSameCurrentScheme()\n    {\n        $routes = $this->getRoutes('test', new Route('/', [], [], [], '', ['http']));\n        $this->assertEquals('/app.php/', $this->getGenerator($routes)->generate('test'));\n\n        $routes = $this->getRoutes('test', new Route('/', [], [], [], '', ['https']));\n        $this->assertEquals('/app.php/', $this->getGenerator($routes, ['scheme' => 'https'])->generate('test'));\n    }\n\n    public function testSchemeRequirementForcesAbsoluteUrl()\n    {\n        $routes = $this->getRoutes('test', new Route('/', [], [], [], '', ['https']));\n        $this->assertEquals('https://localhost/app.php/', $this->getGenerator($routes)->generate('test'));\n\n        $routes = $this->getRoutes('test', new Route('/', [], [], [], '', ['http']));\n        $this->assertEquals('http://localhost/app.php/', $this->getGenerator($routes, ['scheme' => 'https'])->generate('test'));\n    }\n\n    public function testSchemeRequirementCreatesUrlForFirstRequiredScheme()\n    {\n        $routes = $this->getRoutes('test', new Route('/', [], [], [], '', ['Ftp', 'https']));\n        $this->assertEquals('ftp://localhost/app.php/', $this->getGenerator($routes)->generate('test'));\n    }\n\n    public function testPathWithTwoStartingSlashes()\n    {\n        $routes = $this->getRoutes('test', new Route('//path-and-not-domain'));\n\n        // this must not generate '//path-and-not-domain' because that would be a network path\n        $this->assertSame('/path-and-not-domain', $this->getGenerator($routes, ['BaseUrl' => ''])->generate('test'));\n    }\n\n    public function testNoTrailingSlashForMultipleOptionalParameters()\n    {\n        $routes = $this->getRoutes('test', new Route('/category/{slug1}/{slug2}/{slug3}', ['slug2' => null, 'slug3' => null]));\n\n        $this->assertEquals('/app.php/category/foo', $this->getGenerator($routes)->generate('test', ['slug1' => 'foo']));\n    }\n\n    public function testWithAnIntegerAsADefaultValue()\n    {\n        $routes = $this->getRoutes('test', new Route('/{default}', ['default' => 0]));\n\n        $this->assertEquals('/app.php/foo', $this->getGenerator($routes)->generate('test', ['default' => 'foo']));\n    }\n\n    public function testNullForOptionalParameterIsIgnored()\n    {\n        $routes = $this->getRoutes('test', new Route('/test/{default}', ['default' => 0]));\n\n        $this->assertEquals('/app.php/test', $this->getGenerator($routes)->generate('test', ['default' => null]));\n    }\n\n    public function testQueryParamSameAsDefault()\n    {\n        $routes = $this->getRoutes('test', new Route('/test', ['page' => 1]));\n\n        $this->assertSame('/app.php/test?page=2', $this->getGenerator($routes)->generate('test', ['page' => 2]));\n        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', ['page' => 1]));\n        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', ['page' => '1']));\n        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));\n    }\n\n    public function testArrayQueryParamSameAsDefault()\n    {\n        $routes = $this->getRoutes('test', new Route('/test', ['array' => ['foo', 'bar']]));\n\n        $this->assertSame('/app.php/test?array%5B0%5D=bar&array%5B1%5D=foo', $this->getGenerator($routes)->generate('test', ['array' => ['bar', 'foo']]));\n        $this->assertSame('/app.php/test?array%5Ba%5D=foo&array%5Bb%5D=bar', $this->getGenerator($routes)->generate('test', ['array' => ['a' => 'foo', 'b' => 'bar']]));\n        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', ['array' => ['foo', 'bar']]));\n        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test', ['array' => [1 => 'bar', 0 => 'foo']]));\n        $this->assertSame('/app.php/test', $this->getGenerator($routes)->generate('test'));\n    }\n\n    public function testGenerateWithSpecialRouteName()\n    {\n        $routes = $this->getRoutes('$péß^a|', new Route('/bar'));\n\n        $this->assertSame('/app.php/bar', $this->getGenerator($routes)->generate('$péß^a|'));\n    }\n\n    public function testUrlEncoding()\n    {\n        $expectedPath = '/app.php/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'\n            .'/@:%5B%5D/%28%29*%27%22%20+,;-._~%26%24%3C%3E|%7B%7D%25%5C%5E%60!%3Ffoo=bar%23id'\n            .'?query=@:%5B%5D/%28%29*%27%22%20%2B,;-._~%26%24%3C%3E%7C%7B%7D%25%5C%5E%60!?foo%3Dbar%23id';\n\n        // This tests the encoding of reserved characters that are used for delimiting of URI components (defined in RFC 3986)\n        // and other special ASCII chars. These chars are tested as static text path, variable path and query param.\n        $chars = '@:[]/()*\\'\" +,;-._~&$<>|{}%\\\\^`!?foo=bar#id';\n        $routes = $this->getRoutes('test', new Route(\"/$chars/{varpath}\", [], ['varpath' => '.+']));\n        $this->assertSame($expectedPath, $this->getGenerator($routes)->generate('test', [\n            'varpath' => $chars,\n            'query' => $chars,\n        ]));\n    }\n\n    public function testEncodingOfRelativePathSegments()\n    {\n        $routes = $this->getRoutes('test', new Route('/dir/../dir/..'));\n        $this->assertSame('/app.php/dir/%2E%2E/dir/%2E%2E', $this->getGenerator($routes)->generate('test'));\n        $routes = $this->getRoutes('test', new Route('/dir/./dir/.'));\n        $this->assertSame('/app.php/dir/%2E/dir/%2E', $this->getGenerator($routes)->generate('test'));\n        $routes = $this->getRoutes('test', new Route('/a./.a/a../..a/...'));\n        $this->assertSame('/app.php/a./.a/a../..a/...', $this->getGenerator($routes)->generate('test'));\n    }\n\n    public function testEncodingOfSlashInPath()\n    {\n        $routes = $this->getRoutes('test', new Route('/dir/{path}/dir2', [], ['path' => '.+']));\n        $this->assertSame('/app.php/dir/foo/bar%2Fbaz/dir2', $this->getGenerator($routes)->generate('test', ['path' => 'foo/bar%2Fbaz']));\n    }\n\n    public function testEncodingOfSlashInQueryParameters()\n    {\n        $routes = $this->getRoutes('test', new Route('/get'));\n        $this->assertSame('/app.php/get?query=foo/bar', $this->getGenerator($routes)->generate('test', ['query' => 'foo/bar']));\n        $this->assertSame('/app.php/get?query=foo%2Fbar', $this->getGenerator($routes)->generate('test', ['query' => 'foo%2Fbar']));\n    }\n\n    public function testAdjacentVariables()\n    {\n        $routes = $this->getRoutes('test', new Route('/{x}{y}{z}.{_format}', ['z' => 'default-z', '_format' => 'html'], ['y' => '\\d+']));\n        $generator = $this->getGenerator($routes);\n        $this->assertSame('/app.php/foo123', $generator->generate('test', ['x' => 'foo', 'y' => '123']));\n        $this->assertSame('/app.php/foo123bar.xml', $generator->generate('test', ['x' => 'foo', 'y' => '123', 'z' => 'bar', '_format' => 'xml']));\n\n        // The default requirement for 'x' should not allow the separator '.' in this case because it would otherwise match everything\n        // and following optional variables like _format could never match.\n        $this->expectException(InvalidParameterException::class);\n        $generator->generate('test', ['x' => 'do.t', 'y' => '123', 'z' => 'bar', '_format' => 'xml']);\n    }\n\n    public function testOptionalVariableWithNoRealSeparator()\n    {\n        $routes = $this->getRoutes('test', new Route('/get{what}', ['what' => 'All']));\n        $generator = $this->getGenerator($routes);\n\n        $this->assertSame('/app.php/get', $generator->generate('test'));\n        $this->assertSame('/app.php/getSites', $generator->generate('test', ['what' => 'Sites']));\n    }\n\n    public function testRequiredVariableWithNoRealSeparator()\n    {\n        $routes = $this->getRoutes('test', new Route('/get{what}Suffix'));\n        $generator = $this->getGenerator($routes);\n\n        $this->assertSame('/app.php/getSitesSuffix', $generator->generate('test', ['what' => 'Sites']));\n    }\n\n    public function testDefaultRequirementOfVariable()\n    {\n        $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));\n        $generator = $this->getGenerator($routes);\n\n        $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', ['page' => 'index', '_format' => 'mobile.html']));\n    }\n\n    public function testImportantVariable()\n    {\n        $routes = $this->getRoutes('test', (new Route('/{page}.{!_format}'))->addDefaults(['_format' => 'mobile.html']));\n        $generator = $this->getGenerator($routes);\n\n        $this->assertSame('/app.php/index.xml', $generator->generate('test', ['page' => 'index', '_format' => 'xml']));\n        $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', ['page' => 'index', '_format' => 'mobile.html']));\n        $this->assertSame('/app.php/index.mobile.html', $generator->generate('test', ['page' => 'index']));\n    }\n\n    public function testImportantVariableWithNoDefault()\n    {\n        $routes = $this->getRoutes('test', new Route('/{page}.{!_format}'));\n        $generator = $this->getGenerator($routes);\n\n        $this->expectException(MissingMandatoryParametersException::class);\n        $this->expectExceptionMessage('Some mandatory parameters are missing (\"_format\") to generate a URL for route \"test\".');\n\n        $generator->generate('test', ['page' => 'index']);\n    }\n\n    public function testDefaultRequirementOfVariableDisallowsSlash()\n    {\n        $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['page' => 'index', '_format' => 'sl/ash']);\n    }\n\n    public function testDefaultRequirementOfVariableDisallowsNextSeparator()\n    {\n        $routes = $this->getRoutes('test', new Route('/{page}.{_format}'));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['page' => 'do.t', '_format' => 'html']);\n    }\n\n    public function testWithHostDifferentFromContext()\n    {\n        $routes = $this->getRoutes('test', new Route('/{name}', [], [], [], '{locale}.example.com'));\n\n        $this->assertEquals('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test', ['name' => 'Fabien', 'locale' => 'fr']));\n    }\n\n    public function testWithHostSameAsContext()\n    {\n        $routes = $this->getRoutes('test', new Route('/{name}', [], [], [], '{locale}.example.com'));\n\n        $this->assertEquals('/app.php/Fabien', $this->getGenerator($routes, ['host' => 'fr.example.com'])->generate('test', ['name' => 'Fabien', 'locale' => 'fr']));\n    }\n\n    public function testWithHostSameAsContextAndAbsolute()\n    {\n        $routes = $this->getRoutes('test', new Route('/{name}', [], [], [], '{locale}.example.com'));\n\n        $this->assertEquals('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, ['host' => 'fr.example.com'])->generate('test', ['name' => 'Fabien', 'locale' => 'fr'], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testUrlWithInvalidParameterInHost()\n    {\n        $routes = $this->getRoutes('test', new Route('/', [], ['foo' => 'bar'], [], '{foo}.example.com'));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => 'baz'], UrlGeneratorInterface::ABSOLUTE_PATH);\n    }\n\n    public function testUrlWithInvalidParameterInHostWhenParamHasADefaultValue()\n    {\n        $routes = $this->getRoutes('test', new Route('/', ['foo' => 'bar'], ['foo' => 'bar'], [], '{foo}.example.com'));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => 'baz'], UrlGeneratorInterface::ABSOLUTE_PATH);\n    }\n\n    public function testUrlWithInvalidParameterEqualsDefaultValueInHost()\n    {\n        $routes = $this->getRoutes('test', new Route('/', ['foo' => 'baz'], ['foo' => 'bar'], [], '{foo}.example.com'));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('test', ['foo' => 'baz'], UrlGeneratorInterface::ABSOLUTE_PATH);\n    }\n\n    public function testUrlWithInvalidParameterInHostInNonStrictMode()\n    {\n        $routes = $this->getRoutes('test', new Route('/', [], ['foo' => 'bar'], [], '{foo}.example.com'));\n        $generator = $this->getGenerator($routes);\n        $generator->setStrictRequirements(false);\n        $this->assertSame('', $generator->generate('test', ['foo' => 'baz'], UrlGeneratorInterface::ABSOLUTE_PATH));\n    }\n\n    public function testHostIsCaseInsensitive()\n    {\n        $routes = $this->getRoutes('test', new Route('/', [], ['locale' => 'en|de|fr'], [], '{locale}.FooBar.com'));\n        $generator = $this->getGenerator($routes);\n        $this->assertSame('//EN.FooBar.com/app.php/', $generator->generate('test', ['locale' => 'EN'], UrlGeneratorInterface::NETWORK_PATH));\n    }\n\n    public function testDefaultHostIsUsedWhenContextHostIsEmpty()\n    {\n        $routes = $this->getRoutes('test', new Route('/path', ['domain' => 'my.fallback.host'], ['domain' => '.+'], [], '{domain}'));\n\n        $generator = $this->getGenerator($routes);\n        $generator->getContext()->setHost('');\n\n        $this->assertSame('http://my.fallback.host/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testDefaultHostIsUsedWhenContextHostIsEmptyAndPathReferenceType()\n    {\n        $routes = $this->getRoutes('test', new Route('/path', ['domain' => 'my.fallback.host'], ['domain' => '.+'], [], '{domain}'));\n\n        $generator = $this->getGenerator($routes);\n        $generator->getContext()->setHost('');\n\n        $this->assertSame('//my.fallback.host/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_PATH));\n    }\n\n    public function testAbsoluteUrlFallbackToPathIfHostIsEmptyAndSchemeIsHttp()\n    {\n        $routes = $this->getRoutes('test', new Route('/route'));\n\n        $generator = $this->getGenerator($routes);\n        $generator->getContext()->setHost('');\n        $generator->getContext()->setScheme('https');\n\n        $this->assertSame('/app.php/route', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testAbsoluteUrlFallbackToNetworkIfSchemeIsEmptyAndHostIsNot()\n    {\n        $routes = $this->getRoutes('test', new Route('/path'));\n\n        $generator = $this->getGenerator($routes);\n        $generator->getContext()->setHost('example.com');\n        $generator->getContext()->setScheme('');\n\n        $this->assertSame('//example.com/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testAbsoluteUrlFallbackToPathIfSchemeAndHostAreEmpty()\n    {\n        $routes = $this->getRoutes('test', new Route('/path'));\n\n        $generator = $this->getGenerator($routes);\n        $generator->getContext()->setHost('');\n        $generator->getContext()->setScheme('');\n\n        $this->assertSame('/app.php/path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testAbsoluteUrlWithNonHttpSchemeAndEmptyHost()\n    {\n        $routes = $this->getRoutes('test', new Route('/path', [], [], [], '', ['file']));\n\n        $generator = $this->getGenerator($routes);\n        $generator->getContext()->setBaseUrl('');\n        $generator->getContext()->setHost('');\n\n        $this->assertSame('file:///path', $generator->generate('test', [], UrlGeneratorInterface::ABSOLUTE_URL));\n    }\n\n    public function testGenerateNetworkPath()\n    {\n        $routes = $this->getRoutes('test', new Route('/{name}', [], [], [], '{locale}.example.com', ['http']));\n\n        $this->assertSame('//fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',\n            ['name' => 'Fabien', 'locale' => 'fr'], UrlGeneratorInterface::NETWORK_PATH), 'network path with different host'\n        );\n        $this->assertSame('//fr.example.com/app.php/Fabien?query=string', $this->getGenerator($routes, ['host' => 'fr.example.com'])->generate('test',\n            ['name' => 'Fabien', 'locale' => 'fr', 'query' => 'string'], UrlGeneratorInterface::NETWORK_PATH), 'network path although host same as context'\n        );\n        $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes, ['scheme' => 'https'])->generate('test',\n            ['name' => 'Fabien', 'locale' => 'fr'], UrlGeneratorInterface::NETWORK_PATH), 'absolute URL because scheme requirement does not match context'\n        );\n        $this->assertSame('http://fr.example.com/app.php/Fabien', $this->getGenerator($routes)->generate('test',\n            ['name' => 'Fabien', 'locale' => 'fr'], UrlGeneratorInterface::ABSOLUTE_URL), 'absolute URL with same scheme because it is requested'\n        );\n    }\n\n    public function testGenerateRelativePath()\n    {\n        $routes = new RouteCollection();\n        $routes->add('article', new Route('/{author}/{article}/'));\n        $routes->add('comments', new Route('/{author}/{article}/comments'));\n        $routes->add('host', new Route('/{article}', [], [], [], '{author}.example.com'));\n        $routes->add('scheme', new Route('/{author}/blog', [], [], [], '', ['https']));\n        $routes->add('unrelated', new Route('/about'));\n\n        $generator = $this->getGenerator($routes, ['host' => 'example.com', 'pathInfo' => '/fabien/symfony-is-great/']);\n\n        $this->assertSame('comments', $generator->generate('comments',\n            ['author' => 'fabien', 'article' => 'symfony-is-great'], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n        $this->assertSame('comments?page=2', $generator->generate('comments',\n            ['author' => 'fabien', 'article' => 'symfony-is-great', 'page' => 2], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n        $this->assertSame('../twig-is-great/', $generator->generate('article',\n            ['author' => 'fabien', 'article' => 'twig-is-great'], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n        $this->assertSame('../../bernhard/forms-are-great/', $generator->generate('article',\n            ['author' => 'bernhard', 'article' => 'forms-are-great'], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n        $this->assertSame('//bernhard.example.com/app.php/forms-are-great', $generator->generate('host',\n            ['author' => 'bernhard', 'article' => 'forms-are-great'], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n        $this->assertSame('https://example.com/app.php/bernhard/blog', $generator->generate('scheme',\n            ['author' => 'bernhard'], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n        $this->assertSame('../../about', $generator->generate('unrelated',\n            [], UrlGeneratorInterface::RELATIVE_PATH)\n        );\n    }\n\n    public function testAliases()\n    {\n        $routes = new RouteCollection();\n        $routes->add('a', new Route('/foo'));\n        $routes->addAlias('b', 'a');\n        $routes->addAlias('c', 'b');\n\n        $generator = $this->getGenerator($routes);\n\n        $this->assertSame('/app.php/foo', $generator->generate('b'));\n        $this->assertSame('/app.php/foo', $generator->generate('c'));\n    }\n\n    public function testAliasWhichTargetRouteDoesntExist()\n    {\n        $routes = new RouteCollection();\n        $routes->addAlias('d', 'non-existent');\n\n        $this->expectException(RouteNotFoundException::class);\n\n        $this->getGenerator($routes)->generate('d');\n    }\n\n    #[IgnoreDeprecations]\n    public function testDeprecatedAlias()\n    {\n        $this->expectUserDeprecationMessage('Since foo/bar 1.0.0: The \"b\" route alias is deprecated. You should stop using it, as it will be removed in the future.');\n\n        $routes = new RouteCollection();\n        $routes->add('a', new Route('/foo'));\n        $routes->addAlias('b', 'a')\n            ->setDeprecated('foo/bar', '1.0.0', '');\n\n        $this->getGenerator($routes)->generate('b');\n    }\n\n    #[IgnoreDeprecations]\n    public function testDeprecatedAliasWithCustomMessage()\n    {\n        $this->expectUserDeprecationMessage('Since foo/bar 1.0.0: foo b.');\n\n        $routes = new RouteCollection();\n        $routes->add('a', new Route('/foo'));\n        $routes->addAlias('b', 'a')\n            ->setDeprecated('foo/bar', '1.0.0', 'foo %alias_id%.');\n\n        $this->getGenerator($routes)->generate('b');\n    }\n\n    #[IgnoreDeprecations]\n    public function testTargettingADeprecatedAliasShouldTriggerDeprecation()\n    {\n        $this->expectUserDeprecationMessage('Since foo/bar 1.0.0: foo b.');\n\n        $routes = new RouteCollection();\n        $routes->add('a', new Route('/foo'));\n        $routes->addAlias('b', 'a')\n            ->setDeprecated('foo/bar', '1.0.0', 'foo %alias_id%.');\n        $routes->addAlias('c', 'b');\n\n        $this->getGenerator($routes)->generate('c');\n    }\n\n    public function testCircularReferenceShouldThrowAnException()\n    {\n        $routes = new RouteCollection();\n        $routes->addAlias('a', 'b');\n        $routes->addAlias('b', 'a');\n\n        $this->expectException(RouteCircularReferenceException::class);\n        $this->expectExceptionMessage('Circular reference detected for route \"b\", path: \"b -> a -> b\".');\n\n        $this->getGenerator($routes)->generate('b');\n    }\n\n    public function testDeepCircularReferenceShouldThrowAnException()\n    {\n        $routes = new RouteCollection();\n        $routes->addAlias('a', 'b');\n        $routes->addAlias('b', 'c');\n        $routes->addAlias('c', 'b');\n\n        $this->expectException(RouteCircularReferenceException::class);\n        $this->expectExceptionMessage('Circular reference detected for route \"b\", path: \"b -> c -> b\".');\n\n        $this->getGenerator($routes)->generate('b');\n    }\n\n    public function testIndirectCircularReferenceShouldThrowAnException()\n    {\n        $routes = new RouteCollection();\n        $routes->addAlias('a', 'b');\n        $routes->addAlias('b', 'c');\n        $routes->addAlias('c', 'a');\n\n        $this->expectException(RouteCircularReferenceException::class);\n        $this->expectExceptionMessage('Circular reference detected for route \"a\", path: \"a -> b -> c -> a\".');\n\n        $this->getGenerator($routes)->generate('a');\n    }\n\n    #[DataProvider('provideRelativePaths')]\n    public function testGetRelativePath($sourcePath, $targetPath, $expectedPath)\n    {\n        $this->assertSame($expectedPath, UrlGenerator::getRelativePath($sourcePath, $targetPath));\n    }\n\n    public static function provideRelativePaths()\n    {\n        return [\n            [\n                '/same/dir/',\n                '/same/dir/',\n                '',\n            ],\n            [\n                '/same/file',\n                '/same/file',\n                '',\n            ],\n            [\n                '/',\n                '/file',\n                'file',\n            ],\n            [\n                '/',\n                '/dir/file',\n                'dir/file',\n            ],\n            [\n                '/dir/file.html',\n                '/dir/different-file.html',\n                'different-file.html',\n            ],\n            [\n                '/same/dir/extra-file',\n                '/same/dir/',\n                './',\n            ],\n            [\n                '/parent/dir/',\n                '/parent/',\n                '../',\n            ],\n            [\n                '/parent/dir/extra-file',\n                '/parent/',\n                '../',\n            ],\n            [\n                '/a/b/',\n                '/x/y/z/',\n                '../../x/y/z/',\n            ],\n            [\n                '/a/b/c/d/e',\n                '/a/c/d',\n                '../../../c/d',\n            ],\n            [\n                '/a/b/c//',\n                '/a/b/c/',\n                '../',\n            ],\n            [\n                '/a/b/c/',\n                '/a/b/c//',\n                './/',\n            ],\n            [\n                '/root/a/b/c/',\n                '/root/x/b/c/',\n                '../../../x/b/c/',\n            ],\n            [\n                '/a/b/c/d/',\n                '/a',\n                '../../../../a',\n            ],\n            [\n                '/special-chars/sp%20ce/1€/mäh/e=mc²',\n                '/special-chars/sp%20ce/1€/<µ>/e=mc²',\n                '../<µ>/e=mc²',\n            ],\n            [\n                'not-rooted',\n                'dir/file',\n                'dir/file',\n            ],\n            [\n                '//dir/',\n                '',\n                '../../',\n            ],\n            [\n                '/dir/',\n                '/dir/file:with-colon',\n                './file:with-colon',\n            ],\n            [\n                '/dir/',\n                '/dir/subdir/file:with-colon',\n                'subdir/file:with-colon',\n            ],\n            [\n                '/dir/',\n                '/dir/:subdir/',\n                './:subdir/',\n            ],\n        ];\n    }\n\n    public function testFragmentsCanBeAppendedToUrls()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n\n        $url = $this->getGenerator($routes)->generate('test', ['_fragment' => 'frag ment'], UrlGeneratorInterface::ABSOLUTE_PATH);\n        $this->assertEquals('/app.php/testing#frag%20ment', $url);\n\n        $url = $this->getGenerator($routes)->generate('test', ['_fragment' => '0'], UrlGeneratorInterface::ABSOLUTE_PATH);\n        $this->assertEquals('/app.php/testing#0', $url);\n    }\n\n    public function testFragmentsDoNotEscapeValidCharacters()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing'));\n        $url = $this->getGenerator($routes)->generate('test', ['_fragment' => '?/'], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('/app.php/testing#?/', $url);\n    }\n\n    public function testFragmentsCanBeDefinedAsDefaults()\n    {\n        $routes = $this->getRoutes('test', new Route('/testing', ['_fragment' => 'fragment']));\n        $url = $this->getGenerator($routes)->generate('test', [], UrlGeneratorInterface::ABSOLUTE_PATH);\n\n        $this->assertEquals('/app.php/testing#fragment', $url);\n    }\n\n    #[DataProvider('provideLookAroundRequirementsInPath')]\n    public function testLookRoundRequirementsInPath($expected, $path, $requirement)\n    {\n        $routes = $this->getRoutes('test', new Route($path, [], ['foo' => $requirement, 'baz' => '.+?']));\n        $this->assertSame($expected, $this->getGenerator($routes)->generate('test', ['foo' => 'a/b', 'baz' => 'c/d/e']));\n    }\n\n    public static function provideLookAroundRequirementsInPath()\n    {\n        yield ['/app.php/a/b/b%28ar/c/d/e', '/{foo}/b(ar/{baz}', '.+(?=/b\\\\(ar/)'];\n        yield ['/app.php/a/b/bar/c/d/e', '/{foo}/bar/{baz}', '.+(?!$)'];\n        yield ['/app.php/bar/a/b/bam/c/d/e', '/bar/{foo}/bam/{baz}', '(?<=/bar/).+'];\n        yield ['/app.php/bar/a/b/bam/c/d/e', '/bar/{foo}/bam/{baz}', '(?<!^).+'];\n    }\n\n    public function testUtf8VarName()\n    {\n        $routes = $this->getRoutes('test', new Route('/foo/{bär}', [], [], ['utf8' => true]));\n        $this->assertSame('/app.php/foo/baz', $this->getGenerator($routes)->generate('test', ['bär' => 'baz']));\n    }\n\n    public function testQueryParameters()\n    {\n        $routes = $this->getRoutes('user', new Route('/user/{username}'));\n        $url = $this->getGenerator($routes)->generate('user', [\n            'username' => 'john',\n            'a' => 'foo',\n            'b' => 'bar',\n            'c' => 'baz',\n            '_query' => [\n                'a' => '123',\n                'd' => '789',\n            ],\n        ]);\n        $this->assertSame('/app.php/user/john?a=123&b=bar&c=baz&d=789', $url);\n    }\n\n    public function testRouteHostParameterAndQueryParameterWithSameName()\n    {\n        $routes = $this->getRoutes('admin_stats', new Route('/admin/stats', requirements: ['domain' => '.+'], host: '{siteCode}.{domain}'));\n        $url = $this->getGenerator($routes)->generate('admin_stats', [\n            'siteCode' => 'fr',\n            'domain' => 'example.com',\n            '_query' => [\n                'siteCode' => 'us',\n            ],\n        ], UrlGeneratorInterface::NETWORK_PATH);\n        $this->assertSame('//fr.example.com/app.php/admin/stats?siteCode=us', $url);\n    }\n\n    public function testRoutePathParameterAndQueryParameterWithSameName()\n    {\n        $routes = $this->getRoutes('user', new Route('/user/{id}'));\n        $url = $this->getGenerator($routes)->generate('user', [\n            'id' => '123',\n            '_query' => [\n                'id' => '456',\n            ],\n        ]);\n        $this->assertSame('/app.php/user/123?id=456', $url);\n    }\n\n    public function testQueryParameterCannotSubstituteRouteParameter()\n    {\n        $routes = $this->getRoutes('user', new Route('/user/{id}'));\n\n        $this->expectException(MissingMandatoryParametersException::class);\n        $this->expectExceptionMessage('Some mandatory parameters are missing (\"id\") to generate a URL for route \"user\".');\n\n        $this->getGenerator($routes)->generate('user', [\n            '_query' => [\n                'id' => '456',\n            ],\n        ]);\n    }\n\n    public function testQueryParametersWithScalarValue()\n    {\n        $routes = $this->getRoutes('user', new Route('/user/{id}'));\n\n        $this->expectException(InvalidParameterException::class);\n\n        $this->getGenerator($routes)->generate('user', [\n            'id' => '123',\n            '_query' => 'foo',\n        ]);\n    }\n\n    protected function getGenerator(RouteCollection $routes, array $parameters = [], $logger = null, ?string $defaultLocale = null)\n    {\n        $context = new RequestContext('/app.php');\n        foreach ($parameters as $key => $value) {\n            $method = 'set'.$key;\n            $context->$method($value);\n        }\n\n        return new UrlGenerator($routes, $context, $logger, $defaultLocale);\n    }\n\n    protected function getRoutes($name, Route $route)\n    {\n        $routes = new RouteCollection();\n        $routes->add($name, $route);\n\n        return $routes;\n    }\n}\n\nclass StringableObject\n{\n    public function __toString(): string\n    {\n        return 'bar';\n    }\n}\n\nclass StringableObjectWithPublicProperty\n{\n    public $foo = 'property';\n\n    public function __toString(): string\n    {\n        return 'bar';\n    }\n}\n\nclass NonStringableObject\n{\n}\n\nclass NonStringableObjectWithPublicProperty\n{\n    public $foo = 'property';\n}\n"
  },
  {
    "path": "Tests/Loader/AttributeClassLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Alias;\nuse Symfony\\Component\\Routing\\Exception\\LogicException;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\AbstractClassController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\ActionPathController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\AliasClassController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\AliasInvokableController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\AliasLocalizedRouteController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\AliasRouteController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\BazClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\DefaultValueController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\DeprecatedAliasCustomMessageRouteController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\DeprecatedAliasRouteController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\EncodingClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\ExplicitLocalizedActionPathController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\ExtendedRouteOnClassController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\ExtendedRouteOnMethodController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\GlobalDefaultsClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableLocalizedController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableMethodController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedActionPathController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedMethodActionControllers;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedPrefixLocalizedActionController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedPrefixMissingLocaleActionController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedPrefixMissingRouteLocaleActionController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedPrefixWithRouteWithoutLocale;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MethodActionControllers;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MethodsAndSchemes;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MissingRouteNameController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MultipleDeprecatedAliasRouteController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\NothingButNameController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\PrefixedActionLocalizedRouteController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\PrefixedActionPathController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\RequirementsWithoutPlaceholderNameController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\RouteWithEnv;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\RouteWithPrefixController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\Utf8ActionControllers;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\TraceableAttributeClassLoader;\n\nclass AttributeClassLoaderTest extends TestCase\n{\n    protected TraceableAttributeClassLoader $loader;\n\n    protected function setUp(?string $env = null): void\n    {\n        $this->loader = new TraceableAttributeClassLoader($env);\n    }\n\n    public function testGetResolver()\n    {\n        $this->expectException(LogicException::class);\n\n        $loader = new TraceableAttributeClassLoader();\n        $loader->getResolver();\n    }\n\n    #[DataProvider('provideTestSupportsChecksResource')]\n    public function testSupportsChecksResource($resource, $expectedSupports)\n    {\n        $this->assertSame($expectedSupports, $this->loader->supports($resource), '->supports() returns true if the resource is loadable');\n    }\n\n    public static function provideTestSupportsChecksResource(): array\n    {\n        return [\n            ['class', true],\n            ['\\fully\\qualified\\class\\name', true],\n            ['namespaced\\class\\without\\leading\\slash', true],\n            ['ÿClassWithLegalSpecialCharacters', true],\n            ['5', false],\n            ['foo.foo', false],\n            [null, false],\n        ];\n    }\n\n    public function testSupportsChecksTypeIfSpecified()\n    {\n        $this->assertTrue($this->loader->supports('class', 'attribute'), '->supports() checks the resource type if specified');\n        $this->assertFalse($this->loader->supports('class', 'foo'), '->supports() checks the resource type if specified');\n    }\n\n    public function testSimplePathRoute()\n    {\n        $routes = $this->loader->load(ActionPathController::class);\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/path', $routes->get('action')->getPath());\n        $this->assertEquals(new Alias('action'), $routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\ActionPathController::action'));\n    }\n\n    public function testRequirementsWithoutPlaceholderName()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('A placeholder name must be a string (0 given). Did you forget to specify the placeholder key for the requirement \"foo\"');\n\n        $this->loader->load(RequirementsWithoutPlaceholderNameController::class);\n    }\n\n    public function testInvokableControllerLoader()\n    {\n        $routes = $this->loader->load(InvokableController::class);\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/here', $routes->get('lol')->getPath());\n        $this->assertEquals(['GET', 'POST'], $routes->get('lol')->getMethods());\n        $this->assertEquals(['https'], $routes->get('lol')->getSchemes());\n        $this->assertEquals(new Alias('lol'), $routes->getAlias(InvokableController::class));\n        $this->assertEquals(new Alias('lol'), $routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableController::__invoke'));\n    }\n\n    public function testInvokableFQCNAliasConflictController()\n    {\n        $routes = $this->loader->load('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableFQCNAliasConflictController');\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/foobarccc', $routes->get('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableFQCNAliasConflictController')->getPath());\n        $this->assertNull($routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableFQCNAliasConflictController'));\n        $this->assertEquals(new Alias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableFQCNAliasConflictController'), $routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableFQCNAliasConflictController::__invoke'));\n    }\n\n    public function testInvokableMethodControllerLoader()\n    {\n        $routes = $this->loader->load(InvokableMethodController::class);\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/here', $routes->get('lol')->getPath());\n        $this->assertEquals(['GET', 'POST'], $routes->get('lol')->getMethods());\n        $this->assertEquals(['https'], $routes->get('lol')->getSchemes());\n        $this->assertEquals(new Alias('lol'), $routes->getAlias(InvokableMethodController::class));\n        $this->assertEquals(new Alias('lol'), $routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\InvokableMethodController::__invoke'));\n    }\n\n    public function testInvokableLocalizedControllerLoading()\n    {\n        $routes = $this->loader->load(InvokableLocalizedController::class);\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/here', $routes->get('action.en')->getPath());\n        $this->assertEquals('/hier', $routes->get('action.nl')->getPath());\n    }\n\n    public function testLocalizedPathRoutes()\n    {\n        $routes = $this->loader->load(LocalizedActionPathController::class);\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/path', $routes->get('action.en')->getPath());\n        $this->assertEquals('/pad', $routes->get('action.nl')->getPath());\n\n        $this->assertEquals('nl', $routes->get('action.nl')->getRequirement('_locale'));\n        $this->assertEquals('en', $routes->get('action.en')->getRequirement('_locale'));\n    }\n\n    public function testLocalizedPathRoutesWithExplicitPathPropety()\n    {\n        $routes = $this->loader->load(ExplicitLocalizedActionPathController::class);\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/path', $routes->get('action.en')->getPath());\n        $this->assertEquals('/pad', $routes->get('action.nl')->getPath());\n    }\n\n    public function testDefaultValuesForMethods()\n    {\n        $routes = $this->loader->load(DefaultValueController::class);\n        $this->assertCount(7, $routes);\n        $this->assertEquals('/{default}/path', $routes->get('action')->getPath());\n        $this->assertEquals('value', $routes->get('action')->getDefault('default'));\n        $this->assertEquals('Symfony', $routes->get('hello_with_default')->getDefault('name'));\n        $this->assertEquals('World', $routes->get('hello_without_default')->getDefault('name'));\n        $this->assertEquals('diamonds', $routes->get('string_enum_action')->getDefault('default'));\n        $this->assertArrayHasKey('libelle', $routes->get('defaultMappedParam_default')->getDefaults());\n        $this->assertNull($routes->get('defaultMappedParam_default')->getDefault('libelle'));\n        $this->assertArrayHasKey('barLibelle', $routes->get('defaultAdvancedMappedParam_default')->getDefaults());\n        $this->assertNull($routes->get('defaultAdvancedMappedParam_default')->getDefault('barLibelle'));\n        $this->assertEquals(20, $routes->get('int_enum_action')->getDefault('default'));\n    }\n\n    public function testMethodActionControllers()\n    {\n        $routes = $this->loader->load(MethodActionControllers::class);\n        $this->assertSame(['put', 'post'], array_keys($routes->all()));\n        $this->assertEquals('/the/path', $routes->get('put')->getPath());\n        $this->assertEquals('/the/path', $routes->get('post')->getPath());\n        $this->assertEquals(new Alias('post'), $routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MethodActionControllers::post'));\n        $this->assertEquals(new Alias('put'), $routes->getAlias('Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MethodActionControllers::put'));\n    }\n\n    public function testInvokableClassRouteLoadWithMethodAttribute()\n    {\n        $routes = $this->loader->load(LocalizedMethodActionControllers::class);\n        $this->assertCount(4, $routes);\n        $this->assertEquals('/the/path', $routes->get('put.en')->getPath());\n        $this->assertEquals('/the/path', $routes->get('post.en')->getPath());\n    }\n\n    public function testGlobalDefaultsRoutesLoadWithAttribute()\n    {\n        $routes = $this->loader->load(GlobalDefaultsClass::class);\n        $this->assertCount(4, $routes);\n\n        $specificLocaleRoute = $routes->get('specific_locale');\n\n        $this->assertSame('/defaults/specific-locale', $specificLocaleRoute->getPath());\n        $this->assertSame('s_locale', $specificLocaleRoute->getDefault('_locale'));\n        $this->assertSame('g_format', $specificLocaleRoute->getDefault('_format'));\n\n        $specificFormatRoute = $routes->get('specific_format');\n\n        $this->assertSame('/defaults/specific-format', $specificFormatRoute->getPath());\n        $this->assertSame('g_locale', $specificFormatRoute->getDefault('_locale'));\n        $this->assertSame('s_format', $specificFormatRoute->getDefault('_format'));\n\n        $this->assertSame(['GET'], $routes->get('redundant_method')->getMethods());\n        $this->assertSame(['https'], $routes->get('redundant_scheme')->getSchemes());\n    }\n\n    public function testUtf8RoutesLoadWithAttribute()\n    {\n        $routes = $this->loader->load(Utf8ActionControllers::class);\n        $this->assertSame(['one', 'two'], array_keys($routes->all()));\n        $this->assertTrue($routes->get('one')->getOption('utf8'), 'The route must accept utf8');\n        $this->assertFalse($routes->get('two')->getOption('utf8'), 'The route must not accept utf8');\n    }\n\n    public function testRouteWithPathWithPrefix()\n    {\n        $routes = $this->loader->load(PrefixedActionPathController::class);\n        $this->assertCount(1, $routes);\n        $route = $routes->get('action');\n        $this->assertEquals('/prefix/path', $route->getPath());\n        $this->assertEquals('lol=fun', $route->getCondition());\n        $this->assertEquals('frankdejonge.nl', $route->getHost());\n    }\n\n    public function testLocalizedRouteWithPathWithPrefix()\n    {\n        $routes = $this->loader->load(PrefixedActionLocalizedRouteController::class);\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/prefix/path', $routes->get('action.en')->getPath());\n        $this->assertEquals('/prefix/pad', $routes->get('action.nl')->getPath());\n    }\n\n    public function testLocalizedPrefixLocalizedRoute()\n    {\n        $routes = $this->loader->load(LocalizedPrefixLocalizedActionController::class);\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/nl/actie', $routes->get('action.nl')->getPath());\n        $this->assertEquals('/en/action', $routes->get('action.en')->getPath());\n    }\n\n    public function testInvokableClassMultipleRouteLoad()\n    {\n        $routeCollection = $this->loader->load(BazClass::class);\n        $route = $routeCollection->get('route1');\n\n        $this->assertSame('/1', $route->getPath(), '->load preserves class route path');\n        $this->assertSame(['https'], $route->getSchemes(), '->load preserves class route schemes');\n        $this->assertSame(['GET'], $route->getMethods(), '->load preserves class route methods');\n\n        $route = $routeCollection->get('route2');\n\n        $this->assertSame('/2', $route->getPath(), '->load preserves class route path');\n        $this->assertEquals(['https'], $route->getSchemes(), '->load preserves class route schemes');\n        $this->assertEquals(['GET'], $route->getMethods(), '->load preserves class route methods');\n    }\n\n    public function testMissingPrefixLocale()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->expectExceptionMessage('Route to \"action\" with locale \"en\" is missing a corresponding prefix in class \"Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedPrefixMissingLocaleActionController\".');\n        $this->loader->load(LocalizedPrefixMissingLocaleActionController::class);\n    }\n\n    public function testMissingRouteLocale()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->expectExceptionMessage('Route to \"Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\LocalizedPrefixMissingRouteLocaleActionController::action\" is missing paths for locale(s) \"en\".');\n        $this->loader->load(LocalizedPrefixMissingRouteLocaleActionController::class);\n    }\n\n    public function testRouteWithoutName()\n    {\n        $routes = $this->loader->load(MissingRouteNameController::class)->all();\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/path', reset($routes)->getPath());\n    }\n\n    public function testNothingButName()\n    {\n        $routes = $this->loader->load(NothingButNameController::class)->all();\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/', reset($routes)->getPath());\n    }\n\n    public function testNonExistingClass()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->loader->load('ClassThatDoesNotExist');\n    }\n\n    public function testLoadingAbstractClass()\n    {\n        $this->expectException(\\LogicException::class);\n        $this->loader->load(AbstractClassController::class);\n    }\n\n    public function testLocalizedPrefixWithoutRouteLocale()\n    {\n        $routes = $this->loader->load(LocalizedPrefixWithRouteWithoutLocale::class);\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/en/suffix', $routes->get('action.en')->getPath());\n        $this->assertEquals('/nl/suffix', $routes->get('action.nl')->getPath());\n    }\n\n    public function testLoadingRouteWithPrefix()\n    {\n        $routes = $this->loader->load(RouteWithPrefixController::class);\n        $this->assertCount(1, $routes);\n        $this->assertEquals('/prefix/path', $routes->get('action')->getPath());\n    }\n\n    public function testWhenEnv()\n    {\n        $routes = $this->loader->load(RouteWithEnv::class);\n        $this->assertCount(0, $routes);\n\n        $this->setUp('some-env');\n        $routes = $this->loader->load(RouteWithEnv::class);\n        $this->assertCount(3, $routes);\n        $this->assertSame('/path', $routes->get('action')->getPath());\n        $this->assertSame('/path4', $routes->get('action4')->getPath());\n        $this->assertSame('/path5', $routes->get('action5')->getPath());\n    }\n\n    public function testMethodsAndSchemes()\n    {\n        $routes = $this->loader->load(MethodsAndSchemes::class);\n\n        $this->assertSame(['GET', 'POST'], $routes->get('array_many')->getMethods());\n        $this->assertSame(['http', 'https'], $routes->get('array_many')->getSchemes());\n        $this->assertSame(['GET'], $routes->get('array_one')->getMethods());\n        $this->assertSame(['http'], $routes->get('array_one')->getSchemes());\n        $this->assertSame(['POST'], $routes->get('string')->getMethods());\n        $this->assertSame(['https'], $routes->get('string')->getSchemes());\n    }\n\n    public function testLoadingExtendedRouteOnClass()\n    {\n        $routes = $this->loader->load(ExtendedRouteOnClassController::class);\n        $this->assertCount(1, $routes);\n        $this->assertSame('/{section}/class-level/method-level', $routes->get('action')->getPath());\n        $this->assertSame(['section' => 'foo'], $routes->get('action')->getDefaults());\n    }\n\n    public function testLoadingExtendedRouteOnMethod()\n    {\n        $routes = $this->loader->load(ExtendedRouteOnMethodController::class);\n        $this->assertCount(1, $routes);\n        $this->assertSame('/{section}/method-level', $routes->get('action')->getPath());\n        $this->assertSame(['section' => 'foo'], $routes->get('action')->getDefaults());\n    }\n\n    public function testDefaultRouteName()\n    {\n        $routeCollection = $this->loader->load(EncodingClass::class);\n        $defaultName = array_keys($routeCollection->all())[0];\n\n        $this->assertSame('symfony_component_routing_tests_fixtures_attributefixtures_encodingclass_routeàction', $defaultName);\n    }\n\n    public function testAliasesOnMethod()\n    {\n        $routes = $this->loader->load(AliasRouteController::class);\n        $route = $routes->get('action_with_alias');\n        $this->assertCount(1, $routes);\n        $this->assertSame('/path', $route->getPath());\n        $this->assertEquals(new Alias('action_with_alias'), $routes->getAlias('alias'));\n        $this->assertEquals(new Alias('action_with_alias'), $routes->getAlias('completely_different_name'));\n    }\n\n    public function testLocalizedRouteWithAliases()\n    {\n        $routes = $this->loader->load(AliasLocalizedRouteController::class);\n        $this->assertCount(2, $routes);\n\n        $routeNl = $routes->get('localized_route.nl_NL');\n        $routeFr = $routes->get('localized_route.fr_FR');\n\n        $this->assertSame('/nl/localized', $routeNl->getPath());\n        $this->assertSame('/fr/localized', $routeFr->getPath());\n\n        $this->assertNull($routes->getAlias('localized_alias'));\n        $this->assertEquals(new Alias('localized_route.nl_NL'), $routes->getAlias('localized_alias.nl_NL'));\n        $this->assertEquals(new Alias('localized_route.fr_FR'), $routes->getAlias('localized_alias.fr_FR'));\n    }\n\n    public function testThrowsWithAliasesOnClass()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Route aliases cannot be used on non-invokable class \"Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\AliasClassController\".');\n\n        $this->loader->load(AliasClassController::class);\n    }\n\n    public function testAliasesOnInvokableClass()\n    {\n        $routes = $this->loader->load(AliasInvokableController::class);\n        $route = $routes->get('invokable_path');\n        $this->assertCount(1, $routes);\n        $this->assertSame('/path', $route->getPath());\n        $this->assertEquals(new Alias('invokable_path'), $routes->getAlias('alias'));\n        $this->assertEquals(new Alias('invokable_path'), $routes->getAlias('completely_different_name'));\n    }\n\n    public function testDeprecatedAlias()\n    {\n        $routes = $this->loader->load(DeprecatedAliasRouteController::class);\n        $route = $routes->get('action_with_deprecated_alias');\n        $expected = (new Alias('action_with_deprecated_alias'))\n            ->setDeprecated(\n                'MyBundleFixture',\n                '1.0',\n                'The \"%alias_id%\" route alias is deprecated. You should stop using it, as it will be removed in the future.'\n            );\n        $actual = $routes->getAlias('my_other_alias_deprecated');\n        $this->assertCount(1, $routes);\n        $this->assertSame('/path', $route->getPath());\n        $this->assertEquals($expected, $actual);\n    }\n\n    public function testDeprecatedAliasWithCustomMessage()\n    {\n        $routes = $this->loader->load(DeprecatedAliasCustomMessageRouteController::class);\n        $route = $routes->get('action_with_deprecated_alias');\n        $expected = (new Alias('action_with_deprecated_alias'))\n            ->setDeprecated(\n                'MyBundleFixture',\n                '1.0',\n                '%alias_id% alias is deprecated.'\n            );\n        $actual = $routes->getAlias('my_other_alias_deprecated');\n        $this->assertCount(1, $routes);\n        $this->assertSame('/path', $route->getPath());\n        $this->assertEquals($expected, $actual);\n    }\n\n    public function testMultipleDeprecatedAlias()\n    {\n        $routes = $this->loader->load(MultipleDeprecatedAliasRouteController::class);\n        $route = $routes->get('action_with_multiple_deprecated_alias');\n        $this->assertCount(1, $routes);\n        $this->assertSame('/path', $route->getPath());\n\n        $dataset = [\n            'my_first_alias_deprecated' => [\n                'package' => 'MyFirstBundleFixture',\n                'version' => '1.0',\n            ],\n            'my_second_alias_deprecated' => [\n                'package' => 'MySecondBundleFixture',\n                'version' => '2.0',\n            ],\n            'my_third_alias_deprecated' => [\n                'package' => 'SurprisedThirdBundleFixture',\n                'version' => '3.0',\n            ],\n        ];\n\n        foreach ($dataset as $aliasName => $aliasData) {\n            $expected = (new Alias('action_with_multiple_deprecated_alias'))\n                ->setDeprecated(\n                    $aliasData['package'],\n                    $aliasData['version'],\n                    'The \"%alias_id%\" route alias is deprecated. You should stop using it, as it will be removed in the future.'\n                );\n            $actual = $routes->getAlias($aliasName);\n            $this->assertEquals($expected, $actual);\n        }\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/AttributeDirectoryLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Routing\\Loader\\AttributeDirectoryLoader;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses\\BarClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses\\BazClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses\\EncodingClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses\\FooClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\TraceableAttributeClassLoader;\n\nclass AttributeDirectoryLoaderTest extends TestCase\n{\n    private AttributeDirectoryLoader $loader;\n    private TraceableAttributeClassLoader $classLoader;\n\n    protected function setUp(): void\n    {\n        $this->classLoader = new TraceableAttributeClassLoader();\n        $this->loader = new AttributeDirectoryLoader(new FileLocator(), $this->classLoader);\n    }\n\n    public function testLoad()\n    {\n        $this->loader->load(__DIR__.'/../Fixtures/AttributedClasses');\n\n        self::assertSame([\n            BarClass::class,\n            BazClass::class,\n            EncodingClass::class,\n            FooClass::class,\n        ], $this->classLoader->foundClasses);\n    }\n\n    public function testSupports()\n    {\n        $fixturesDir = __DIR__.'/../Fixtures';\n\n        $this->assertTrue($this->loader->supports($fixturesDir), '->supports() returns true if the resource is loadable');\n        $this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');\n\n        $this->assertTrue($this->loader->supports($fixturesDir, 'attribute'), '->supports() checks the resource type if specified');\n        $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified');\n    }\n\n    public function testItSupportsAnyAttribute()\n    {\n        $this->assertTrue($this->loader->supports(__DIR__.'/../Fixtures/even-with-not-existing-folder', 'attribute'));\n    }\n\n    public function testLoadFileIfLocatedResourceIsFile()\n    {\n        $this->loader->load(__DIR__.'/../Fixtures/AttributedClasses/FooClass.php');\n        self::assertSame([FooClass::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAbstractClass()\n    {\n        self::assertNull($this->loader->load(__DIR__.'/../Fixtures/AttributedClasses/AbstractClass.php'));\n        self::assertSame([], $this->classLoader->foundClasses);\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/AttributeFileLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Routing\\Loader\\AttributeFileLoader;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributedClasses\\FooClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamAfterCommaController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamAfterParenthesisController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamInlineAfterCommaController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamInlineAfterParenthesisController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamInlineQuotedAfterCommaController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamInlineQuotedAfterParenthesisController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamQuotedAfterCommaController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributesFixtures\\AttributesClassParamQuotedAfterParenthesisController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\OtherAnnotatedClasses\\VariadicClass;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\TraceableAttributeClassLoader;\n\nclass AttributeFileLoaderTest extends TestCase\n{\n    private AttributeFileLoader $loader;\n    private TraceableAttributeClassLoader $classLoader;\n\n    protected function setUp(): void\n    {\n        $this->classLoader = new TraceableAttributeClassLoader();\n        $this->loader = new AttributeFileLoader(new FileLocator(), $this->classLoader);\n    }\n\n    public function testLoad()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributedClasses/FooClass.php'));\n        self::assertSame([FooClass::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadTraitWithClassConstant()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributedClasses/FooTrait.php'));\n        self::assertSame([], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadFileWithoutStartTag()\n    {\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('Did you forget to add the \"<?php\" start tag at the beginning of the file?');\n        $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/NoStartTagClass.php');\n    }\n\n    public function testLoadVariadic()\n    {\n        self::assertCount(1, $this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php'));\n        self::assertSame([VariadicClass::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAbstractClass()\n    {\n        self::assertNull($this->loader->load(__DIR__.'/../Fixtures/AttributedClasses/AbstractClass.php'));\n        self::assertSame([], $this->classLoader->foundClasses);\n    }\n\n    public function testSupports()\n    {\n        $fixture = __DIR__.'/../Fixtures/annotated.php';\n\n        $this->assertTrue($this->loader->supports($fixture), '->supports() returns true if the resource is loadable');\n        $this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');\n\n        $this->assertTrue($this->loader->supports($fixture, 'attribute'), '->supports() checks the resource type if specified');\n        $this->assertFalse($this->loader->supports($fixture, 'foo'), '->supports() checks the resource type if specified');\n    }\n\n    public function testLoadAttributesClassAfterComma()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php'));\n        self::assertSame([AttributesClassParamAfterCommaController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesInlineClassAfterComma()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php'));\n        self::assertSame([AttributesClassParamInlineAfterCommaController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesQuotedClassAfterComma()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php'));\n        self::assertSame([AttributesClassParamQuotedAfterCommaController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesInlineQuotedClassAfterComma()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php'));\n        self::assertSame([AttributesClassParamInlineQuotedAfterCommaController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesClassAfterParenthesis()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php'));\n        self::assertSame([AttributesClassParamAfterParenthesisController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesInlineClassAfterParenthesis()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php'));\n        self::assertSame([AttributesClassParamInlineAfterParenthesisController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesQuotedClassAfterParenthesis()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php'));\n        self::assertSame([AttributesClassParamQuotedAfterParenthesisController::class], $this->classLoader->foundClasses);\n    }\n\n    public function testLoadAttributesInlineQuotedClassAfterParenthesis()\n    {\n        self::assertCount(0, $this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php'));\n        self::assertSame([AttributesClassParamInlineQuotedAfterParenthesisController::class], $this->classLoader->foundClasses);\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/AttributeServicesLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolver;\nuse Symfony\\Component\\Routing\\Loader\\AttributeServicesLoader;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\ActionPathController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\AttributeFixtures\\MethodActionControllers;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\TraceableAttributeClassLoader;\n\nclass AttributeServicesLoaderTest extends TestCase\n{\n    public function testSupports()\n    {\n        $loader = new AttributeServicesLoader();\n\n        $this->assertFalse($loader->supports('attributes', null));\n        $this->assertFalse($loader->supports('attributes', 'attribute'));\n        $this->assertFalse($loader->supports('other', 'routing.controllers'));\n        $this->assertTrue($loader->supports('routing.controllers'));\n    }\n\n    public function testDelegatesToAttributeLoaderAndMergesCollections()\n    {\n        $attributeLoader = new TraceableAttributeClassLoader();\n\n        $servicesLoader = new AttributeServicesLoader([\n            ActionPathController::class,\n            MethodActionControllers::class,\n        ]);\n\n        $resolver = new LoaderResolver([\n            $attributeLoader,\n            $servicesLoader,\n        ]);\n\n        $attributeLoader->setResolver($resolver);\n        $servicesLoader->setResolver($resolver);\n\n        $collection = $servicesLoader->load('routing.controllers');\n\n        $this->assertArrayHasKey('action', $collection->all());\n        $this->assertArrayHasKey('put', $collection->all());\n        $this->assertArrayHasKey('post', $collection->all());\n\n        $this->assertSame(['/path'], [$collection->get('action')->getPath()]);\n        $this->assertSame('/the/path', $collection->get('put')->getPath());\n        $this->assertSame('/the/path', $collection->get('post')->getPath());\n\n        $this->assertSame([\n            ActionPathController::class,\n            MethodActionControllers::class,\n        ], $attributeLoader->foundClasses);\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/ClosureLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Loader\\ClosureLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass ClosureLoaderTest extends TestCase\n{\n    public function testSupports()\n    {\n        $loader = new ClosureLoader();\n\n        $closure = static function () {};\n\n        $this->assertTrue($loader->supports($closure), '->supports() returns true if the resource is loadable');\n        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');\n\n        $this->assertTrue($loader->supports($closure, 'closure'), '->supports() checks the resource type if specified');\n        $this->assertFalse($loader->supports($closure, 'foo'), '->supports() checks the resource type if specified');\n    }\n\n    public function testLoad()\n    {\n        $loader = new ClosureLoader('some-env');\n\n        $route = new Route('/');\n        $routes = $loader->load(function (?string $env = null) use ($route) {\n            $this->assertSame('some-env', $env);\n\n            $routes = new RouteCollection();\n\n            $routes->add('foo', $route);\n\n            return $routes;\n        });\n\n        $this->assertEquals($route, $routes->get('foo'), '->load() loads a \\Closure resource');\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/Configurator/Traits/PrefixTraitTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader\\Configurator\\Traits;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\Traits\\PrefixTrait;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass PrefixTraitTest extends TestCase\n{\n    public function testAddLocalizedPrefixUpdatesAliases()\n    {\n        $collection = new RouteCollection();\n        $collection->add('app_route', new Route('/path'));\n        $collection->addAlias('app_alias', 'app_route');\n\n        $trait = new class {\n            use PrefixTrait;\n\n            public function add(RouteCollection $c, array $p)\n            {\n                $this->addPrefix($c, $p, false);\n            }\n        };\n\n        $trait->add($collection, ['en' => '/en', 'fr' => '/fr']);\n\n        $this->assertNull($collection->get('app_route'));\n\n        $this->assertNotNull($collection->get('app_route.en'));\n        $this->assertNotNull($collection->get('app_route.fr'));\n\n        $this->assertNull($collection->getAlias('app_alias'), 'The original alias should be removed as its target no longer exists');\n\n        $aliasEn = $collection->getAlias('app_alias.en');\n        $this->assertNotNull($aliasEn, 'Localized alias for EN should exist');\n        $this->assertEquals('app_route.en', $aliasEn->getId());\n\n        $aliasFr = $collection->getAlias('app_alias.fr');\n        $this->assertNotNull($aliasFr, 'Localized alias for FR should exist');\n        $this->assertEquals('app_route.fr', $aliasFr->getId());\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/ContainerLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\DependencyInjection\\Container;\nuse Symfony\\Component\\Routing\\Loader\\ContainerLoader;\n\nclass ContainerLoaderTest extends TestCase\n{\n    #[DataProvider('supportsProvider')]\n    public function testSupports(bool $expected, ?string $type = null)\n    {\n        $this->assertSame($expected, (new ContainerLoader(new Container()))->supports('foo', $type));\n    }\n\n    public static function supportsProvider()\n    {\n        return [\n            [true, 'service'],\n            [false, 'bar'],\n            [false, null],\n        ];\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/DirectoryLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolver;\nuse Symfony\\Component\\Routing\\Loader\\AttributeFileLoader;\nuse Symfony\\Component\\Routing\\Loader\\DirectoryLoader;\nuse Symfony\\Component\\Routing\\Loader\\YamlFileLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\TraceableAttributeClassLoader;\n\nclass DirectoryLoaderTest extends TestCase\n{\n    private DirectoryLoader $loader;\n\n    protected function setUp(): void\n    {\n        $locator = new FileLocator();\n        $this->loader = new DirectoryLoader($locator);\n        $resolver = new LoaderResolver([\n            new YamlFileLoader($locator),\n            new AttributeFileLoader($locator, new TraceableAttributeClassLoader()),\n            $this->loader,\n        ]);\n        $this->loader->setResolver($resolver);\n    }\n\n    public function testLoadDirectory()\n    {\n        $collection = $this->loader->load(__DIR__.'/../Fixtures/directory', 'directory');\n        $this->verifyCollection($collection);\n    }\n\n    public function testImportDirectory()\n    {\n        $collection = $this->loader->load(__DIR__.'/../Fixtures/directory_import', 'directory');\n        $this->verifyCollection($collection);\n    }\n\n    private function verifyCollection(RouteCollection $collection)\n    {\n        $routes = $collection->all();\n\n        $this->assertCount(3, $routes, 'Three routes are loaded');\n        $this->assertContainsOnlyInstancesOf(Route::class, $routes);\n\n        for ($i = 1; $i <= 3; ++$i) {\n            $this->assertSame('/route/'.$i, $routes['route'.$i]->getPath());\n        }\n    }\n\n    public function testSupports()\n    {\n        $fixturesDir = __DIR__.'/../Fixtures';\n\n        $this->assertFalse($this->loader->supports($fixturesDir), '->supports(*) returns false');\n\n        $this->assertTrue($this->loader->supports($fixturesDir, 'directory'), '->supports(*, \"directory\") returns true');\n        $this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports(*, \"foo\") returns false');\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/FileLocatorStub.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse Symfony\\Component\\Config\\FileLocatorInterface;\n\nclass FileLocatorStub implements FileLocatorInterface\n{\n    public function locate(string $name, ?string $currentPath = null, bool $first = true): string|array\n    {\n        if (str_starts_with($name, 'http')) {\n            return $name;\n        }\n\n        return rtrim($currentPath, '/').'/'.$name;\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/GlobFileLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Config\\Resource\\GlobResource;\nuse Symfony\\Component\\Routing\\Loader\\GlobFileLoader;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass GlobFileLoaderTest extends TestCase\n{\n    public function testSupports()\n    {\n        $loader = new GlobFileLoader(new FileLocator());\n\n        $this->assertTrue($loader->supports('any-path', 'glob'), '->supports() returns true if the resource has the glob type');\n        $this->assertFalse($loader->supports('any-path'), '->supports() returns false if the resource is not of glob type');\n    }\n\n    public function testLoadAddsTheGlobResourceToTheContainer()\n    {\n        $loader = new GlobFileLoaderWithoutImport(new FileLocator());\n        $collection = $loader->load(__DIR__.'/../Fixtures/directory/*.yml');\n\n        $this->assertEquals(new GlobResource(__DIR__.'/../Fixtures/directory', '/*.yml', false), $collection->getResources()[0]);\n    }\n}\n\nclass GlobFileLoaderWithoutImport extends GlobFileLoader\n{\n    public function import(mixed $resource, ?string $type = null, bool $ignoreErrors = false, ?string $sourceResource = null, $exclude = null): mixed\n    {\n        return new RouteCollection();\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/ObjectLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Loader\\ObjectLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass ObjectLoaderTest extends TestCase\n{\n    public function testLoadCallsServiceAndReturnsCollection()\n    {\n        $loader = new TestObjectLoader('some-env');\n\n        // create a basic collection that will be returned\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $loader->loaderMap = [\n            'my_route_provider_service' => new TestObjectLoaderRouteService($collection, 'some-env'),\n        ];\n\n        $actualRoutes = $loader->load(\n            'my_route_provider_service::loadRoutes',\n            'service'\n        );\n\n        $this->assertSame($collection, $actualRoutes);\n        // the service file should be listed as a resource\n        $this->assertNotEmpty($actualRoutes->getResources());\n    }\n\n    #[DataProvider('getBadResourceStrings')]\n    public function testExceptionWithoutSyntax(string $resourceString)\n    {\n        $loader = new TestObjectLoader();\n\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $loader->load($resourceString);\n    }\n\n    public static function getBadResourceStrings()\n    {\n        return [\n            ['Foo:Bar:baz'],\n            ['Foo::Bar::baz'],\n            ['Foo:'],\n            ['Foo::'],\n            [':Foo'],\n            ['::Foo'],\n        ];\n    }\n\n    public function testExceptionOnNoObjectReturned()\n    {\n        $loader = new TestObjectLoader();\n        $loader->loaderMap = ['my_service' => 'NOT_AN_OBJECT'];\n\n        $this->expectException(\\TypeError::class);\n\n        $loader->load('my_service::method');\n    }\n\n    public function testExceptionOnBadMethod()\n    {\n        $loader = new TestObjectLoader();\n        $loader->loaderMap = ['my_service' => new \\stdClass()];\n\n        $this->expectException(\\BadMethodCallException::class);\n\n        $loader->load('my_service::method');\n    }\n\n    public function testExceptionOnMethodNotReturningCollection()\n    {\n        $service = $this->createMock(CustomRouteLoader::class);\n\n        $service->expects($this->once())\n            ->method('loadRoutes')\n            ->willReturn('NOT_A_COLLECTION');\n\n        $loader = new TestObjectLoader();\n        $loader->loaderMap = ['my_service' => $service];\n\n        $this->expectException(\\LogicException::class);\n\n        $loader->load('my_service::loadRoutes');\n    }\n}\n\nclass TestObjectLoader extends ObjectLoader\n{\n    public array $loaderMap = [];\n\n    public function supports(mixed $resource, ?string $type = null): bool\n    {\n        return 'service';\n    }\n\n    protected function getObject(string $id): object\n    {\n        return $this->loaderMap[$id];\n    }\n}\n\ninterface CustomRouteLoader\n{\n    public function loadRoutes();\n}\n\nclass TestObjectLoaderRouteService\n{\n    private RouteCollection $collection;\n    private ?string $env;\n\n    public function __construct($collection, ?string $env = null)\n    {\n        $this->collection = $collection;\n        $this->env = $env;\n    }\n\n    public function loadRoutes(TestObjectLoader $loader, ?string $env = null)\n    {\n        if ($this->env !== $env) {\n            throw new \\InvalidArgumentException(\\sprintf('Expected env \"%s\", \"%s\" given.', $this->env, $env));\n        }\n\n        return $this->collection;\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/PhpFileLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Config\\FileLocatorInterface;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolver;\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Config\\Resource\\ResourceInterface;\nuse Symfony\\Component\\Routing\\Loader\\AttributeClassLoader;\nuse Symfony\\Component\\Routing\\Loader\\PhpFileLoader;\nuse Symfony\\Component\\Routing\\Loader\\Psr4DirectoryLoader;\nuse Symfony\\Component\\Routing\\Loader\\YamlFileLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\MyController;\n\nclass PhpFileLoaderTest extends TestCase\n{\n    public function testSupports()\n    {\n        $loader = new PhpFileLoader($this->createStub(FileLocatorInterface::class));\n\n        $this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable');\n        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');\n\n        $this->assertTrue($loader->supports('foo.php', 'php'), '->supports() checks the resource type if specified');\n        $this->assertFalse($loader->supports('foo.php', 'foo'), '->supports() checks the resource type if specified');\n    }\n\n    public function testLoadWithRoute()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routeCollection = $loader->load('validpattern.php');\n        $routes = $routeCollection->all();\n\n        $this->assertCount(1, $routes, 'One route is loaded');\n        $this->assertContainsOnlyInstancesOf(Route::class, $routes);\n\n        foreach ($routes as $route) {\n            $this->assertSame('/blog/{slug}', $route->getPath());\n            $this->assertSame('MyBlogBundle:Blog:show', $route->getDefault('_controller'));\n            $this->assertTrue($route->getDefault('_stateless'));\n            $this->assertSame('{locale}.example.com', $route->getHost());\n            $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));\n            $this->assertEquals(['GET', 'POST', 'PUT', 'OPTIONS'], $route->getMethods());\n            $this->assertEquals(['https'], $route->getSchemes());\n        }\n    }\n\n    public function testLoadWithImport()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routeCollection = $loader->load('validresource.php');\n        $routes = $routeCollection->all();\n\n        $this->assertCount(1, $routes, 'One route is loaded');\n        $this->assertContainsOnlyInstancesOf(Route::class, $routes);\n\n        foreach ($routes as $route) {\n            $this->assertSame('/prefix/blog/{slug}', $route->getPath());\n            $this->assertSame('MyBlogBundle:Blog:show', $route->getDefault('_controller'));\n            $this->assertSame('{locale}.example.com', $route->getHost());\n            $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));\n            $this->assertEquals(['GET', 'POST', 'PUT', 'OPTIONS'], $route->getMethods());\n            $this->assertEquals(['https'], $route->getSchemes());\n        }\n    }\n\n    public function testThatDefiningVariableInConfigFileHasNoSideEffects()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures']);\n        $loader = new PhpFileLoader($locator);\n        $routeCollection = $loader->load('with_define_path_variable.php');\n        $resources = $routeCollection->getResources();\n        $this->assertCount(1, $resources);\n        $this->assertContainsOnlyInstancesOf(ResourceInterface::class, $resources);\n        $fileResource = reset($resources);\n        $this->assertSame(\n            realpath($locator->locate('with_define_path_variable.php')),\n            (string) $fileResource\n        );\n    }\n\n    public function testLoadingRouteWithDefaults()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routes = $loader->load('defaults.php');\n\n        $this->assertCount(1, $routes);\n\n        $defaultsRoute = $routes->get('defaults');\n\n        $this->assertSame('/defaults', $defaultsRoute->getPath());\n        $this->assertSame('en', $defaultsRoute->getDefault('_locale'));\n        $this->assertSame('html', $defaultsRoute->getDefault('_format'));\n    }\n\n    public function testLoadingRouteWithCollectionDefaults()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routes = $loader->load('collection-defaults.php');\n\n        $this->assertCount(2, $routes);\n\n        $defaultsRoute = $routes->get('defaultsA');\n        $this->assertSame(['GET'], $defaultsRoute->getMethods());\n        $this->assertArrayHasKey('attribute', $defaultsRoute->getDefaults());\n        $this->assertTrue($defaultsRoute->getDefault('_stateless'));\n        $this->assertSame('/defaultsA', $defaultsRoute->getPath());\n        $this->assertSame('en', $defaultsRoute->getDefault('_locale'));\n        $this->assertSame('html', $defaultsRoute->getDefault('_format'));\n\n        // The second route has a specific method and is not stateless, overwriting the collection settings\n        $defaultsRoute = $routes->get('defaultsB');\n        $this->assertSame(['POST'], $defaultsRoute->getMethods());\n        $this->assertArrayHasKey('attribute', $defaultsRoute->getDefaults());\n        $this->assertFalse($defaultsRoute->getDefault('_stateless'));\n        $this->assertSame('/defaultsB', $defaultsRoute->getPath());\n        $this->assertSame('en', $defaultsRoute->getDefault('_locale'));\n        $this->assertSame('html', $defaultsRoute->getDefault('_format'));\n    }\n\n    public function testLoadingImportedRoutesWithDefaults()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routes = $loader->load('importer-with-defaults.php');\n\n        $this->assertCount(2, $routes);\n\n        $expectedRoutes = new RouteCollection();\n        $expectedRoutes->add('one', $localeRoute = new Route('/defaults/one'));\n        $localeRoute->setDefault('_locale', 'g_locale');\n        $localeRoute->setDefault('_format', 'g_format');\n        $localeRoute->setDefault('_stateless', true);\n        $expectedRoutes->add('two', $formatRoute = new Route('/defaults/two'));\n        $formatRoute->setDefault('_locale', 'g_locale');\n        $formatRoute->setDefault('_format', 'g_format');\n        $formatRoute->setDefault('_stateless', true);\n        $formatRoute->setDefault('specific', 'imported');\n\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/imported-with-defaults.php'));\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/importer-with-defaults.php'));\n\n        $this->assertEquals($expectedRoutes, $routes);\n    }\n\n    public function testLoadingUtf8Route()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('utf8.php');\n\n        $this->assertCount(2, $routes);\n\n        $expectedRoutes = new RouteCollection();\n        $expectedRoutes->add('some_route', new Route('/'));\n\n        $expectedRoutes->add('some_utf8_route', $route = new Route('/utf8'));\n        $route->setOption('utf8', true);\n\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/localized/utf8.php'));\n\n        $this->assertEquals($expectedRoutes, $routes);\n    }\n\n    public function testLoadingUtf8ImportedRoutes()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('importer-with-utf8.php');\n\n        $this->assertCount(2, $routes);\n\n        $expectedRoutes = new RouteCollection();\n        $expectedRoutes->add('utf8_one', $one = new Route('/one'));\n        $one->setOption('utf8', true);\n\n        $expectedRoutes->add('utf8_two', $two = new Route('/two'));\n        $two->setOption('utf8', true);\n\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/localized/imported-with-utf8.php'));\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/localized/importer-with-utf8.php'));\n\n        $this->assertEquals($expectedRoutes, $routes);\n    }\n\n    public function testRoutingConfigurator()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures']);\n        $loader = new PhpFileLoader($locator);\n        $routeCollectionClosure = $loader->load('php_dsl.php');\n        $routeCollectionObject = $loader->load('php_object_dsl.php');\n\n        $expectedCollection = new RouteCollection();\n\n        $expectedCollection->add('foo', (new Route('/foo'))\n            ->setOptions(['utf8' => true])\n            ->setCondition('abc')\n        );\n        $expectedCollection->add('buz', (new Route('/zub'))\n            ->setDefaults(['_controller' => 'foo:act', '_stateless' => true])\n        );\n        $expectedCollection->add('controller_class', (new Route('/controller'))\n            ->setDefaults(['_controller' => ['Acme\\MyApp\\MyController', 'myAction']])\n        );\n        $expectedCollection->add('c_root', (new Route('/sub/pub/'))\n            ->setRequirements(['id' => '\\d+'])\n        );\n        $expectedCollection->add('c_bar', (new Route('/sub/pub/bar'))\n            ->setRequirements(['id' => '\\d+'])\n        );\n        $expectedCollection->add('c_pub_buz', (new Route('/sub/pub/buz'))\n            ->setHost('host')\n            ->setRequirements(['id' => '\\d+'])\n        );\n        $expectedCollection->add('z_c_root', new Route('/zub/pub/'));\n        $expectedCollection->add('z_c_bar', new Route('/zub/pub/bar'));\n        $expectedCollection->add('z_c_pub_buz', (new Route('/zub/pub/buz'))->setHost('host'));\n        $expectedCollection->add('r_root', new Route('/bus'));\n        $expectedCollection->add('r_bar', new Route('/bus/bar/'));\n        $expectedCollection->add('ouf', (new Route('/ouf'))\n            ->setSchemes(['https'])\n            ->setMethods(['GET'])\n            ->setDefaults(['id' => 0])\n        );\n\n        $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub.php')));\n        $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub_root.php')));\n\n        $expectedCollectionClosure = $expectedCollection;\n        $expectedCollectionObject = clone $expectedCollection;\n\n        $expectedCollectionClosure->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl.php')));\n        $expectedCollectionObject->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_object_dsl.php')));\n\n        $this->assertEquals($expectedCollectionClosure, $routeCollectionClosure);\n        $this->assertEquals($expectedCollectionObject, $routeCollectionObject);\n    }\n\n    public function testRoutingConfiguratorCanImportGlobPatterns()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures/glob']);\n        $loader = new PhpFileLoader($locator);\n        $routeCollection = $loader->load('php_dsl.php');\n\n        $route = $routeCollection->get('bar_route');\n        $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));\n\n        $route = $routeCollection->get('baz_route');\n        $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));\n    }\n\n    public function testRoutingI18nConfigurator()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures']);\n        $loader = new PhpFileLoader($locator);\n        $routeCollection = $loader->load('php_dsl_i18n.php');\n\n        $expectedCollection = new RouteCollection();\n\n        $expectedCollection->add('foo.en', (new Route('/glish/foo'))->setDefaults(['_locale' => 'en', '_canonical_route' => 'foo'])->setRequirement('_locale', 'en'));\n        $expectedCollection->add('bar.en', (new Route('/glish/bar'))->setDefaults(['_locale' => 'en', '_canonical_route' => 'bar'])->setRequirement('_locale', 'en'));\n        $expectedCollection->add('baz.en', (new Route('/baz'))->setDefaults(['_locale' => 'en', '_canonical_route' => 'baz'])->setRequirement('_locale', 'en'));\n        $expectedCollection->add('c_foo.fr', (new Route('/ench/pub/foo'))->setDefaults(['_locale' => 'fr', '_canonical_route' => 'c_foo'])->setRequirement('_locale', 'fr'));\n        $expectedCollection->add('c_bar.fr', (new Route('/ench/pub/bar'))->setDefaults(['_locale' => 'fr', '_canonical_route' => 'c_bar'])->setRequirement('_locale', 'fr'));\n        $expectedCollection->add('non_localized.fr', (new Route('/ench/non-localized'))->setDefaults(['_locale' => 'fr', '_canonical_route' => 'non_localized'])->setRequirement('_locale', 'fr'));\n\n        $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_sub_i18n.php')));\n        $expectedCollection->addResource(new FileResource(realpath(__DIR__.'/../Fixtures/php_dsl_i18n.php')));\n\n        $this->assertEquals($expectedCollection, $routeCollection);\n    }\n\n    public function testImportingRoutesWithHostsInImporter()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-with-host.php');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-with-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('php'), $routes);\n    }\n\n    public function testImportingRoutesWithLocalesAndHostInImporter()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-with-locale-and-host.php');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-with-locale-and-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('php'), $routes);\n    }\n\n    public function testImportingRoutesWithoutHostInImporter()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-without-host.php');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-without-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('php'), $routes);\n    }\n\n    public function testImportingRoutesWithSingleHostInImporter()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-with-single-host.php');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-with-single-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('php'), $routes);\n    }\n\n    public function testAddingRouteWithHosts()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('route-with-hosts.php');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/route-with-hosts-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('php'), $routes);\n    }\n\n    public function testImportingAliases()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures/alias']));\n        $routes = $loader->load('alias.php');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/alias/expected.php';\n\n        $this->assertEquals($expectedRoutes('php'), $routes);\n    }\n\n    public function testWhenEnv()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures']);\n        $loader = new PhpFileLoader($locator, 'some-env');\n        $routes = $loader->load('when-env.php');\n\n        $this->assertSame(['b', 'a'], array_keys($routes->all()));\n        $this->assertSame('/b', $routes->get('b')->getPath());\n    }\n\n    public function testLoadsArrayRoutes()\n    {\n        $loader = new PhpFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routes = $loader->load('array_routes.php');\n        $this->assertSame('/a', $routes->get('a')->getPath());\n        $this->assertSame('/b', $routes->get('b')->getPath());\n        $this->assertSame(['GET'], $routes->get('b')->getMethods());\n    }\n\n    public function testWhenEnvWithArray()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures']);\n        $loader = new PhpFileLoader($locator, 'some-env');\n        $routes = $loader->load('array_when_env.php');\n        $this->assertSame('/a', $routes->get('a')->getPath());\n        $this->assertSame('/x', $routes->get('x')->getPath());\n    }\n\n    public function testYamlImportsAreResolvedWhenProcessingPhpReturnedArrays()\n    {\n        $locator = new FileLocator([__DIR__.'/../Fixtures']);\n        $loader = new PhpFileLoader($locator);\n        $yamlFileLoader = new YamlFileLoader($locator);\n        $loaderResolver = new LoaderResolver([$loader, $yamlFileLoader]);\n        $loader->setResolver($loaderResolver);\n        $yamlFileLoader->setResolver($loaderResolver);\n\n        $routes = $loader->load('importer-php-returns-array.php');\n\n        $this->assertSame('/blog/{slug}', $routes->get('blog_show')->getPath());\n        $this->assertSame('/direct', $routes->get('direct')->getPath());\n    }\n\n    #[DataProvider('providePsr4ConfigFiles')]\n    public function testImportAttributesWithPsr4Prefix(string $configFile)\n    {\n        $locator = new FileLocator(\\dirname(__DIR__).'/Fixtures');\n        new LoaderResolver([\n            $loader = new PhpFileLoader($locator),\n            new Psr4DirectoryLoader($locator),\n            new class extends AttributeClassLoader {\n                protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n                {\n                    $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                }\n            },\n        ]);\n\n        $route = $loader->load($configFile)->get('my_route');\n        $this->assertSame('/my-prefix/my/route', $route->getPath());\n        $this->assertSame(MyController::class.'::__invoke', $route->getDefault('_controller'));\n    }\n\n    public static function providePsr4ConfigFiles(): array\n    {\n        return [\n            ['psr4-attributes.php'],\n            ['psr4-controllers-redirection.php'],\n        ];\n    }\n\n    public function testImportAttributesFromClass()\n    {\n        new LoaderResolver([\n            $loader = new PhpFileLoader(new FileLocator(\\dirname(__DIR__).'/Fixtures')),\n            new class extends AttributeClassLoader {\n                protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n                {\n                    $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                }\n            },\n        ]);\n\n        $route = $loader->load('class-attributes.php')->get('my_route');\n        $this->assertSame('/my-prefix/my/route', $route->getPath());\n        $this->assertSame(MyController::class.'::__invoke', $route->getDefault('_controller'));\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/Psr4DirectoryLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Config\\Loader\\DelegatingLoader;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolver;\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Loader\\AttributeClassLoader;\nuse Symfony\\Component\\Routing\\Loader\\Psr4DirectoryLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\MyController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace\\EvenDeeperNamespace\\MyOtherController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace\\MyChildController;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\SubNamespace\\MyControllerWithATrait;\n\nclass Psr4DirectoryLoaderTest extends TestCase\n{\n    public function testTopLevelController()\n    {\n        $route = $this->loadPsr4Controllers()->get('my_route');\n\n        $this->assertSame('/my/route', $route->getPath());\n        $this->assertSame(MyController::class.'::__invoke', $route->getDefault('_controller'));\n    }\n\n    public function testNestedController()\n    {\n        $collection = $this->loadPsr4Controllers();\n\n        $route = $collection->get('my_other_controller_one');\n        $this->assertSame('/my/other/route/first', $route->getPath());\n        $this->assertSame(['PUT'], $route->getMethods());\n        $this->assertSame(MyOtherController::class.'::firstAction', $route->getDefault('_controller'));\n\n        $route = $collection->get('my_other_controller_two');\n        $this->assertSame('/my/other/route/second', $route->getPath());\n        $this->assertSame(['PUT'], $route->getMethods());\n        $this->assertSame(MyOtherController::class.'::secondAction', $route->getDefault('_controller'));\n    }\n\n    public function testTraitController()\n    {\n        $route = $this->loadPsr4Controllers()->get('my_controller_with_a_trait');\n\n        $this->assertSame('/my/controller/with/a/trait/a/route/from/a/trait', $route->getPath());\n        $this->assertSame(MyControllerWithATrait::class.'::someAction', $route->getDefault('_controller'));\n    }\n\n    public function testAbstractController()\n    {\n        $route = $this->loadPsr4Controllers()->get('my_child_controller_from_abstract');\n\n        $this->assertSame('/my/child/controller/a/route/from/an/abstract/controller', $route->getPath());\n        $this->assertSame(MyChildController::class.'::someAction', $route->getDefault('_controller'));\n    }\n\n    public function testExcludeSubNamespace()\n    {\n        $fixturesPath = \\dirname(__DIR__).'/Fixtures';\n        $excluded = [\n            rtrim(str_replace('\\\\', '/', $fixturesPath.'/Psr4Controllers/SubNamespace'), '/') => true,\n        ];\n        $collection = $this->getLoader()->load(\n            ['path' => 'Psr4Controllers', 'namespace' => 'Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers', '_excluded' => $excluded],\n            'attribute'\n        );\n\n        $this->assertNotNull($collection->get('my_route'));\n        $this->assertNull($collection->get('my_other_controller_one'));\n        $this->assertNull($collection->get('my_controller_with_a_trait'));\n        $this->assertNull($collection->get('my_child_controller_from_abstract'));\n    }\n\n    public function testExcludeSingleFile()\n    {\n        $fixturesPath = \\dirname(__DIR__).'/Fixtures';\n        $excluded = [\n            rtrim(str_replace('\\\\', '/', $fixturesPath.'/Psr4Controllers/MyController.php'), '/') => true,\n        ];\n        $collection = $this->getLoader()->load(\n            ['path' => 'Psr4Controllers', 'namespace' => 'Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers', '_excluded' => $excluded],\n            'attribute'\n        );\n\n        $this->assertNull($collection->get('my_route'));\n        $this->assertNotNull($collection->get('my_other_controller_one'));\n    }\n\n    #[DataProvider('provideNamespacesThatNeedTrimming')]\n    public function testPsr4NamespaceTrim(string $namespace)\n    {\n        $route = $this->getLoader()\n            ->load(\n                ['path' => 'Psr4Controllers', 'namespace' => $namespace],\n                'attribute',\n            )\n            ->get('my_route');\n\n        $this->assertSame('/my/route', $route->getPath());\n        $this->assertSame(MyController::class.'::__invoke', $route->getDefault('_controller'));\n    }\n\n    public static function provideNamespacesThatNeedTrimming(): array\n    {\n        return [\n            ['\\\\Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers'],\n            ['Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\\\'],\n            ['\\\\Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\\\'],\n        ];\n    }\n\n    #[DataProvider('provideInvalidPsr4Namespaces')]\n    public function testInvalidPsr4Namespace(string $namespace, string $expectedExceptionMessage)\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage($expectedExceptionMessage);\n\n        $this->getLoader()->load(\n            ['path' => 'Psr4Controllers', 'namespace' => $namespace],\n            'attribute'\n        );\n    }\n\n    public static function provideInvalidPsr4Namespaces(): array\n    {\n        return [\n            'slash instead of back-slash' => [\n                'namespace' => 'App\\Application/Controllers',\n                'expectedExceptionMessage' => 'Namespace \"App\\Application/Controllers\" is not a valid PSR-4 prefix.',\n            ],\n            'invalid namespace' => [\n                'namespace' => 'App\\Contro llers',\n                'expectedExceptionMessage' => 'Namespace \"App\\Contro llers\" is not a valid PSR-4 prefix.',\n            ],\n        ];\n    }\n\n    private function loadPsr4Controllers(): RouteCollection\n    {\n        return $this->getLoader()->load(\n            ['path' => 'Psr4Controllers', 'namespace' => 'Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers'],\n            'attribute'\n        );\n    }\n\n    private function getLoader(): DelegatingLoader\n    {\n        $locator = new FileLocator(\\dirname(__DIR__).'/Fixtures');\n\n        return new DelegatingLoader(\n            new LoaderResolver([\n                new Psr4DirectoryLoader($locator),\n                new class extends AttributeClassLoader {\n                    protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n                    {\n                        $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                    }\n                },\n            ])\n        );\n    }\n}\n"
  },
  {
    "path": "Tests/Loader/YamlFileLoaderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Loader;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Config\\FileLocatorInterface;\nuse Symfony\\Component\\Config\\Loader\\LoaderResolver;\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Loader\\AttributeClassLoader;\nuse Symfony\\Component\\Routing\\Loader\\Psr4DirectoryLoader;\nuse Symfony\\Component\\Routing\\Loader\\YamlFileLoader;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Psr4Controllers\\MyController;\n\nclass YamlFileLoaderTest extends TestCase\n{\n    public function testSupports()\n    {\n        $loader = new YamlFileLoader($this->createStub(FileLocatorInterface::class));\n\n        $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable');\n        $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable');\n        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');\n\n        $this->assertTrue($loader->supports('foo.yml', 'yaml'), '->supports() checks the resource type if specified');\n        $this->assertTrue($loader->supports('foo.yaml', 'yaml'), '->supports() checks the resource type if specified');\n        $this->assertFalse($loader->supports('foo.yml', 'foo'), '->supports() checks the resource type if specified');\n    }\n\n    public function testLoadDoesNothingIfEmpty()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $collection = $loader->load('empty.yml');\n\n        $this->assertEquals([], $collection->all());\n        $this->assertEquals([new FileResource(realpath(__DIR__.'/../Fixtures/empty.yml'))], $collection->getResources());\n    }\n\n    #[DataProvider('getPathsToInvalidFiles')]\n    public function testLoadThrowsExceptionWithInvalidFile(string $filePath)\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $loader->load($filePath);\n    }\n\n    public static function getPathsToInvalidFiles()\n    {\n        return [\n            ['nonvalid.yml'],\n            ['nonvalid2.yml'],\n            ['incomplete.yml'],\n            ['nonvalidkeys.yml'],\n            ['nonesense_resource_plus_path.yml'],\n            ['nonesense_type_without_resource.yml'],\n            ['bad_format.yml'],\n            ['alias/invalid-alias.yaml'],\n            ['alias/invalid-deprecated-no-package.yaml'],\n            ['alias/invalid-deprecated-no-version.yaml'],\n        ];\n    }\n\n    public function testLoadSpecialRouteName()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routeCollection = $loader->load('special_route_name.yml');\n        $route = $routeCollection->get('#$péß^a|');\n\n        $this->assertInstanceOf(Route::class, $route);\n        $this->assertSame('/true', $route->getPath());\n    }\n\n    public function testLoadWithRoute()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routeCollection = $loader->load('validpattern.yml');\n        $route = $routeCollection->get('blog_show');\n\n        $this->assertInstanceOf(Route::class, $route);\n        $this->assertSame('/blog/{slug}', $route->getPath());\n        $this->assertSame('{locale}.example.com', $route->getHost());\n        $this->assertSame('MyBundle:Blog:show', $route->getDefault('_controller'));\n        $this->assertSame('\\w+', $route->getRequirement('locale'));\n        $this->assertSame('RouteCompiler', $route->getOption('compiler_class'));\n        $this->assertEquals(['GET', 'POST', 'PUT', 'OPTIONS'], $route->getMethods());\n        $this->assertEquals(['https'], $route->getSchemes());\n        $this->assertEquals('context.getMethod() == \"GET\"', $route->getCondition());\n        $this->assertTrue($route->getDefault('_stateless'));\n    }\n\n    public function testLoadWithResource()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routeCollection = $loader->load('validresource.yml');\n        $routes = $routeCollection->all();\n\n        $this->assertCount(2, $routes, 'Two routes are loaded');\n        $this->assertContainsOnlyInstancesOf(Route::class, $routes);\n\n        foreach ($routes as $route) {\n            $this->assertSame('/{foo}/blog/{slug}', $route->getPath());\n            $this->assertSame('123', $route->getDefault('foo'));\n            $this->assertSame('\\d+', $route->getRequirement('foo'));\n            $this->assertSame('bar', $route->getOption('foo'));\n            $this->assertSame('', $route->getHost());\n            $this->assertSame('context.getMethod() == \"POST\"', $route->getCondition());\n        }\n    }\n\n    public function testLoadRouteWithControllerAttribute()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller']));\n        $routeCollection = $loader->load('routing.yml');\n\n        $route = $routeCollection->get('app_homepage');\n\n        $this->assertSame('AppBundle:Homepage:show', $route->getDefault('_controller'));\n    }\n\n    public function testLoadRouteWithoutControllerAttribute()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller']));\n        $routeCollection = $loader->load('routing.yml');\n\n        $route = $routeCollection->get('app_logout');\n\n        $this->assertNull($route->getDefault('_controller'));\n    }\n\n    public function testLoadRouteWithControllerSetInDefaults()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller']));\n        $routeCollection = $loader->load('routing.yml');\n\n        $route = $routeCollection->get('app_blog');\n\n        $this->assertSame('AppBundle:Blog:list', $route->getDefault('_controller'));\n    }\n\n    public function testOverrideControllerInDefaults()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller']));\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('/The routing file \"[^\"]*\" must not specify both the \"controller\" key and the defaults key \"_controller\" for \"app_blog\"/');\n\n        $loader->load('override_defaults.yml');\n    }\n\n    #[DataProvider('provideFilesImportingRoutesWithControllers')]\n    public function testImportRouteWithController($file)\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller']));\n        $routeCollection = $loader->load($file);\n\n        $route = $routeCollection->get('app_homepage');\n        $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));\n\n        $route = $routeCollection->get('app_blog');\n        $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));\n\n        $route = $routeCollection->get('app_logout');\n        $this->assertSame('FrameworkBundle:Template:template', $route->getDefault('_controller'));\n    }\n\n    public static function provideFilesImportingRoutesWithControllers()\n    {\n        yield ['import_controller.yml'];\n        yield ['import__controller.yml'];\n    }\n\n    public function testImportWithOverriddenController()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/controller']));\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessageMatches('/The routing file \"[^\"]*\" must not specify both the \"controller\" key and the defaults key \"_controller\" for \"_static\"/');\n\n        $loader->load('import_override_defaults.yml');\n    }\n\n    public function testImportRouteWithGlobMatchingSingleFile()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/glob']));\n        $routeCollection = $loader->load('import_single.yml');\n\n        $route = $routeCollection->get('bar_route');\n        $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));\n    }\n\n    public function testImportRouteWithGlobMatchingMultipleFiles()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/glob']));\n        $routeCollection = $loader->load('import_multiple.yml');\n\n        $route = $routeCollection->get('bar_route');\n        $this->assertSame('AppBundle:Bar:view', $route->getDefault('_controller'));\n\n        $route = $routeCollection->get('baz_route');\n        $this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));\n    }\n\n    public function testImportRouteWithNamePrefix()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/import_with_name_prefix']));\n        $routeCollection = $loader->load('routing.yml');\n\n        $this->assertNotNull($routeCollection->get('app_blog'));\n        $this->assertEquals('/blog', $routeCollection->get('app_blog')->getPath());\n        $this->assertNotNull($routeCollection->get('api_app_blog'));\n        $this->assertEquals('/api/blog', $routeCollection->get('api_app_blog')->getPath());\n    }\n\n    public function testRemoteSourcesAreNotAccepted()\n    {\n        $loader = new YamlFileLoader(new FileLocatorStub());\n        $this->expectException(\\InvalidArgumentException::class);\n        $loader->load('http://remote.com/here.yml');\n    }\n\n    public function testLoadingRouteWithDefaults()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routes = $loader->load('defaults.yml');\n\n        $this->assertCount(1, $routes);\n\n        $defaultsRoute = $routes->get('defaults');\n\n        $this->assertSame('/defaults', $defaultsRoute->getPath());\n        $this->assertSame('en', $defaultsRoute->getDefault('_locale'));\n        $this->assertSame('html', $defaultsRoute->getDefault('_format'));\n        $this->assertTrue($defaultsRoute->getDefault('_stateless'));\n    }\n\n    public function testLoadingImportedRoutesWithDefaults()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n        $routes = $loader->load('importer-with-defaults.yml');\n\n        $this->assertCount(2, $routes);\n\n        $expectedRoutes = new RouteCollection();\n        $expectedRoutes->add('one', $localeRoute = new Route('/defaults/one'));\n        $localeRoute->setDefault('_locale', 'g_locale');\n        $localeRoute->setDefault('_format', 'g_format');\n        $localeRoute->setDefault('_stateless', true);\n        $expectedRoutes->add('two', $formatRoute = new Route('/defaults/two'));\n        $formatRoute->setDefault('_locale', 'g_locale');\n        $formatRoute->setDefault('_format', 'g_format');\n        $formatRoute->setDefault('_stateless', true);\n        $formatRoute->setDefault('specific', 'imported');\n\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/imported-with-defaults.yml'));\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/importer-with-defaults.yml'));\n\n        $this->assertEquals($expectedRoutes, $routes);\n    }\n\n    public function testLoadingUtf8Route()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('utf8.yml');\n\n        $this->assertCount(2, $routes);\n\n        $expectedRoutes = new RouteCollection();\n        $expectedRoutes->add('some_route', new Route('/'));\n\n        $expectedRoutes->add('some_utf8_route', $route = new Route('/utf8'));\n        $route->setOption('utf8', true);\n\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/localized/utf8.yml'));\n\n        $this->assertEquals($expectedRoutes, $routes);\n    }\n\n    public function testLoadingUtf8ImportedRoutes()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('importer-with-utf8.yml');\n\n        $this->assertCount(2, $routes);\n\n        $expectedRoutes = new RouteCollection();\n        $expectedRoutes->add('utf8_one', $one = new Route('/one'));\n        $one->setOption('utf8', true);\n\n        $expectedRoutes->add('utf8_two', $two = new Route('/two'));\n        $two->setOption('utf8', true);\n\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/localized/imported-with-utf8.yml'));\n        $expectedRoutes->addResource(new FileResource(__DIR__.'/../Fixtures/localized/importer-with-utf8.yml'));\n\n        $this->assertEquals($expectedRoutes, $routes);\n    }\n\n    public function testLoadingLocalizedRoute()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('localized-route.yml');\n\n        $this->assertCount(3, $routes);\n    }\n\n    public function testImportingRoutesFromDefinition()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('importing-localized-route.yml');\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('/nl', $routes->get('home.nl')->getPath());\n        $this->assertEquals('/en', $routes->get('home.en')->getPath());\n        $this->assertEquals('/here', $routes->get('not_localized')->getPath());\n    }\n\n    public function testImportingRoutesWithLocales()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('importer-with-locale.yml');\n\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/nl/voorbeeld', $routes->get('imported.nl')->getPath());\n        $this->assertEquals('/en/example', $routes->get('imported.en')->getPath());\n\n        $this->assertEquals('nl', $routes->get('imported.nl')->getRequirement('_locale'));\n        $this->assertEquals('en', $routes->get('imported.en')->getRequirement('_locale'));\n    }\n\n    public function testImportingNonLocalizedRoutesWithLocales()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('importer-with-locale-imports-non-localized-route.yml');\n\n        $this->assertCount(2, $routes);\n        $this->assertEquals('/nl/imported', $routes->get('imported.nl')->getPath());\n        $this->assertEquals('/en/imported', $routes->get('imported.en')->getPath());\n\n        $this->assertSame('nl', $routes->get('imported.nl')->getRequirement('_locale'));\n        $this->assertSame('en', $routes->get('imported.en')->getRequirement('_locale'));\n    }\n\n    public function testImportingRoutesWithOfficialLocales()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('officially_formatted_locales.yml');\n\n        $this->assertCount(3, $routes);\n        $this->assertEquals('/omelette-au-fromage', $routes->get('official.fr.UTF-8')->getPath());\n        $this->assertEquals('/eu-não-sou-espanhol', $routes->get('official.pt-PT')->getPath());\n        $this->assertEquals('/churrasco', $routes->get('official.pt_BR')->getPath());\n    }\n\n    public function testImportingRoutesFromDefinitionMissingLocalePrefix()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $this->expectException(\\InvalidArgumentException::class);\n        $loader->load('missing-locale-in-importer.yml');\n    }\n\n    public function testImportingRouteWithoutPathOrLocales()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $this->expectException(\\InvalidArgumentException::class);\n        $loader->load('route-without-path-or-locales.yml');\n    }\n\n    public function testImportingWithControllerDefault()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/localized']));\n        $routes = $loader->load('importer-with-controller-default.yml');\n        $this->assertCount(3, $routes);\n        $this->assertEquals('DefaultController::defaultAction', $routes->get('home.en')->getDefault('_controller'));\n        $this->assertEquals('DefaultController::defaultAction', $routes->get('home.nl')->getDefault('_controller'));\n        $this->assertEquals('DefaultController::defaultAction', $routes->get('not_localized')->getDefault('_controller'));\n    }\n\n    public function testImportRouteWithNoTrailingSlash()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/import_with_no_trailing_slash']));\n        $routeCollection = $loader->load('routing.yml');\n\n        $this->assertEquals('/slash/', $routeCollection->get('a_app_homepage')->getPath());\n        $this->assertEquals('/no-slash', $routeCollection->get('b_app_homepage')->getPath());\n    }\n\n    public function testRequirementsWithoutPlaceholderName()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']));\n\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('A placeholder name must be a string (0 given). Did you forget to specify the placeholder key for the requirement \"\\\\d+\" of route \"foo\"');\n\n        $loader->load('requirements_without_placeholder_name.yml');\n    }\n\n    public function testImportingRoutesWithHostsInImporter()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-with-host.yml');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-with-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('yml'), $routes);\n    }\n\n    public function testImportingRoutesWithLocalesAndHostInImporter()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-with-locale-and-host.yml');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-with-locale-and-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('yml'), $routes);\n    }\n\n    public function testImportingRoutesWithoutHostInImporter()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-without-host.yml');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-without-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('yml'), $routes);\n    }\n\n    public function testImportingRoutesWithSingleHostInImporter()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('importer-with-single-host.yml');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/import-with-single-host-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('yml'), $routes);\n    }\n\n    public function testAddingRouteWithHosts()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/locale_and_host']));\n        $routes = $loader->load('route-with-hosts.yml');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/locale_and_host/route-with-hosts-expected-collection.php';\n\n        $this->assertEquals($expectedRoutes('yml'), $routes);\n    }\n\n    public function testWhenEnv()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures']), 'some-env');\n        $routes = $loader->load('when-env.yml');\n\n        $this->assertSame(['b', 'a'], array_keys($routes->all()));\n        $this->assertSame('/b', $routes->get('b')->getPath());\n        $this->assertSame('/a1', $routes->get('a')->getPath());\n    }\n\n    public function testImportingAliases()\n    {\n        $loader = new YamlFileLoader(new FileLocator([__DIR__.'/../Fixtures/alias']));\n        $routes = $loader->load('alias.yaml');\n\n        $expectedRoutes = require __DIR__.'/../Fixtures/alias/expected.php';\n\n        $this->assertEquals($expectedRoutes('yaml'), $routes);\n    }\n\n    public function testPriorityWithPrefix()\n    {\n        new LoaderResolver([\n            $loader = new YamlFileLoader(new FileLocator(\\dirname(__DIR__).'/Fixtures/localized')),\n            new class extends AttributeClassLoader {\n                protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n                {\n                    $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                }\n            },\n        ]);\n\n        $routes = $loader->load('localized-prefix.yml');\n\n        $this->assertSame(2, $routes->getPriority('important.cs'));\n        $this->assertSame(2, $routes->getPriority('important.en'));\n        $this->assertSame(1, $routes->getPriority('also_important'));\n    }\n\n    public function testPriorityWithHost()\n    {\n        new LoaderResolver([\n            $loader = new YamlFileLoader(new FileLocator(\\dirname(__DIR__).'/Fixtures/locale_and_host')),\n            new class extends AttributeClassLoader {\n                protected function configureRoute(\n                    Route $route,\n                    \\ReflectionClass $class,\n                    \\ReflectionMethod $method,\n                    object $annot,\n                ): void {\n                    $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                }\n            },\n        ]);\n\n        $routes = $loader->load('priorized-host.yml');\n\n        $this->assertSame(2, $routes->getPriority('important.cs'));\n        $this->assertSame(2, $routes->getPriority('important.en'));\n        $this->assertSame(1, $routes->getPriority('also_important'));\n    }\n\n    #[DataProvider('providePsr4ConfigFiles')]\n    public function testImportAttributesWithPsr4Prefix(string $configFile)\n    {\n        $locator = new FileLocator(\\dirname(__DIR__).'/Fixtures');\n        new LoaderResolver([\n            $loader = new YamlFileLoader($locator),\n            new Psr4DirectoryLoader($locator),\n            new class extends AttributeClassLoader {\n                protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n                {\n                    $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                }\n            },\n        ]);\n\n        $route = $loader->load($configFile)->get('my_route');\n        $this->assertSame('/my-prefix/my/route', $route->getPath());\n        $this->assertSame(MyController::class.'::__invoke', $route->getDefault('_controller'));\n    }\n\n    public static function providePsr4ConfigFiles(): array\n    {\n        return [\n            ['psr4-attributes.yaml'],\n            ['psr4-controllers-redirection.yaml'],\n        ];\n    }\n\n    public function testImportAttributesFromClass()\n    {\n        new LoaderResolver([\n            $loader = new YamlFileLoader(new FileLocator(\\dirname(__DIR__).'/Fixtures')),\n            new class extends AttributeClassLoader {\n                protected function configureRoute(Route $route, \\ReflectionClass $class, \\ReflectionMethod $method, object $attr): void\n                {\n                    $route->setDefault('_controller', $class->getName().'::'.$method->getName());\n                }\n            },\n        ]);\n\n        $route = $loader->load('class-attributes.yaml')->get('my_route');\n        $this->assertSame('/my-prefix/my/route', $route->getPath());\n        $this->assertSame(MyController::class.'::__invoke', $route->getDefault('_controller'));\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/CompiledRedirectableUrlMatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher;\n\nuse Symfony\\Component\\Routing\\Matcher\\CompiledUrlMatcher;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper;\nuse Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass CompiledRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest\n{\n    protected function getUrlMatcher(RouteCollection $routes, ?RequestContext $context = null, bool $mock = false)\n    {\n        $dumper = new CompiledUrlMatcherDumper($routes);\n        $compiledRoutes = $dumper->getCompiledRoutes();\n\n        if (!$mock) {\n            return new TestCompiledRedirectableUrlMatcher($compiledRoutes, $context ?? new RequestContext());\n        }\n\n        return $this->getMockBuilder(TestCompiledRedirectableUrlMatcher::class)\n            ->setConstructorArgs([$compiledRoutes, $context ?? new RequestContext()])\n            ->onlyMethods(['redirect'])\n            ->getMock();\n    }\n}\n\nclass TestCompiledRedirectableUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface\n{\n    public function redirect(string $path, string $route, ?string $scheme = null): array\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/CompiledUrlMatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher;\n\nuse Symfony\\Component\\Routing\\Matcher\\CompiledUrlMatcher;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcher;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass CompiledUrlMatcherTest extends UrlMatcherTest\n{\n    public function testStaticHostIsCaseInsensitive()\n    {\n        $collection = new RouteCollection();\n        $collection->add('static_host_route', new Route('/test', [], [], [], 'API.example.com'));\n\n        $context = new RequestContext('/test', 'GET', 'api.example.com');\n        $matcher = new UrlMatcher($collection, $context);\n\n        $result = $matcher->match('/test');\n        $this->assertEquals('static_host_route', $result['_route'], 'UrlMatcher should match case-insensitive host');\n\n        $dumper = new CompiledUrlMatcherDumper($collection);\n        $compiledRoutes = $dumper->getCompiledRoutes();\n\n        $compiledMatcher = new CompiledUrlMatcher($compiledRoutes, $context);\n\n        $result = $compiledMatcher->match('/test');\n        $this->assertEquals('static_host_route', $result['_route'], 'CompiledUrlMatcher should match case-insensitive host');\n    }\n\n    protected function getUrlMatcher(RouteCollection $routes, ?RequestContext $context = null)\n    {\n        $dumper = new CompiledUrlMatcherDumper($routes);\n\n        return new CompiledUrlMatcher($dumper->getCompiledRoutes(), $context ?? new RequestContext());\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/Dumper/CompiledUrlMatcherDumperTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher\\Dumper;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\FileLocator;\nuse Symfony\\Component\\Routing\\Loader\\Configurator\\RoutingConfigurator;\nuse Symfony\\Component\\Routing\\Loader\\PhpFileLoader;\nuse Symfony\\Component\\Routing\\Matcher\\CompiledUrlMatcher;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\CompiledUrlMatcherDumper;\nuse Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcherInterface;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass CompiledUrlMatcherDumperTest extends TestCase\n{\n    private string $dumpPath;\n\n    protected function setUp(): void\n    {\n        $this->dumpPath = tempnam(sys_get_temp_dir(), 'sf_matcher_');\n    }\n\n    protected function tearDown(): void\n    {\n        @unlink($this->dumpPath);\n    }\n\n    public function testRedirectPreservesUrlEncoding()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo:bar/'));\n\n        $matcher = $this->generateDumpedMatcher($collection);\n        $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/', 'foo')->willReturn([]);\n\n        $matcher->match('/foo%3Abar');\n    }\n\n    #[DataProvider('getRouteCollections')]\n    public function testDump(RouteCollection $collection, $fixture)\n    {\n        $basePath = __DIR__.'/../../Fixtures/dumper/';\n\n        $dumper = new CompiledUrlMatcherDumper($collection);\n        $this->assertStringEqualsFile($basePath.$fixture, $dumper->dump());\n    }\n\n    public static function getRouteCollections()\n    {\n        /* test case 1 */\n\n        $collection = new RouteCollection();\n\n        $collection->add('overridden', new Route('/overridden'));\n\n        // defaults and requirements\n        $collection->add('foo', new Route(\n            '/foo/{bar}',\n            ['def' => 'test'],\n            ['bar' => 'baz|symfony']\n        ));\n        // method requirement\n        $collection->add('bar', new Route(\n            '/bar/{foo}',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['GET', 'head']\n        ));\n        // GET method requirement automatically adds HEAD as valid\n        $collection->add('barhead', new Route(\n            '/barhead/{foo}',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['GET']\n        ));\n        // simple\n        $collection->add('baz', new Route(\n            '/test/baz'\n        ));\n        // simple with extension\n        $collection->add('baz2', new Route(\n            '/test/baz.html'\n        ));\n        // trailing slash\n        $collection->add('baz3', new Route(\n            '/test/baz3/'\n        ));\n        // trailing slash with variable\n        $collection->add('baz4', new Route(\n            '/test/{foo}/'\n        ));\n        // trailing slash and method\n        $collection->add('baz5', new Route(\n            '/test/{foo}/',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['post']\n        ));\n        // complex name\n        $collection->add('baz.baz6', new Route(\n            '/test/{foo}/',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['put']\n        ));\n        // defaults without variable\n        $collection->add('foofoo', new Route(\n            '/foofoo',\n            ['def' => 'test']\n        ));\n        // pattern with quotes\n        $collection->add('quoter', new Route(\n            '/{quoter}',\n            [],\n            ['quoter' => '[\\']+']\n        ));\n        // space in pattern\n        $collection->add('space', new Route(\n            '/spa ce'\n        ));\n\n        // prefixes\n        $collection1 = new RouteCollection();\n        $collection1->add('overridden', new Route('/overridden1'));\n        $collection1->add('foo1', (new Route('/{foo}'))->setMethods('PUT'));\n        $collection1->add('bar1', new Route('/{bar}'));\n        $collection1->addPrefix('/b\\'b');\n        $collection2 = new RouteCollection();\n        $collection2->addCollection($collection1);\n        $collection2->add('overridden', new Route('/{var}', [], ['var' => '.*']));\n        $collection1 = new RouteCollection();\n        $collection1->add('foo2', new Route('/{foo1}'));\n        $collection1->add('bar2', new Route('/{bar1}'));\n        $collection1->addPrefix('/b\\'b');\n        $collection2->addCollection($collection1);\n        $collection2->addPrefix('/a');\n        $collection->addCollection($collection2);\n\n        // overridden through addCollection() and multiple sub-collections with no own prefix\n        $collection1 = new RouteCollection();\n        $collection1->add('overridden2', new Route('/old'));\n        $collection1->add('helloWorld', new Route('/hello/{who}', ['who' => 'World!']));\n        $collection2 = new RouteCollection();\n        $collection3 = new RouteCollection();\n        $collection3->add('overridden2', new Route('/new'));\n        $collection3->add('hey', new Route('/hey/'));\n        $collection2->addCollection($collection3);\n        $collection1->addCollection($collection2);\n        $collection1->addPrefix('/multi');\n        $collection->addCollection($collection1);\n\n        // \"dynamic\" prefix\n        $collection1 = new RouteCollection();\n        $collection1->add('foo3', new Route('/{foo}'));\n        $collection1->add('bar3', new Route('/{bar}'));\n        $collection1->addPrefix('/b');\n        $collection1->addPrefix('{_locale}');\n        $collection->addCollection($collection1);\n\n        // route between collections\n        $collection->add('ababa', new Route('/ababa'));\n\n        // collection with static prefix but only one route\n        $collection1 = new RouteCollection();\n        $collection1->add('foo4', new Route('/{foo}'));\n        $collection1->addPrefix('/aba');\n        $collection->addCollection($collection1);\n\n        // prefix and host\n\n        $collection1 = new RouteCollection();\n\n        $route1 = new Route('/route1', [], [], [], 'a.example.com');\n        $collection1->add('route1', $route1);\n\n        $route2 = new Route('/c2/route2', [], [], [], 'a.example.com');\n        $collection1->add('route2', $route2);\n\n        $route3 = new Route('/c2/route3', [], [], [], 'b.example.com');\n        $collection1->add('route3', $route3);\n\n        $route4 = new Route('/route4', [], [], [], 'a.example.com');\n        $collection1->add('route4', $route4);\n\n        $route5 = new Route('/route5', [], [], [], 'c.example.com');\n        $collection1->add('route5', $route5);\n\n        $route6 = new Route('/route6', [], [], [], null);\n        $collection1->add('route6', $route6);\n\n        $collection->addCollection($collection1);\n\n        // host and variables\n\n        $collection1 = new RouteCollection();\n\n        $route11 = new Route('/route11', [], [], [], '{var1}.example.com');\n        $collection1->add('route11', $route11);\n\n        $route12 = new Route('/route12', ['var1' => 'val'], [], [], '{var1}.example.com');\n        $collection1->add('route12', $route12);\n\n        $route13 = new Route('/route13/{name}', [], [], [], '{var1}.example.com');\n        $collection1->add('route13', $route13);\n\n        $route14 = new Route('/route14/{name}', ['var1' => 'val'], [], [], '{var1}.example.com');\n        $collection1->add('route14', $route14);\n\n        $route15 = new Route('/route15/{name}', [], [], [], 'c.example.com');\n        $collection1->add('route15', $route15);\n\n        $route16 = new Route('/route16/{name}', ['var1' => 'val'], [], [], null);\n        $collection1->add('route16', $route16);\n\n        $route17 = new Route('/route17', [], [], [], null);\n        $collection1->add('route17', $route17);\n\n        $collection->addCollection($collection1);\n\n        // multiple sub-collections with a single route and a prefix each\n        $collection1 = new RouteCollection();\n        $collection1->add('a', new Route('/a...'));\n        $collection2 = new RouteCollection();\n        $collection2->add('b', new Route('/{var}'));\n        $collection3 = new RouteCollection();\n        $collection3->add('c', new Route('/{var}'));\n        $collection3->addPrefix('/c');\n        $collection2->addCollection($collection3);\n        $collection2->addPrefix('/b');\n        $collection1->addCollection($collection2);\n        $collection1->addPrefix('/a');\n        $collection->addCollection($collection1);\n\n        /* test case 2 */\n\n        $redirectCollection = clone $collection;\n\n        // force HTTPS redirection\n        $redirectCollection->add('secure', new Route(\n            '/secure',\n            [],\n            [],\n            [],\n            '',\n            ['https']\n        ));\n\n        // force HTTP redirection\n        $redirectCollection->add('nonsecure', new Route(\n            '/nonsecure',\n            [],\n            [],\n            [],\n            '',\n            ['http']\n        ));\n\n        /* test case 3 */\n\n        $rootprefixCollection = new RouteCollection();\n        $rootprefixCollection->add('static', new Route('/test'));\n        $rootprefixCollection->add('dynamic', new Route('/{var}'));\n        $rootprefixCollection->addPrefix('rootprefix');\n        $route = new Route('/with-condition');\n        $route->setCondition('context.getMethod() == \"GET\"');\n        $rootprefixCollection->add('with-condition', $route);\n        $route = new Route('/with-condition/{id}');\n        $route->setRequirement('id', '\\d+');\n        $route->setCondition(\"params['id'] < 100\");\n        $rootprefixCollection->add('with-condition-dynamic', $route);\n\n        /* test case 4 */\n        $headMatchCasesCollection = new RouteCollection();\n        $headMatchCasesCollection->add('just_head', new Route(\n            '/just_head',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['HEAD']\n        ));\n        $headMatchCasesCollection->add('head_and_get', new Route(\n            '/head_and_get',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['HEAD', 'GET']\n        ));\n        $headMatchCasesCollection->add('get_and_head', new Route(\n            '/get_and_head',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['GET', 'HEAD']\n        ));\n        $headMatchCasesCollection->add('post_and_head', new Route(\n            '/post_and_head',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['POST', 'HEAD']\n        ));\n        $headMatchCasesCollection->add('put_and_post', new Route(\n            '/put_and_post',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['PUT', 'POST']\n        ));\n        $headMatchCasesCollection->add('put_and_get_and_head', new Route(\n            '/put_and_post',\n            [],\n            [],\n            [],\n            '',\n            [],\n            ['PUT', 'GET', 'HEAD']\n        ));\n\n        /* test case 5 */\n        $groupOptimisedCollection = new RouteCollection();\n        $groupOptimisedCollection->add('a_first', new Route('/a/11'));\n        $groupOptimisedCollection->add('a_second', new Route('/a/22'));\n        $groupOptimisedCollection->add('a_third', new Route('/a/333'));\n        $groupOptimisedCollection->add('a_wildcard', new Route('/{param}'));\n        $groupOptimisedCollection->add('a_fourth', new Route('/a/44/'));\n        $groupOptimisedCollection->add('a_fifth', new Route('/a/55/'));\n        $groupOptimisedCollection->add('a_sixth', new Route('/a/66/'));\n        $groupOptimisedCollection->add('nested_wildcard', new Route('/nested/{param}'));\n        $groupOptimisedCollection->add('nested_a', new Route('/nested/group/a/'));\n        $groupOptimisedCollection->add('nested_b', new Route('/nested/group/b/'));\n        $groupOptimisedCollection->add('nested_c', new Route('/nested/group/c/'));\n\n        $groupOptimisedCollection->add('slashed_a', new Route('/slashed/group/'));\n        $groupOptimisedCollection->add('slashed_b', new Route('/slashed/group/b/'));\n        $groupOptimisedCollection->add('slashed_c', new Route('/slashed/group/c/'));\n\n        /* test case 6 & 7 */\n        $trailingSlashCollection = new RouteCollection();\n        $trailingSlashCollection->add('simple_trailing_slash_no_methods', new Route('/trailing/simple/no-methods/', [], [], [], '', [], []));\n        $trailingSlashCollection->add('simple_trailing_slash_GET_method', new Route('/trailing/simple/get-method/', [], [], [], '', [], ['GET']));\n        $trailingSlashCollection->add('simple_trailing_slash_HEAD_method', new Route('/trailing/simple/head-method/', [], [], [], '', [], ['HEAD']));\n        $trailingSlashCollection->add('simple_trailing_slash_POST_method', new Route('/trailing/simple/post-method/', [], [], [], '', [], ['POST']));\n        $trailingSlashCollection->add('regex_trailing_slash_no_methods', new Route('/trailing/regex/no-methods/{param}/', [], [], [], '', [], []));\n        $trailingSlashCollection->add('regex_trailing_slash_GET_method', new Route('/trailing/regex/get-method/{param}/', [], [], [], '', [], ['GET']));\n        $trailingSlashCollection->add('regex_trailing_slash_HEAD_method', new Route('/trailing/regex/head-method/{param}/', [], [], [], '', [], ['HEAD']));\n        $trailingSlashCollection->add('regex_trailing_slash_POST_method', new Route('/trailing/regex/post-method/{param}/', [], [], [], '', [], ['POST']));\n\n        $trailingSlashCollection->add('simple_not_trailing_slash_no_methods', new Route('/not-trailing/simple/no-methods', [], [], [], '', [], []));\n        $trailingSlashCollection->add('simple_not_trailing_slash_GET_method', new Route('/not-trailing/simple/get-method', [], [], [], '', [], ['GET']));\n        $trailingSlashCollection->add('simple_not_trailing_slash_HEAD_method', new Route('/not-trailing/simple/head-method', [], [], [], '', [], ['HEAD']));\n        $trailingSlashCollection->add('simple_not_trailing_slash_POST_method', new Route('/not-trailing/simple/post-method', [], [], [], '', [], ['POST']));\n        $trailingSlashCollection->add('regex_not_trailing_slash_no_methods', new Route('/not-trailing/regex/no-methods/{param}', [], [], [], '', [], []));\n        $trailingSlashCollection->add('regex_not_trailing_slash_GET_method', new Route('/not-trailing/regex/get-method/{param}', [], [], [], '', [], ['GET']));\n        $trailingSlashCollection->add('regex_not_trailing_slash_HEAD_method', new Route('/not-trailing/regex/head-method/{param}', [], [], [], '', [], ['HEAD']));\n        $trailingSlashCollection->add('regex_not_trailing_slash_POST_method', new Route('/not-trailing/regex/post-method/{param}', [], [], [], '', [], ['POST']));\n\n        /* test case 8 */\n        $unicodeCollection = new RouteCollection();\n        $unicodeCollection->add('a', new Route('/{a}', [], ['a' => 'a'], ['utf8' => false]));\n        $unicodeCollection->add('b', new Route('/{a}', [], ['a' => '.'], ['utf8' => true]));\n        $unicodeCollection->add('c', new Route('/{a}', [], ['a' => '.'], ['utf8' => false]));\n\n        /* test case 9 */\n        $hostTreeCollection = new RouteCollection();\n        $hostTreeCollection->add('a', (new Route('/'))->setHost('{d}.e.c.b.a'));\n        $hostTreeCollection->add('b', (new Route('/'))->setHost('d.c.b.a'));\n        $hostTreeCollection->add('c', (new Route('/'))->setHost('{e}.e.c.b.a'));\n\n        /* test case 10 */\n        $chunkedCollection = new RouteCollection();\n        for ($i = 0; $i < 1000; ++$i) {\n            $h = substr(md5($i), 0, 6);\n            $chunkedCollection->add('_'.$i, new Route('/'.$h.'/{a}/{b}/{c}/'.$h));\n        }\n\n        /* test case 11 */\n        $demoCollection = new RouteCollection();\n        $demoCollection->add('a', new Route('/admin/post/'));\n        $demoCollection->add('b', new Route('/admin/post/new'));\n        $demoCollection->add('c', (new Route('/admin/post/{id}'))->setRequirements(['id' => '\\d+']));\n        $demoCollection->add('d', (new Route('/admin/post/{id}/edit'))->setRequirements(['id' => '\\d+']));\n        $demoCollection->add('e', (new Route('/admin/post/{id}/delete'))->setRequirements(['id' => '\\d+']));\n        $demoCollection->add('f', new Route('/blog/'));\n        $demoCollection->add('g', new Route('/blog/rss.xml'));\n        $demoCollection->add('h', (new Route('/blog/page/{page}'))->setRequirements(['id' => '\\d+']));\n        $demoCollection->add('i', (new Route('/blog/posts/{page}'))->setRequirements(['id' => '\\d+']));\n        $demoCollection->add('j', (new Route('/blog/comments/{id}/new'))->setRequirements(['id' => '\\d+']));\n        $demoCollection->add('k', new Route('/blog/search'));\n        $demoCollection->add('l', new Route('/login'));\n        $demoCollection->add('m', new Route('/logout'));\n        $demoCollection->addPrefix('/{_locale}');\n        $demoCollection->add('n', new Route('/{_locale}'));\n        $demoCollection->addRequirements(['_locale' => 'en|fr']);\n        $demoCollection->addDefaults(['_locale' => 'en']);\n\n        /* test case 12 */\n        $suffixCollection = new RouteCollection();\n        $suffixCollection->add('r1', new Route('abc{foo}/1'));\n        $suffixCollection->add('r2', new Route('abc{foo}/2'));\n        $suffixCollection->add('r10', new Route('abc{foo}/10'));\n        $suffixCollection->add('r20', new Route('abc{foo}/20'));\n        $suffixCollection->add('r100', new Route('abc{foo}/100'));\n        $suffixCollection->add('r200', new Route('abc{foo}/200'));\n\n        /* test case 13 */\n        $hostCollection = new RouteCollection();\n        $hostCollection->add('r1', (new Route('abc{foo}'))->setHost('{foo}.example.com'));\n        $hostCollection->add('r2', (new Route('abc{foo}'))->setHost('{foo}.example.com'));\n\n        /* test case 14 */\n        $fixedLocaleCollection = new RouteCollection();\n        $routes = new RoutingConfigurator($fixedLocaleCollection, new PhpFileLoader(new FileLocator()), __FILE__, __FILE__);\n        $routes\n            ->collection()\n            ->prefix('/{_locale}')\n            ->add('home', [\n                'fr' => 'accueil',\n                'en' => 'home',\n            ])\n        ;\n\n        return [\n            [new RouteCollection(), 'compiled_url_matcher0.php'],\n            [$collection, 'compiled_url_matcher1.php'],\n            [$redirectCollection, 'compiled_url_matcher2.php'],\n            [$rootprefixCollection, 'compiled_url_matcher3.php'],\n            [$headMatchCasesCollection, 'compiled_url_matcher4.php'],\n            [$groupOptimisedCollection, 'compiled_url_matcher5.php'],\n            [$trailingSlashCollection, 'compiled_url_matcher6.php'],\n            [$trailingSlashCollection, 'compiled_url_matcher7.php'],\n            [$unicodeCollection, 'compiled_url_matcher8.php'],\n            [$hostTreeCollection, 'compiled_url_matcher9.php'],\n            [$chunkedCollection, 'compiled_url_matcher10.php'],\n            [$demoCollection, 'compiled_url_matcher11.php'],\n            [$suffixCollection, 'compiled_url_matcher12.php'],\n            [$hostCollection, 'compiled_url_matcher13.php'],\n            [$fixedLocaleCollection, 'compiled_url_matcher14.php'],\n        ];\n    }\n\n    private function generateDumpedMatcher(RouteCollection $collection)\n    {\n        $dumper = new CompiledUrlMatcherDumper($collection);\n        $code = $dumper->dump();\n\n        file_put_contents($this->dumpPath, $code);\n        $compiledRoutes = require $this->dumpPath;\n\n        return $this->getMockBuilder(TestCompiledUrlMatcher::class)\n            ->setConstructorArgs([$compiledRoutes, new RequestContext()])\n            ->onlyMethods(['redirect'])\n            ->getMock();\n    }\n\n    public function testGenerateDumperMatcherWithObject()\n    {\n        $routeCollection = new RouteCollection();\n        $routeCollection->add('_', new Route('/', [new \\stdClass()]));\n        $dumper = new CompiledUrlMatcherDumper($routeCollection);\n\n        $this->expectExceptionMessage('Symfony\\Component\\Routing\\Route cannot contain objects, but \"stdClass\" given.');\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $dumper->dump();\n    }\n}\n\nclass TestCompiledUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface\n{\n    public function redirect(string $path, string $route, ?string $scheme = null): array\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/Dumper/StaticPrefixCollectionTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher\\Dumper;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Matcher\\Dumper\\StaticPrefixCollection;\nuse Symfony\\Component\\Routing\\Route;\n\nclass StaticPrefixCollectionTest extends TestCase\n{\n    #[DataProvider('routeProvider')]\n    public function testGrouping(array $routes, $expected)\n    {\n        $collection = new StaticPrefixCollection('/');\n\n        foreach ($routes as $route) {\n            [$path, $name] = $route;\n            $staticPrefix = (new Route($path))->compile()->getStaticPrefix();\n            $collection->addRoute($staticPrefix, [$name]);\n        }\n\n        $dumped = $this->dumpCollection($collection);\n        $this->assertEquals($expected, $dumped);\n    }\n\n    public static function routeProvider()\n    {\n        return [\n            'Simple - not nested' => [\n                [\n                    ['/', 'root'],\n                    ['/prefix/segment/', 'prefix_segment'],\n                    ['/leading/segment/', 'leading_segment'],\n                ],\n                <<<EOF\n                    root\n                    prefix_segment\n                    leading_segment\n                    EOF,\n            ],\n            'Nested - small group' => [\n                [\n                    ['/', 'root'],\n                    ['/prefix/segment/aa', 'prefix_segment'],\n                    ['/prefix/segment/bb', 'leading_segment'],\n                ],\n                <<<EOF\n                    root\n                    /prefix/segment/\n                    -> prefix_segment\n                    -> leading_segment\n                    EOF,\n            ],\n            'Nested - contains item at intersection' => [\n                [\n                    ['/', 'root'],\n                    ['/prefix/segment/', 'prefix_segment'],\n                    ['/prefix/segment/bb', 'leading_segment'],\n                ],\n                <<<EOF\n                    root\n                    /prefix/segment/\n                    -> prefix_segment\n                    -> leading_segment\n                    EOF,\n            ],\n            'Simple one level nesting' => [\n                [\n                    ['/', 'root'],\n                    ['/group/segment/', 'nested_segment'],\n                    ['/group/thing/', 'some_segment'],\n                    ['/group/other/', 'other_segment'],\n                ],\n                <<<EOF\n                    root\n                    /group/\n                    -> nested_segment\n                    -> some_segment\n                    -> other_segment\n                    EOF,\n            ],\n            'Retain matching order with groups' => [\n                [\n                    ['/group/aa/', 'aa'],\n                    ['/group/bb/', 'bb'],\n                    ['/group/cc/', 'cc'],\n                    ['/(.*)', 'root'],\n                    ['/group/dd/', 'dd'],\n                    ['/group/ee/', 'ee'],\n                    ['/group/ff/', 'ff'],\n                ],\n                <<<EOF\n                    /group/\n                    -> aa\n                    -> bb\n                    -> cc\n                    root\n                    /group/\n                    -> dd\n                    -> ee\n                    -> ff\n                    EOF,\n            ],\n            'Retain complex matching order with groups at base' => [\n                [\n                    ['/aaa/111/', 'first_aaa'],\n                    ['/prefixed/group/aa/', 'aa'],\n                    ['/prefixed/group/bb/', 'bb'],\n                    ['/prefixed/group/cc/', 'cc'],\n                    ['/prefixed/(.*)', 'root'],\n                    ['/prefixed/group/dd/', 'dd'],\n                    ['/prefixed/group/ee/', 'ee'],\n                    ['/prefixed/', 'parent'],\n                    ['/prefixed/group/ff/', 'ff'],\n                    ['/aaa/222/', 'second_aaa'],\n                    ['/aaa/333/', 'third_aaa'],\n                ],\n                <<<EOF\n                    /aaa/\n                    -> first_aaa\n                    -> second_aaa\n                    -> third_aaa\n                    /prefixed/\n                    -> /prefixed/group/\n                    -> -> aa\n                    -> -> bb\n                    -> -> cc\n                    -> root\n                    -> /prefixed/group/\n                    -> -> dd\n                    -> -> ee\n                    -> -> ff\n                    -> parent\n                    EOF,\n            ],\n\n            'Group regardless of segments' => [\n                [\n                    ['/aaa-111/', 'a1'],\n                    ['/aaa-222/', 'a2'],\n                    ['/aaa-333/', 'a3'],\n                    ['/group-aa/', 'g1'],\n                    ['/group-bb/', 'g2'],\n                    ['/group-cc/', 'g3'],\n                ],\n                <<<EOF\n                    /aaa-\n                    -> a1\n                    -> a2\n                    -> a3\n                    /group-\n                    -> g1\n                    -> g2\n                    -> g3\n                    EOF,\n            ],\n        ];\n    }\n\n    private function dumpCollection(StaticPrefixCollection $collection, $prefix = '')\n    {\n        $lines = [];\n\n        foreach ($collection->getRoutes() as $item) {\n            if ($item instanceof StaticPrefixCollection) {\n                $lines[] = $prefix.$item->getPrefix();\n                $lines[] = $this->dumpCollection($item, $prefix.'-> ');\n            } else {\n                $lines[] = $prefix.implode(' ', $item);\n            }\n        }\n\n        return implode(\"\\n\", $lines);\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/ExpressionLanguageProviderTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\DependencyInjection\\ServiceLocator;\nuse Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage;\nuse Symfony\\Component\\Routing\\Matcher\\ExpressionLanguageProvider;\nuse Symfony\\Component\\Routing\\RequestContext;\n\nclass ExpressionLanguageProviderTest extends TestCase\n{\n    private RequestContext $context;\n    private ExpressionLanguage $expressionLanguage;\n\n    protected function setUp(): void\n    {\n        $functionProvider = new ServiceLocator([\n            'env' => static fn () => static fn (string $arg) => [\n                'APP_ENV' => 'test',\n                'PHP_VERSION' => '7.2',\n            ][$arg] ?? null,\n            'sum' => static fn () => static fn ($a, $b) => $a + $b,\n            'foo' => static fn () => static fn () => 'bar',\n        ]);\n\n        $this->context = new RequestContext();\n        $this->context->setParameter('_functions', $functionProvider);\n\n        $this->expressionLanguage = new ExpressionLanguage();\n        $this->expressionLanguage->registerProvider(new ExpressionLanguageProvider($functionProvider));\n    }\n\n    #[DataProvider('compileProvider')]\n    public function testCompile(string $expression, string $expected)\n    {\n        $this->assertSame($expected, $this->expressionLanguage->compile($expression));\n    }\n\n    public static function compileProvider(): iterable\n    {\n        return [\n            ['env(\"APP_ENV\")', '($context->getParameter(\\'_functions\\')->get(\\'env\\')(\"APP_ENV\"))'],\n            ['sum(1, 2)', '($context->getParameter(\\'_functions\\')->get(\\'sum\\')(1, 2))'],\n            ['foo()', '($context->getParameter(\\'_functions\\')->get(\\'foo\\')())'],\n        ];\n    }\n\n    #[DataProvider('evaluateProvider')]\n    public function testEvaluate(string $expression, $expected)\n    {\n        $this->assertSame($expected, $this->expressionLanguage->evaluate($expression, ['context' => $this->context]));\n    }\n\n    public static function evaluateProvider(): iterable\n    {\n        return [\n            ['env(\"APP_ENV\")', 'test'],\n            ['env(\"PHP_VERSION\")', '7.2'],\n            ['env(\"unknown_env_variable\")', null],\n            ['sum(1, 2)', 3],\n            ['foo()', 'bar'],\n        ];\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/RedirectableUrlMatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher;\n\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\nuse Symfony\\Component\\Routing\\Matcher\\RedirectableUrlMatcher;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass RedirectableUrlMatcherTest extends UrlMatcherTest\n{\n    public function testMissingTrailingSlash()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->willReturn([]);\n        $matcher->match('/foo');\n    }\n\n    public function testExtraTrailingSlash()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo'));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->willReturn([]);\n        $matcher->match('/foo/');\n    }\n\n    public function testRedirectWhenNoSlashForNonSafeMethod()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/'));\n\n        $context = new RequestContext();\n        $context->setMethod('POST');\n        $matcher = $this->getUrlMatcher($coll, $context);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/foo');\n    }\n\n    public function testSchemeRedirectRedirectsToFirstScheme()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', ['FTP', 'HTTPS']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher\n            ->expects($this->once())\n            ->method('redirect')\n            ->with('/foo', 'foo', 'ftp')\n            ->willReturn(['_route' => 'foo'])\n        ;\n        $matcher->match('/foo');\n    }\n\n    public function testNoSchemaRedirectIfOneOfMultipleSchemesMatches()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', ['https', 'http']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher\n            ->expects($this->never())\n            ->method('redirect');\n        $matcher->match('/foo');\n    }\n\n    public function testSchemeRedirectWithParams()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{bar}', [], [], [], '', ['https']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher\n            ->expects($this->once())\n            ->method('redirect')\n            ->with('/foo/baz', 'foo', 'https')\n            ->willReturn(['redirect' => 'value'])\n        ;\n        $this->assertEquals(['_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'], $matcher->match('/foo/baz'));\n    }\n\n    public function testSchemeRedirectForRoot()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/', [], [], [], '', ['https']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher\n            ->expects($this->once())\n            ->method('redirect')\n            ->with('/', 'foo', 'https')\n            ->willReturn(['redirect' => 'value']);\n        $this->assertEquals(['_route' => 'foo', 'redirect' => 'value'], $matcher->match('/'));\n    }\n\n    public function testSlashRedirectWithParams()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{bar}/'));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher\n            ->expects($this->once())\n            ->method('redirect')\n            ->with('/foo/baz/', 'foo', null)\n            ->willReturn(['redirect' => 'value'])\n        ;\n        $this->assertEquals(['_route' => 'foo', 'bar' => 'baz', 'redirect' => 'value'], $matcher->match('/foo/baz'));\n    }\n\n    public function testRedirectPreservesUrlEncoding()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo:bar/'));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/')->willReturn([]);\n        $matcher->match('/foo%3Abar');\n    }\n\n    public function testSchemeRequirement()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', ['https']));\n        $matcher = $this->getUrlMatcher($coll, new RequestContext(), true);\n        $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo', 'https')->willReturn([]);\n        $this->assertSame(['_route' => 'foo'], $matcher->match('/foo'));\n    }\n\n    public function testFallbackPage()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/'));\n        $coll->add('bar', new Route('/{name}'));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->with('/foo/', 'foo')->willReturn(['_route' => 'foo']);\n        $this->assertSame(['_route' => 'foo'], $matcher->match('/foo'));\n\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo'));\n        $coll->add('bar', new Route('/{name}/'));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo')->willReturn(['_route' => 'foo']);\n        $this->assertSame(['_route' => 'foo'], $matcher->match('/foo/'));\n    }\n\n    public function testMissingTrailingSlashAndScheme()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', (new Route('/foo/'))->setSchemes(['https']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->with('/foo/', 'foo', 'https')->willReturn([]);\n        $matcher->match('/foo');\n    }\n\n    public function testSlashAndVerbPrecedenceWithRedirection()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/api/customers/{customerId}/contactpersons', [], [], [], '', [], ['post']));\n        $coll->add('b', new Route('/api/customers/{customerId}/contactpersons/', [], [], [], '', [], ['get']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $expected = [\n            '_route' => 'b',\n            'customerId' => '123',\n        ];\n        $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons/'));\n\n        $matcher->expects($this->once())->method('redirect')->with('/api/customers/123/contactpersons/')->willReturn([]);\n        $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons'));\n    }\n\n    public function testNonGreedyTrailingRequirement()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{a}', [], ['a' => '\\d+']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->with('/123')->willReturn([]);\n\n        $this->assertEquals(['_route' => 'a', 'a' => '123'], $matcher->match('/123/'));\n    }\n\n    public function testTrailingRequirementWithDefaultA()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/fr-fr/{a}', ['a' => 'aaa'], ['a' => '.+']));\n\n        $matcher = $this->getUrlMatcher($coll, null, true);\n        $matcher->expects($this->once())->method('redirect')->with('/fr-fr')->willReturn([]);\n\n        $this->assertEquals(['_route' => 'a', 'a' => 'aaa'], $matcher->match('/fr-fr/'));\n    }\n\n    protected function getUrlMatcher(RouteCollection $routes, ?RequestContext $context = null, bool $mock = false)\n    {\n        if (!$mock) {\n            return new class($routes, $context ?? new RequestContext()) extends RedirectableUrlMatcher {\n                public function redirect(string $path, string $route, ?string $scheme = null): array\n                {\n                    return [];\n                }\n            };\n        }\n\n        return $this->getMockBuilder(RedirectableUrlMatcher::class)\n            ->setConstructorArgs([$routes, $context ?? new RequestContext()])\n            ->onlyMethods(['redirect'])\n            ->getMock();\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/TraceableUrlMatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher;\n\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Matcher\\TraceableUrlMatcher;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass TraceableUrlMatcherTest extends UrlMatcherTest\n{\n    public function test()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', [], ['POST']));\n        $coll->add('bar', new Route('/bar/{id}', [], ['id' => '\\d+']));\n        $coll->add('bar1', new Route('/bar/{name}', [], ['id' => '\\w+'], [], '', [], ['POST']));\n        $coll->add('bar2', new Route('/foo', [], [], [], 'baz'));\n        $coll->add('bar3', new Route('/foo1', [], [], [], 'baz'));\n        $coll->add('bar4', new Route('/foo2', [], [], [], 'baz', [], [], 'context.getMethod() == \"GET\"'));\n\n        $context = new RequestContext();\n        $context->setHost('baz');\n\n        $matcher = new TraceableUrlMatcher($coll, $context);\n        $traces = $matcher->getTraces('/babar');\n        $this->assertSame([0, 0, 0, 0, 0, 0], $this->getLevels($traces));\n\n        $traces = $matcher->getTraces('/foo');\n        $this->assertSame([1, 0, 0, 2], $this->getLevels($traces));\n\n        $traces = $matcher->getTraces('/bar/12');\n        $this->assertSame([0, 2], $this->getLevels($traces));\n\n        $traces = $matcher->getTraces('/bar/dd');\n        $this->assertSame([0, 1, 1, 0, 0, 0], $this->getLevels($traces));\n\n        $traces = $matcher->getTraces('/foo1');\n        $this->assertSame([0, 0, 0, 0, 2], $this->getLevels($traces));\n\n        $context->setMethod('POST');\n        $traces = $matcher->getTraces('/foo');\n        $this->assertSame([2], $this->getLevels($traces));\n\n        $traces = $matcher->getTraces('/bar/dd');\n        $this->assertSame([0, 1, 2], $this->getLevels($traces));\n\n        $traces = $matcher->getTraces('/foo2');\n        $this->assertSame([0, 0, 0, 0, 0, 1], $this->getLevels($traces));\n    }\n\n    public function testMatchRouteOnMultipleHosts()\n    {\n        $routes = new RouteCollection();\n        $routes->add('first', new Route(\n            '/mypath/',\n            ['_controller' => 'MainBundle:Info:first'],\n            [],\n            [],\n            'some.example.com'\n        ));\n\n        $routes->add('second', new Route(\n            '/mypath/',\n            ['_controller' => 'MainBundle:Info:second'],\n            [],\n            [],\n            'another.example.com'\n        ));\n\n        $context = new RequestContext();\n        $context->setHost('baz');\n\n        $matcher = new TraceableUrlMatcher($routes, $context);\n\n        $traces = $matcher->getTraces('/mypath/');\n        $this->assertSame(\n            [TraceableUrlMatcher::ROUTE_ALMOST_MATCHES, TraceableUrlMatcher::ROUTE_ALMOST_MATCHES],\n            $this->getLevels($traces)\n        );\n    }\n\n    public function getLevels($traces)\n    {\n        $levels = [];\n        foreach ($traces as $trace) {\n            $levels[] = $trace['level'];\n        }\n\n        return $levels;\n    }\n\n    public function testRoutesWithConditions()\n    {\n        $routes = new RouteCollection();\n        $routes->add('foo', new Route('/foo', [], [], [], 'baz', [], [], \"request.headers.get('User-Agent') matches '/firefox/i'\"));\n        $routes->add('bar', new Route('/bar/{id}', [], [], [], 'baz', [], [], \"params['id'] < 100\"));\n\n        $context = new RequestContext();\n        $context->setHost('baz');\n\n        $matcher = new TraceableUrlMatcher($routes, $context);\n\n        $notMatchingRequest = Request::create('/foo', 'GET');\n        $traces = $matcher->getTracesForRequest($notMatchingRequest);\n        $this->assertEquals(\"Condition \\\"request.headers.get('User-Agent') matches '/firefox/i'\\\" does not evaluate to \\\"true\\\"\", $traces[0]['log']);\n\n        $matchingRequest = Request::create('/foo', 'GET', [], [], [], ['HTTP_USER_AGENT' => 'Firefox']);\n        $traces = $matcher->getTracesForRequest($matchingRequest);\n        $this->assertEquals('Route matches!', $traces[0]['log']);\n\n        $notMatchingRequest = Request::create('/bar/1000', 'GET');\n        $traces = $matcher->getTracesForRequest($notMatchingRequest);\n        $this->assertEquals(\"Condition \\\"params['id'] < 100\\\" does not evaluate to \\\"true\\\"\", $traces[1]['log']);\n\n        $matchingRequest = Request::create('/bar/10', 'GET');\n        $traces = $matcher->getTracesForRequest($matchingRequest);\n        $this->assertEquals('Route matches!', $traces[1]['log']);\n    }\n\n    protected function getUrlMatcher(RouteCollection $routes, ?RequestContext $context = null)\n    {\n        return new TraceableUrlMatcher($routes, $context ?? new RequestContext());\n    }\n}\n"
  },
  {
    "path": "Tests/Matcher/UrlMatcherTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Matcher;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Exception\\MethodNotAllowedException;\nuse Symfony\\Component\\Routing\\Exception\\NoConfigurationException;\nuse Symfony\\Component\\Routing\\Exception\\ResourceNotFoundException;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcher;\nuse Symfony\\Component\\Routing\\RequestContext;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass UrlMatcherTest extends TestCase\n{\n    public function testZero()\n    {\n        $coll = new RouteCollection();\n        $coll->add('index', new Route('/'));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n        $matcher->match('0');\n    }\n\n    public function testNoMethodSoAllowed()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo'));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertIsArray($matcher->match('/foo'));\n    }\n\n    public function testMethodNotAllowed()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', [], ['post']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        try {\n            $matcher->match('/foo');\n            $this->fail();\n        } catch (MethodNotAllowedException $e) {\n            $this->assertEquals(['POST'], $e->getAllowedMethods());\n        }\n    }\n\n    public function testMethodNotAllowedOnRoot()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/', [], [], [], '', [], ['GET']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n\n        try {\n            $matcher->match('/');\n            $this->fail();\n        } catch (MethodNotAllowedException $e) {\n            $this->assertEquals(['GET'], $e->getAllowedMethods());\n        }\n    }\n\n    public function testHeadAllowedWhenRequirementContainsGet()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', [], ['get']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'head'));\n        $this->assertIsArray($matcher->match('/foo'));\n    }\n\n    public function testMethodNotAllowedAggregatesAllowedMethods()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo1', new Route('/foo', [], [], [], '', [], ['post']));\n        $coll->add('foo2', new Route('/foo', [], [], [], '', [], ['put', 'delete']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        try {\n            $matcher->match('/foo');\n            $this->fail();\n        } catch (MethodNotAllowedException $e) {\n            $this->assertEquals(['POST', 'PUT', 'DELETE'], $e->getAllowedMethods());\n        }\n    }\n\n    public function testPatternMatchAndParameterReturn()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo/{bar}'));\n        $matcher = $this->getUrlMatcher($collection);\n        try {\n            $matcher->match('/no-match');\n            $this->fail();\n        } catch (ResourceNotFoundException $e) {\n        }\n\n        $this->assertEquals(['_route' => 'foo', 'bar' => 'baz'], $matcher->match('/foo/baz'));\n    }\n\n    public function testDefaultsAreMerged()\n    {\n        // test that defaults are merged\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo/{bar}', ['def' => 'test']));\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'foo', 'bar' => 'baz', 'def' => 'test'], $matcher->match('/foo/baz'));\n    }\n\n    public function testMethodIsIgnoredIfNoMethodGiven()\n    {\n        // test that route \"method\" is ignored if no method is given in the context\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo', [], [], [], '', [], ['get', 'head']));\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertIsArray($matcher->match('/foo'));\n\n        // route does not match with POST method context\n        $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'post'));\n        try {\n            $matcher->match('/foo');\n            $this->fail();\n        } catch (MethodNotAllowedException $e) {\n        }\n\n        // route does match with GET or HEAD method context\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertIsArray($matcher->match('/foo'));\n        $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'head'));\n        $this->assertIsArray($matcher->match('/foo'));\n    }\n\n    public function testRouteWithOptionalVariableAsFirstSegment()\n    {\n        $collection = new RouteCollection();\n        $collection->add('bar', new Route('/{bar}/foo', ['bar' => 'bar'], ['bar' => 'foo|bar']));\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'bar', 'bar' => 'bar'], $matcher->match('/bar/foo'));\n        $this->assertEquals(['_route' => 'bar', 'bar' => 'foo'], $matcher->match('/foo/foo'));\n\n        $collection = new RouteCollection();\n        $collection->add('bar', new Route('/{bar}', ['bar' => 'bar'], ['bar' => 'foo|bar']));\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'bar', 'bar' => 'foo'], $matcher->match('/foo'));\n        $this->assertEquals(['_route' => 'bar', 'bar' => 'bar'], $matcher->match('/'));\n    }\n\n    public function testRouteWithOnlyOptionalVariables()\n    {\n        $collection = new RouteCollection();\n        $collection->add('bar', new Route('/{foo}/{bar}', ['foo' => 'foo', 'bar' => 'bar'], []));\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'bar', 'foo' => 'foo', 'bar' => 'bar'], $matcher->match('/'));\n        $this->assertEquals(['_route' => 'bar', 'foo' => 'a', 'bar' => 'bar'], $matcher->match('/a'));\n        $this->assertEquals(['_route' => 'bar', 'foo' => 'a', 'bar' => 'b'], $matcher->match('/a/b'));\n    }\n\n    public function testMatchWithPrefixes()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/{foo}'));\n        $collection->addPrefix('/b');\n        $collection->addPrefix('/a');\n\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'foo', 'foo' => 'foo'], $matcher->match('/a/b/foo'));\n    }\n\n    public function testMatchWithDynamicPrefix()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/{foo}'));\n        $collection->addPrefix('/b');\n        $collection->addPrefix('/{_locale}');\n\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_locale' => 'fr', '_route' => 'foo', 'foo' => 'foo'], $matcher->match('/fr/b/foo'));\n    }\n\n    public function testMatchSpecialRouteName()\n    {\n        $collection = new RouteCollection();\n        $collection->add('$péß^a|', new Route('/bar'));\n\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => '$péß^a|'], $matcher->match('/bar'));\n    }\n\n    public function testMatchImportantVariable()\n    {\n        $collection = new RouteCollection();\n        $collection->add('index', new Route('/index.{!_format}', ['_format' => 'xml']));\n\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'index', '_format' => 'xml'], $matcher->match('/index.xml'));\n    }\n\n    public function testShortPathDoesNotMatchImportantVariable()\n    {\n        $collection = new RouteCollection();\n        $collection->add('index', new Route('/index.{!_format}', ['_format' => 'xml']));\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/index');\n    }\n\n    public function testTrailingEncodedNewlineIsNotOverlooked()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/foo%0a');\n    }\n\n    public function testMatchNonAlpha()\n    {\n        $collection = new RouteCollection();\n        $chars = '!\"$%éà &\\'()*+,./:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\\\[]^_`abcdefghijklmnopqrstuvwxyz{|}~-';\n        $collection->add('foo', new Route('/{foo}/bar', [], ['foo' => '['.preg_quote($chars).']+'], ['utf8' => true]));\n\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'foo', 'foo' => $chars], $matcher->match('/'.rawurlencode($chars).'/bar'));\n        $this->assertEquals(['_route' => 'foo', 'foo' => $chars], $matcher->match('/'.strtr($chars, ['%' => '%25']).'/bar'));\n    }\n\n    public function testMatchWithDotMetacharacterInRequirements()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/{foo}/bar', [], ['foo' => '.+']));\n\n        $matcher = $this->getUrlMatcher($collection);\n        $this->assertEquals(['_route' => 'foo', 'foo' => \"\\n\"], $matcher->match('/'.urlencode(\"\\n\").'/bar'), 'linefeed character is matched');\n    }\n\n    public function testMatchOverriddenRoute()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $collection1 = new RouteCollection();\n        $collection1->add('foo', new Route('/foo1'));\n\n        $collection->addCollection($collection1);\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo1'));\n        $this->expectException(ResourceNotFoundException::class);\n        $this->assertEquals([], $matcher->match('/foo'));\n    }\n\n    public function testMatchRegression()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{foo}'));\n        $coll->add('bar', new Route('/foo/bar/{foo}'));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/foo/bar/bar'));\n\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/{bar}'));\n        $matcher = $this->getUrlMatcher($collection);\n        try {\n            $matcher->match('/');\n            $this->fail();\n        } catch (ResourceNotFoundException $e) {\n        }\n    }\n\n    public function testMultipleParams()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo1', new Route('/foo/{a}/{b}'));\n        $coll->add('foo2', new Route('/foo/{a}/test/test/{b}'));\n        $coll->add('foo3', new Route('/foo/{a}/{b}/{c}/{d}'));\n\n        $route = $this->getUrlMatcher($coll)->match('/foo/test/test/test/bar')['_route'];\n\n        $this->assertEquals('foo2', $route);\n    }\n\n    public function testDefaultRequirementForOptionalVariables()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/{page}.{_format}', ['page' => 'index', '_format' => 'html']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['page' => 'my-page', '_format' => 'xml', '_route' => 'test'], $matcher->match('/my-page.xml'));\n    }\n\n    public function testMatchingIsEager()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/{foo}-{bar}-', [], ['foo' => '.+', 'bar' => '.+']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['foo' => 'text1-text2-text3', 'bar' => 'text4', '_route' => 'test'], $matcher->match('/text1-text2-text3-text4-'));\n    }\n\n    public function testAdjacentVariables()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/{w}{x}{y}{z}.{_format}', ['z' => 'default-z', '_format' => 'html'], ['y' => 'y|Y']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        // 'w' eagerly matches as much as possible and the other variables match the remaining chars.\n        // This also shows that the variables w-z must all exclude the separating char (the dot '.' in this case) by default requirement.\n        // Otherwise they would also consume '.xml' and _format would never match as it's an optional variable.\n        $this->assertEquals(['w' => 'wwwww', 'x' => 'x', 'y' => 'Y', 'z' => 'Z', '_format' => 'xml', '_route' => 'test'], $matcher->match('/wwwwwxYZ.xml'));\n        // As 'y' has custom requirement and can only be of value 'y|Y', it will leave  'ZZZ' to variable z.\n        // So with carefully chosen requirements adjacent variables, can be useful.\n        $this->assertEquals(['w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'ZZZ', '_format' => 'html', '_route' => 'test'], $matcher->match('/wwwwwxyZZZ'));\n        // z and _format are optional.\n        $this->assertEquals(['w' => 'wwwww', 'x' => 'x', 'y' => 'y', 'z' => 'default-z', '_format' => 'html', '_route' => 'test'], $matcher->match('/wwwwwxy'));\n\n        $this->expectException(ResourceNotFoundException::class);\n        $matcher->match('/wxy.html');\n    }\n\n    public function testOptionalVariableWithNoRealSeparator()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/get{what}', ['what' => 'All']));\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['what' => 'All', '_route' => 'test'], $matcher->match('/get'));\n        $this->assertEquals(['what' => 'Sites', '_route' => 'test'], $matcher->match('/getSites'));\n\n        // Usually the character in front of an optional parameter can be left out, e.g. with pattern '/get/{what}' just '/get' would match.\n        // But here the 't' in 'get' is not a separating character, so it makes no sense to match without it.\n        $this->expectException(ResourceNotFoundException::class);\n        $matcher->match('/ge');\n    }\n\n    public function testRequiredVariableWithNoRealSeparator()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/get{what}Suffix'));\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['what' => 'Sites', '_route' => 'test'], $matcher->match('/getSitesSuffix'));\n    }\n\n    public function testDefaultRequirementOfVariable()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/{page}.{_format}'));\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['page' => 'index', '_format' => 'mobile.html', '_route' => 'test'], $matcher->match('/index.mobile.html'));\n    }\n\n    public function testDefaultRequirementOfVariableDisallowsSlash()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/{page}.{_format}'));\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/index.sl/ash');\n    }\n\n    public function testDefaultRequirementOfVariableDisallowsNextSeparator()\n    {\n        $coll = new RouteCollection();\n        $coll->add('test', new Route('/{page}.{_format}', [], ['_format' => 'html|xml']));\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/do.t.html');\n    }\n\n    public function testMissingTrailingSlash()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/foo');\n    }\n\n    public function testExtraTrailingSlash()\n    {\n        $this->expectException(ResourceNotFoundException::class);\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo'));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $matcher->match('/foo/');\n    }\n\n    public function testMissingTrailingSlashForNonSafeMethod()\n    {\n        $this->expectException(ResourceNotFoundException::class);\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/'));\n\n        $context = new RequestContext();\n        $context->setMethod('POST');\n        $matcher = $this->getUrlMatcher($coll, $context);\n        $matcher->match('/foo');\n    }\n\n    public function testExtraTrailingSlashForNonSafeMethod()\n    {\n        $this->expectException(ResourceNotFoundException::class);\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo'));\n\n        $context = new RequestContext();\n        $context->setMethod('POST');\n        $matcher = $this->getUrlMatcher($coll, $context);\n        $matcher->match('/foo/');\n    }\n\n    public function testSchemeRequirement()\n    {\n        $this->expectException(ResourceNotFoundException::class);\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', ['https']));\n        $matcher = $this->getUrlMatcher($coll);\n        $matcher->match('/foo');\n    }\n\n    public function testSchemeRequirementForNonSafeMethod()\n    {\n        $this->expectException(ResourceNotFoundException::class);\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo', [], [], [], '', ['https']));\n\n        $context = new RequestContext();\n        $context->setMethod('POST');\n        $matcher = $this->getUrlMatcher($coll, $context);\n        $matcher->match('/foo');\n    }\n\n    public function testSamePathWithDifferentScheme()\n    {\n        $coll = new RouteCollection();\n        $coll->add('https_route', new Route('/', [], [], [], '', ['https']));\n        $coll->add('http_route', new Route('/', [], [], [], '', ['http']));\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'http_route'], $matcher->match('/'));\n    }\n\n    public function testCondition()\n    {\n        $coll = new RouteCollection();\n        $route = new Route('/foo');\n        $route->setCondition('context.getMethod() == \"POST\"');\n        $coll->add('foo', $route);\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/foo');\n    }\n\n    public function testRequestCondition()\n    {\n        $coll = new RouteCollection();\n        $route = new Route('/foo/{bar}');\n        $route->setCondition('request.getBaseUrl() == \"/bar\"');\n        $coll->add('bar', $route);\n        $route = new Route('/foo/{bar}');\n        $route->setCondition('request.getBaseUrl() == \"/sub/front.php\" and request.getPathInfo() == \"/foo/bar\"');\n        $coll->add('foo', $route);\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('/sub/front.php'));\n        $this->assertEquals(['bar' => 'bar', '_route' => 'foo'], $matcher->match('/foo/bar'));\n    }\n\n    public function testRouteParametersCondition()\n    {\n        $coll = new RouteCollection();\n        $route = new Route('/foo');\n        $route->setCondition(\"params['_route'] matches '/^s[a-z]+$/'\");\n        $coll->add('static', $route);\n        $route = new Route('/bar');\n        $route->setHost('en.example.com');\n        $route->setCondition(\"params['_route'] matches '/^s[a-z\\-]+$/'\");\n        $coll->add('static-with-host', $route);\n        $route = new Route('/foo/{id}');\n        $route->setCondition(\"params['id'] < 100\");\n        $coll->add('dynamic1', $route);\n        $route = new Route('/foo/{id}');\n        $route->setCondition(\"params['id'] > 100 and params['id'] < 1000\");\n        $coll->add('dynamic2', $route);\n        $route = new Route('/bar/{id}/');\n        $route->setCondition(\"params['id'] < 100\");\n        $coll->add('dynamic-with-slash', $route);\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('/sub/front.php', 'GET', 'en.example.com'));\n\n        $this->assertEquals(['_route' => 'static'], $matcher->match('/foo'));\n        $this->assertEquals(['_route' => 'static-with-host'], $matcher->match('/bar'));\n        $this->assertEquals(['_route' => 'dynamic1', 'id' => '10'], $matcher->match('/foo/10'));\n        $this->assertEquals(['_route' => 'dynamic2', 'id' => '200'], $matcher->match('/foo/200'));\n        $this->assertEquals(['_route' => 'dynamic-with-slash', 'id' => '10'], $matcher->match('/bar/10/'));\n\n        $this->expectException(ResourceNotFoundException::class);\n        $matcher->match('/foo/3000');\n    }\n\n    public function testDecodeOnce()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{foo}'));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['foo' => 'bar%23', '_route' => 'foo'], $matcher->match('/foo/bar%2523'));\n    }\n\n    public function testCannotRelyOnPrefix()\n    {\n        $coll = new RouteCollection();\n\n        $subColl = new RouteCollection();\n        $subColl->add('bar', new Route('/bar'));\n        $subColl->addPrefix('/prefix');\n        // overwrite the pattern, so the prefix is not valid anymore for this route in the collection\n        $subColl->get('bar')->setPath('/new');\n\n        $coll->addCollection($subColl);\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'bar'], $matcher->match('/new'));\n    }\n\n    public function testWithHost()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{foo}', [], [], [], '{locale}.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'foo', 'locale' => 'en'], $matcher->match('/foo/bar'));\n    }\n\n    public function testWithHostOnRouteCollection()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{foo}'));\n        $coll->add('bar', new Route('/bar/{foo}', [], [], [], '{locale}.example.net'));\n        $coll->setHost('{locale}.example.com');\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'foo', 'locale' => 'en'], $matcher->match('/foo/bar'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar', 'locale' => 'en'], $matcher->match('/bar/bar'));\n    }\n\n    public function testVariationInTrailingSlashWithHosts()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/', [], [], [], 'foo.example.com'));\n        $coll->add('bar', new Route('/foo', [], [], [], 'bar.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'foo.example.com'));\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'bar.example.com'));\n        $this->assertEquals(['_route' => 'bar'], $matcher->match('/foo'));\n    }\n\n    public function testVariationInTrailingSlashWithHostsInReverse()\n    {\n        // The order should not matter\n        $coll = new RouteCollection();\n        $coll->add('bar', new Route('/foo', [], [], [], 'bar.example.com'));\n        $coll->add('foo', new Route('/foo/', [], [], [], 'foo.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'foo.example.com'));\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'bar.example.com'));\n        $this->assertEquals(['_route' => 'bar'], $matcher->match('/foo'));\n    }\n\n    public function testVariationInTrailingSlashWithHostsAndVariable()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/{foo}/', [], [], [], 'foo.example.com'));\n        $coll->add('bar', new Route('/{foo}', [], [], [], 'bar.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'foo.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'foo'], $matcher->match('/bar/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'bar.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/bar'));\n    }\n\n    public function testVariationInTrailingSlashWithHostsAndVariableInReverse()\n    {\n        // The order should not matter\n        $coll = new RouteCollection();\n        $coll->add('bar', new Route('/{foo}', [], [], [], 'bar.example.com'));\n        $coll->add('foo', new Route('/{foo}/', [], [], [], 'foo.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'foo.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'foo'], $matcher->match('/bar/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'bar.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/bar'));\n    }\n\n    public function testVariationInTrailingSlashWithMethods()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/', [], [], [], '', [], ['POST']));\n        $coll->add('bar', new Route('/foo', [], [], [], '', [], ['GET']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET'));\n        $this->assertEquals(['_route' => 'bar'], $matcher->match('/foo'));\n    }\n\n    public function testVariationInTrailingSlashWithMethodsInReverse()\n    {\n        // The order should not matter\n        $coll = new RouteCollection();\n        $coll->add('bar', new Route('/foo', [], [], [], '', [], ['GET']));\n        $coll->add('foo', new Route('/foo/', [], [], [], '', [], ['POST']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET'));\n        $this->assertEquals(['_route' => 'bar'], $matcher->match('/foo'));\n    }\n\n    public function testVariableVariationInTrailingSlashWithMethods()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/{foo}/', [], [], [], '', [], ['POST']));\n        $coll->add('bar', new Route('/{foo}', [], [], [], '', [], ['GET']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'foo'], $matcher->match('/bar/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/bar'));\n    }\n\n    public function testVariableVariationInTrailingSlashWithMethodsInReverse()\n    {\n        // The order should not matter\n        $coll = new RouteCollection();\n        $coll->add('bar', new Route('/{foo}', [], [], [], '', [], ['GET']));\n        $coll->add('foo', new Route('/{foo}/', [], [], [], '', [], ['POST']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'foo'], $matcher->match('/bar/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/bar'));\n    }\n\n    public function testMixOfStaticAndVariableVariationInTrailingSlashWithHosts()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/', [], [], [], 'foo.example.com'));\n        $coll->add('bar', new Route('/{foo}', [], [], [], 'bar.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'foo.example.com'));\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'bar.example.com'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/bar'));\n    }\n\n    public function testMixOfStaticAndVariableVariationInTrailingSlashWithMethods()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/', [], [], [], '', [], ['POST']));\n        $coll->add('bar', new Route('/{foo}', [], [], [], '', [], ['GET']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n        $this->assertEquals(['_route' => 'foo'], $matcher->match('/foo/'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET'));\n        $this->assertEquals(['foo' => 'bar', '_route' => 'bar'], $matcher->match('/bar'));\n        $this->assertEquals(['foo' => 'foo', '_route' => 'bar'], $matcher->match('/foo'));\n    }\n\n    public function testWithOutHostHostDoesNotMatch()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/foo/{foo}', [], [], [], '{locale}.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'example.com'));\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/foo/bar');\n    }\n\n    public function testPathIsCaseSensitive()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/locale', [], ['locale' => 'EN|FR|DE']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n\n        $matcher->match('/en');\n    }\n\n    public function testHostIsCaseInsensitive()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/', [], ['locale' => 'EN|FR|DE'], [], '{locale}.example.com'));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com'));\n        $this->assertEquals(['_route' => 'foo', 'locale' => 'en'], $matcher->match('/'));\n    }\n\n    public function testNoConfiguration()\n    {\n        $coll = new RouteCollection();\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(NoConfigurationException::class);\n\n        $matcher->match('/');\n    }\n\n    public function testNestedCollections()\n    {\n        $coll = new RouteCollection();\n\n        $subColl = new RouteCollection();\n        $subColl->add('a', new Route('/a'));\n        $subColl->add('b', new Route('/b'));\n        $subColl->add('c', new Route('/c'));\n        $subColl->addPrefix('/p');\n        $coll->addCollection($subColl);\n\n        $coll->add('baz', new Route('/{baz}'));\n\n        $subColl = new RouteCollection();\n        $subColl->add('buz', new Route('/buz'));\n        $subColl->addPrefix('/prefix');\n        $coll->addCollection($subColl);\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'a'], $matcher->match('/p/a'));\n        $this->assertEquals(['_route' => 'baz', 'baz' => 'p'], $matcher->match('/p'));\n        $this->assertEquals(['_route' => 'buz'], $matcher->match('/prefix/buz'));\n    }\n\n    public function testSchemeAndMethodMismatch()\n    {\n        $coll = new RouteCollection();\n        $coll->add('foo', new Route('/', [], [], [], null, ['https'], ['POST']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n        $this->expectExceptionMessage('No routes found for \"/\".');\n\n        $matcher->match('/');\n    }\n\n    public function testSiblingRoutes()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', (new Route('/a{a}'))->setMethods('POST'));\n        $coll->add('b', (new Route('/a{a}'))->setMethods('PUT'));\n        $coll->add('c', new Route('/a{a}'));\n        $coll->add('d', (new Route('/b{a}'))->setCondition('false'));\n        $coll->add('e', (new Route('/{b}{a}'))->setCondition('false'));\n        $coll->add('f', (new Route('/{b}{a}'))->setRequirements(['b' => 'b']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'c', 'a' => 'a'], $matcher->match('/aa'));\n        $this->assertEquals(['_route' => 'f', 'b' => 'b', 'a' => 'a'], $matcher->match('/ba'));\n    }\n\n    public function testUnicodeRoute()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{a}', [], ['a' => '.'], ['utf8' => false]));\n        $coll->add('b', new Route('/{a}', [], ['a' => '.'], ['utf8' => true]));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'b', 'a' => 'é'], $matcher->match('/é'));\n    }\n\n    public function testRequirementWithCapturingGroup()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{a}/{b}', [], ['a' => '(a|b)']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'a', 'a' => 'a', 'b' => 'b'], $matcher->match('/a/b'));\n    }\n\n    public function testDotAllWithCatchAll()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{id}.html', [], ['id' => '.+']));\n        $coll->add('b', new Route('/{all}', [], ['all' => '.+']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'a', 'id' => 'foo/bar'], $matcher->match('/foo/bar.html'));\n    }\n\n    public function testHostPattern()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{app}/{action}/{unused}', [], [], [], '{host}'));\n\n        $expected = [\n            '_route' => 'a',\n            'app' => 'an_app',\n            'action' => 'an_action',\n            'unused' => 'unused',\n            'host' => 'foo',\n        ];\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'foo'));\n        $this->assertEquals($expected, $matcher->match('/an_app/an_action/unused'));\n    }\n\n    public function testUtf8Prefix()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/é{foo}', [], [], ['utf8' => true]));\n        $coll->add('b', new Route('/è{bar}', [], [], ['utf8' => true]));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals('a', $matcher->match('/éo')['_route']);\n    }\n\n    public function testUtf8AndMethodMatching()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/admin/api/list/{shortClassName}/{id}.{_format}', [], [], ['utf8' => true], '', [], ['PUT']));\n        $coll->add('b', new Route('/admin/api/package.{_format}', [], [], [], '', [], ['POST']));\n        $coll->add('c', new Route('/admin/api/package.{_format}', ['_format' => 'json'], [], [], '', [], ['GET']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals('c', $matcher->match('/admin/api/package.json')['_route']);\n    }\n\n    public function testHostWithDot()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/foo', [], [], [], 'foo.example.com'));\n        $coll->add('b', new Route('/bar/{baz}'));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals('b', $matcher->match('/bar/abc.123')['_route']);\n    }\n\n    public function testSlashVariant()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/foo/{bar}', [], ['bar' => '.*']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals('a', $matcher->match('/foo/')['_route']);\n    }\n\n    public function testSlashVariant2()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/foo/{bär}/', [], ['bär' => '.*'], ['utf8' => true]));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertEquals(['_route' => 'a', 'bär' => 'bar'], $matcher->match('/foo/bar/'));\n    }\n\n    public function testSlashWithVerb()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{foo}', [], [], [], '', [], ['put', 'delete']));\n        $coll->add('b', new Route('/bar/'));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $this->assertSame(['_route' => 'b'], $matcher->match('/bar/'));\n\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/dav/{foo}', [], ['foo' => '.*'], [], '', [], ['GET', 'OPTIONS']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'OPTIONS'));\n        $expected = [\n            '_route' => 'a',\n            'foo' => 'files/bar/',\n        ];\n        $this->assertEquals($expected, $matcher->match('/dav/files/bar/'));\n    }\n\n    public function testSlashAndVerbPrecedence()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/api/customers/{customerId}/contactpersons/', [], [], [], '', [], ['post']));\n        $coll->add('b', new Route('/api/customers/{customerId}/contactpersons', [], [], [], '', [], ['get']));\n\n        $matcher = $this->getUrlMatcher($coll);\n        $expected = [\n            '_route' => 'b',\n            'customerId' => '123',\n        ];\n        $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons'));\n\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/api/customers/{customerId}/contactpersons/', [], [], [], '', [], ['get']));\n        $coll->add('b', new Route('/api/customers/{customerId}/contactpersons', [], [], [], '', [], ['post']));\n\n        $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'POST'));\n        $expected = [\n            '_route' => 'b',\n            'customerId' => '123',\n        ];\n        $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons'));\n    }\n\n    public function testGreedyTrailingRequirement()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/{a}', [], ['a' => '.+']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['_route' => 'a', 'a' => 'foo'], $matcher->match('/foo'));\n        $this->assertEquals(['_route' => 'a', 'a' => 'foo/'], $matcher->match('/foo/'));\n    }\n\n    public function testTrailingRequirementWithDefault()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/fr-fr/{a}', ['a' => 'aaa'], ['a' => '.+']));\n        $coll->add('b', new Route('/en-en/{b}', ['b' => 'bbb'], ['b' => '.*']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['_route' => 'a', 'a' => 'aaa'], $matcher->match('/fr-fr'));\n        $this->assertEquals(['_route' => 'a', 'a' => 'AAA'], $matcher->match('/fr-fr/AAA'));\n        $this->assertEquals(['_route' => 'b', 'b' => 'bbb'], $matcher->match('/en-en'));\n        $this->assertEquals(['_route' => 'b', 'b' => 'BBB'], $matcher->match('/en-en/BBB'));\n    }\n\n    public function testTrailingRequirementWithDefaultA()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/fr-fr/{a}', ['a' => 'aaa'], ['a' => '.+']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->expectException(ResourceNotFoundException::class);\n        $matcher->match('/fr-fr/');\n    }\n\n    public function testTrailingRequirementWithDefaultB()\n    {\n        $coll = new RouteCollection();\n        $coll->add('b', new Route('/en-en/{b}', ['b' => 'bbb'], ['b' => '.*']));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['_route' => 'b', 'b' => ''], $matcher->match('/en-en/'));\n    }\n\n    public function testRestrictiveTrailingRequirementWithStaticRouteAfter()\n    {\n        $coll = new RouteCollection();\n        $coll->add('a', new Route('/hello{_}', [], ['_' => '/(?!/)']));\n        $coll->add('b', new Route('/hello'));\n\n        $matcher = $this->getUrlMatcher($coll);\n\n        $this->assertEquals(['_route' => 'a', '_' => '/'], $matcher->match('/hello/'));\n    }\n\n    public function testUtf8VarName()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo/{bär}/{bäz?foo}', [], [], ['utf8' => true]));\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $this->assertEquals(['_route' => 'foo', 'bär' => 'baz', 'bäz' => 'foo'], $matcher->match('/foo/baz'));\n    }\n\n    public function testParameterWithRequirementWithDefault()\n    {\n        $collection = new RouteCollection();\n\n        $route = new Route('/test/{foo}', ['foo' => 'foo-'], ['foo' => '\\w+']);\n        $collection->add('test', $route);\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $result = $matcher->match('/test/foo');\n        $this->assertSame('test', $result['_route']);\n        $this->assertSame('foo', $result['foo']);\n\n        try {\n            $matcher->match('/test/foo-');\n        } catch (ResourceNotFoundException $e) {\n            $this->assertStringContainsString('No routes found', $e->getMessage());\n        }\n\n        $result = $matcher->match('/test');\n        $this->assertSame('test', $result['_route']);\n        $this->assertSame('foo-', $result['foo']);\n    }\n\n    public function testMapping()\n    {\n        $collection = new RouteCollection();\n        $collection->add('a', new Route('/conference/{slug:conference}'));\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $expected = [\n            '_route' => 'a',\n            'slug' => 'vienna-2024',\n            '_route_mapping' => [\n                'slug' => 'conference',\n            ],\n        ];\n        $this->assertEquals($expected, $matcher->match('/conference/vienna-2024'));\n    }\n\n    public function testMappingwithAlias()\n    {\n        $collection = new RouteCollection();\n        $collection->add('a', new Route('/conference/{conferenceSlug:conference.slug}'));\n\n        $matcher = $this->getUrlMatcher($collection);\n\n        $expected = [\n            '_route' => 'a',\n            'conferenceSlug' => 'vienna-2024',\n            '_route_mapping' => [\n                'conferenceSlug' => [\n                    'conference',\n                    'slug',\n                ],\n            ],\n        ];\n        $this->assertEquals($expected, $matcher->match('/conference/vienna-2024'));\n    }\n\n    protected function getUrlMatcher(RouteCollection $routes, ?RequestContext $context = null)\n    {\n        return new UrlMatcher($routes, $context ?? new RequestContext());\n    }\n}\n"
  },
  {
    "path": "Tests/RequestContextTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests;\n\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\RequestContext;\n\nclass RequestContextTest extends TestCase\n{\n    public function testConstruct()\n    {\n        $requestContext = new RequestContext(\n            'foo',\n            'post',\n            'foo.bar',\n            'HTTPS',\n            8080,\n            444,\n            '/baz',\n            'bar=foobar',\n            [\n                'foo' => 'bar',\n            ]\n        );\n\n        $this->assertEquals('foo', $requestContext->getBaseUrl());\n        $this->assertEquals('POST', $requestContext->getMethod());\n        $this->assertEquals('foo.bar', $requestContext->getHost());\n        $this->assertEquals('https', $requestContext->getScheme());\n        $this->assertSame(8080, $requestContext->getHttpPort());\n        $this->assertSame(444, $requestContext->getHttpsPort());\n        $this->assertEquals('/baz', $requestContext->getPathInfo());\n        $this->assertEquals('bar=foobar', $requestContext->getQueryString());\n        $this->assertSame(['foo' => 'bar'], $requestContext->getParameters());\n    }\n\n    public function testConstructParametersBcLayer()\n    {\n        $requestContext = new class extends RequestContext {\n            public function __construct()\n            {\n                $this->setParameters(['foo' => 'bar']);\n                parent::__construct();\n            }\n        };\n\n        $this->assertSame(['foo' => 'bar'], $requestContext->getParameters());\n    }\n\n    public function testFromUriWithBaseUrl()\n    {\n        $requestContext = RequestContext::fromUri('https://test.com:444/index.php');\n\n        $this->assertSame('GET', $requestContext->getMethod());\n        $this->assertSame('https', $requestContext->getScheme());\n        $this->assertSame('test.com', $requestContext->getHost());\n        $this->assertSame('/index.php', $requestContext->getBaseUrl());\n        $this->assertSame('/', $requestContext->getPathInfo());\n        $this->assertSame(80, $requestContext->getHttpPort());\n        $this->assertSame(444, $requestContext->getHttpsPort());\n    }\n\n    public function testFromUriWithTrailingSlash()\n    {\n        $requestContext = RequestContext::fromUri('http://test.com:8080/');\n\n        $this->assertSame('http', $requestContext->getScheme());\n        $this->assertSame('test.com', $requestContext->getHost());\n        $this->assertSame(8080, $requestContext->getHttpPort());\n        $this->assertSame(443, $requestContext->getHttpsPort());\n        $this->assertSame('', $requestContext->getBaseUrl());\n        $this->assertSame('/', $requestContext->getPathInfo());\n    }\n\n    public function testFromUriWithoutTrailingSlash()\n    {\n        $requestContext = RequestContext::fromUri('https://test.com');\n\n        $this->assertSame('https', $requestContext->getScheme());\n        $this->assertSame('test.com', $requestContext->getHost());\n        $this->assertSame('', $requestContext->getBaseUrl());\n        $this->assertSame('/', $requestContext->getPathInfo());\n    }\n\n    public function testFromUriBeingEmpty()\n    {\n        $requestContext = RequestContext::fromUri('');\n\n        $this->assertSame('http', $requestContext->getScheme());\n        $this->assertSame('localhost', $requestContext->getHost());\n        $this->assertSame('', $requestContext->getBaseUrl());\n        $this->assertSame('/', $requestContext->getPathInfo());\n    }\n\n    #[TestWith(['http://foo.com\\\\bar'])]\n    #[TestWith(['\\\\\\\\foo.com/bar'])]\n    #[TestWith([\"a\\rb\"])]\n    #[TestWith([\"a\\nb\"])]\n    #[TestWith([\"a\\tb\"])]\n    #[TestWith([\"\\u0000foo\"])]\n    #[TestWith([\"foo\\u0000\"])]\n    #[TestWith([' foo'])]\n    #[TestWith(['foo '])]\n    #[TestWith([':'])]\n    public function testFromBadUri(string $uri)\n    {\n        $context = RequestContext::fromUri($uri);\n\n        $this->assertSame('http', $context->getScheme());\n        $this->assertSame('localhost', $context->getHost());\n        $this->assertSame('', $context->getBaseUrl());\n        $this->assertSame('/', $context->getPathInfo());\n    }\n\n    public function testFromRequest()\n    {\n        $request = Request::create('https://test.com:444/foo?bar=baz');\n        $requestContext = new RequestContext();\n        $requestContext->setHttpPort(123);\n        $requestContext->fromRequest($request);\n\n        $this->assertEquals('', $requestContext->getBaseUrl());\n        $this->assertEquals('GET', $requestContext->getMethod());\n        $this->assertEquals('test.com', $requestContext->getHost());\n        $this->assertEquals('https', $requestContext->getScheme());\n        $this->assertEquals('/foo', $requestContext->getPathInfo());\n        $this->assertEquals('bar=baz', $requestContext->getQueryString());\n        $this->assertSame(123, $requestContext->getHttpPort());\n        $this->assertSame(444, $requestContext->getHttpsPort());\n\n        $request = Request::create('http://test.com:8080/foo?bar=baz');\n        $requestContext = new RequestContext();\n        $requestContext->setHttpsPort(567);\n        $requestContext->fromRequest($request);\n\n        $this->assertSame(8080, $requestContext->getHttpPort());\n        $this->assertSame(567, $requestContext->getHttpsPort());\n    }\n\n    public function testGetParameters()\n    {\n        $requestContext = new RequestContext();\n        $this->assertEquals([], $requestContext->getParameters());\n\n        $requestContext->setParameters(['foo' => 'bar']);\n        $this->assertEquals(['foo' => 'bar'], $requestContext->getParameters());\n    }\n\n    public function testHasParameter()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setParameters(['foo' => 'bar']);\n\n        $this->assertTrue($requestContext->hasParameter('foo'));\n        $this->assertFalse($requestContext->hasParameter('baz'));\n    }\n\n    public function testGetParameter()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setParameters(['foo' => 'bar']);\n\n        $this->assertEquals('bar', $requestContext->getParameter('foo'));\n        $this->assertNull($requestContext->getParameter('baz'));\n    }\n\n    public function testSetParameter()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setParameter('foo', 'bar');\n\n        $this->assertEquals('bar', $requestContext->getParameter('foo'));\n    }\n\n    public function testMethod()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setMethod('post');\n\n        $this->assertSame('POST', $requestContext->getMethod());\n    }\n\n    public function testScheme()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setScheme('HTTPS');\n\n        $this->assertSame('https', $requestContext->getScheme());\n    }\n\n    public function testHost()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setHost('eXampLe.com');\n\n        $this->assertSame('example.com', $requestContext->getHost());\n    }\n\n    public function testQueryString()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setQueryString(null);\n\n        $this->assertSame('', $requestContext->getQueryString());\n    }\n\n    public function testPort()\n    {\n        $requestContext = new RequestContext();\n        $requestContext->setHttpPort('123');\n        $requestContext->setHttpsPort('456');\n\n        $this->assertSame(123, $requestContext->getHttpPort());\n        $this->assertSame(456, $requestContext->getHttpsPort());\n    }\n\n    public function testFluentInterface()\n    {\n        $requestContext = new RequestContext();\n\n        $this->assertSame($requestContext, $requestContext->setBaseUrl('/app.php'));\n        $this->assertSame($requestContext, $requestContext->setPathInfo('/index'));\n        $this->assertSame($requestContext, $requestContext->setMethod('POST'));\n        $this->assertSame($requestContext, $requestContext->setScheme('https'));\n        $this->assertSame($requestContext, $requestContext->setHost('example.com'));\n        $this->assertSame($requestContext, $requestContext->setQueryString('foo=bar'));\n        $this->assertSame($requestContext, $requestContext->setHttpPort(80));\n        $this->assertSame($requestContext, $requestContext->setHttpsPort(443));\n        $this->assertSame($requestContext, $requestContext->setParameters([]));\n        $this->assertSame($requestContext, $requestContext->setParameter('foo', 'bar'));\n    }\n}\n"
  },
  {
    "path": "Tests/Requirement/EnumRequirementTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Requirement;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Exception\\InvalidArgumentException;\nuse Symfony\\Component\\Routing\\Requirement\\EnumRequirement;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestIntBackedEnum;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestStringBackedEnum;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestStringBackedEnum2;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestUnitEnum;\n\nclass EnumRequirementTest extends TestCase\n{\n    public function testNotABackedEnum()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('\"Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestUnitEnum\" is not a \"BackedEnum\" class.');\n\n        new EnumRequirement(TestUnitEnum::class);\n    }\n\n    public function testCaseNotABackedEnum()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('Case must be a \"BackedEnum\" instance, \"string\" given.');\n\n        new EnumRequirement(['wrong']);\n    }\n\n    public function testCaseFromAnotherEnum()\n    {\n        $this->expectException(InvalidArgumentException::class);\n        $this->expectExceptionMessage('\"Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestStringBackedEnum2::Spades\" is not a case of \"Symfony\\Component\\Routing\\Tests\\Fixtures\\Enum\\TestStringBackedEnum\".');\n\n        new EnumRequirement([TestStringBackedEnum::Diamonds, TestStringBackedEnum2::Spades]);\n    }\n\n    #[DataProvider('provideToString')]\n    public function testToString(string $expected, string|array $cases = [])\n    {\n        $this->assertSame($expected, (string) new EnumRequirement($cases));\n    }\n\n    public static function provideToString()\n    {\n        return [\n            ['hearts|diamonds|clubs|spades', TestStringBackedEnum::class],\n            ['10|20|30|40', TestIntBackedEnum::class],\n            ['diamonds|spades', [TestStringBackedEnum::Diamonds, TestStringBackedEnum::Spades]],\n            ['diamonds', [TestStringBackedEnum::Diamonds]],\n            ['hearts|diamonds|clubs|spa\\|des', TestStringBackedEnum2::class],\n        ];\n    }\n\n    public function testInRoute()\n    {\n        $this->assertSame([\n            'bar' => 'hearts|diamonds|clubs|spades',\n        ], (new Route(\n            path: '/foo/{bar}',\n            requirements: [\n                'bar' => new EnumRequirement(TestStringBackedEnum::class),\n            ],\n        ))->getRequirements());\n    }\n}\n"
  },
  {
    "path": "Tests/Requirement/RequirementTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests\\Requirement;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\Attributes\\TestWith;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Requirement\\Requirement;\nuse Symfony\\Component\\Routing\\Route;\n\nclass RequirementTest extends TestCase\n{\n    #[TestWith(['FOO'])]\n    #[TestWith(['foo'])]\n    #[TestWith(['1987'])]\n    #[TestWith(['42-42'])]\n    #[TestWith(['fo2o-bar'])]\n    #[TestWith(['foo-bA198r-Ccc'])]\n    #[TestWith(['fo10O-bar-CCc-fooba187rccc'])]\n    public function testAsciiSlugOK(string $slug)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{slug}', [], ['slug' => Requirement::ASCII_SLUG]))->compile()->getRegex(),\n            '/'.$slug,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['-'])]\n    #[TestWith(['fôo'])]\n    #[TestWith(['-FOO'])]\n    #[TestWith(['foo-'])]\n    #[TestWith(['-foo-'])]\n    #[TestWith(['-foo-bar-'])]\n    #[TestWith(['foo--bar'])]\n    public function testAsciiSlugKO(string $slug)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{slug}', [], ['slug' => Requirement::ASCII_SLUG]))->compile()->getRegex(),\n            '/'.$slug,\n        );\n    }\n\n    #[TestWith(['foo'])]\n    #[TestWith(['foo/bar/ccc'])]\n    #[TestWith(['///'])]\n    public function testCatchAllOK(string $path)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{path}', [], ['path' => Requirement::CATCH_ALL]))->compile()->getRegex(),\n            '/'.$path,\n        );\n    }\n\n    #[TestWith([''])]\n    public function testCatchAllKO(string $path)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{path}', [], ['path' => Requirement::CATCH_ALL]))->compile()->getRegex(),\n            '/'.$path,\n        );\n    }\n\n    #[TestWith(['0000-01-01'])]\n    #[TestWith(['9999-12-31'])]\n    #[TestWith(['2022-04-15'])]\n    #[TestWith(['2024-02-29'])]\n    #[TestWith(['1243-04-31'])]\n    public function testDateYmdOK(string $date)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{date}', [], ['date' => Requirement::DATE_YMD]))->compile()->getRegex(),\n            '/'.$date,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['0000-01-00'])]\n    #[TestWith(['9999-00-31'])]\n    #[TestWith(['2022-02-30'])]\n    #[TestWith(['2022-02-31'])]\n    public function testDateYmdKO(string $date)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{date}', [], ['date' => Requirement::DATE_YMD]))->compile()->getRegex(),\n            '/'.$date,\n        );\n    }\n\n    #[TestWith(['0'])]\n    #[TestWith(['012'])]\n    #[TestWith(['1'])]\n    #[TestWith(['42'])]\n    #[TestWith(['42198'])]\n    #[TestWith(['999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'])]\n    public function testDigitsOK(string $digits)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{digits}', [], ['digits' => Requirement::DIGITS]))->compile()->getRegex(),\n            '/'.$digits,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['-1'])]\n    #[TestWith(['3.14'])]\n    public function testDigitsKO(string $digits)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{digits}', [], ['digits' => Requirement::DIGITS]))->compile()->getRegex(),\n            '/'.$digits,\n        );\n    }\n\n    #[TestWith(['67c8b7d295c70befc3070bf2'])]\n    #[TestWith(['000000000000000000000000'])]\n    public function testMongoDbIdOK(string $id)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{id}', [], ['id' => Requirement::MONGODB_ID]))->compile()->getRegex(),\n            '/'.$id,\n        );\n    }\n\n    #[TestWith(['67C8b7D295C70BEFC3070BF2'])]\n    #[TestWith(['67c8b7d295c70befc3070bg2'])]\n    #[TestWith(['67c8b7d295c70befc3070bf2a'])]\n    #[TestWith(['67c8b7d295c70befc3070bf'])]\n    public function testMongoDbIdKO(string $id)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{id}', [], ['id' => Requirement::MONGODB_ID]))->compile()->getRegex(),\n            '/'.$id,\n        );\n    }\n\n    #[TestWith(['1'])]\n    #[TestWith(['42'])]\n    #[TestWith(['42198'])]\n    #[TestWith(['999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'])]\n    public function testPositiveIntOK(string $digits)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{digits}', [], ['digits' => Requirement::POSITIVE_INT]))->compile()->getRegex(),\n            '/'.$digits,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['0'])]\n    #[TestWith(['045'])]\n    #[TestWith(['foo'])]\n    #[TestWith(['-1'])]\n    #[TestWith(['3.14'])]\n    public function testPositiveIntKO(string $digits)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{digits}', [], ['digits' => Requirement::POSITIVE_INT]))->compile()->getRegex(),\n            '/'.$digits,\n        );\n    }\n\n    #[TestWith(['00000000000000000000000000'])]\n    #[TestWith(['ZZZZZZZZZZZZZZZZZZZZZZZZZZ'])]\n    #[TestWith(['01G0P4XH09KW3RCF7G4Q57ESN0'])]\n    #[TestWith(['05CSACM1MS9RB9H5F61BYA146Q'])]\n    public function testUidBase32OK(string $uid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_BASE32]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['01G0P4XH09KW3RCF7G4Q57ESN'])]\n    #[TestWith(['01G0P4XH09KW3RCF7G4Q57ESNU'])]\n    public function testUidBase32KO(string $uid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_BASE32]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[TestWith(['1111111111111111111111'])]\n    #[TestWith(['zzzzzzzzzzzzzzzzzzzzzz'])]\n    #[TestWith(['1BkPBX6T19U8TUAjBTtgwH'])]\n    #[TestWith(['1fg491dt8eQpf2TU42o2bY'])]\n    public function testUidBase58OK(string $uid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_BASE58]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['1BkPBX6T19U8TUAjBTtgw'])]\n    #[TestWith(['1BkPBX6T19U8TUAjBTtgwI'])]\n    public function testUidBase58KO(string $uid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_BASE58]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[DataProvider('provideUidRfc4122')]\n    public function testUidRfc4122OK(string $uid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_RFC4122]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[DataProvider('provideUidRfc4122KO')]\n    public function testUidRfc4122KO(string $uid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_RFC4122]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[DataProvider('provideUidRfc4122')]\n    public function testUidRfc9562OK(string $uid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_RFC9562]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    #[DataProvider('provideUidRfc4122KO')]\n    public function testUidRfc9562KO(string $uid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uid}', [], ['uid' => Requirement::UID_RFC9562]))->compile()->getRegex(),\n            '/'.$uid,\n        );\n    }\n\n    public static function provideUidRfc4122(): iterable\n    {\n        yield ['00000000-0000-0000-0000-000000000000'];\n        yield ['ffffffff-ffff-ffff-ffff-ffffffffffff'];\n        yield ['01802c4e-c409-9f07-863c-f025ca7766a0'];\n        yield ['056654ca-0699-4e16-9895-e60afca090d7'];\n    }\n\n    public static function provideUidRfc4122KO(): iterable\n    {\n        yield [''];\n        yield ['foo'];\n        yield ['01802c4e-c409-9f07-863c-f025ca7766a'];\n        yield ['01802c4e-c409-9f07-863c-f025ca7766ag'];\n        yield ['01802c4ec4099f07863cf025ca7766a0'];\n    }\n\n    #[TestWith(['00000000000000000000000000'])]\n    #[TestWith(['7ZZZZZZZZZZZZZZZZZZZZZZZZZ'])]\n    #[TestWith(['01G0P4ZPM69QTD4MM4ENAEA4EW'])]\n    public function testUlidOK(string $ulid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{ulid}', [], ['ulid' => Requirement::ULID]))->compile()->getRegex(),\n            '/'.$ulid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['8ZZZZZZZZZZZZZZZZZZZZZZZZZ'])]\n    #[TestWith(['01G0P4ZPM69QTD4MM4ENAEA4E'])]\n    public function testUlidKO(string $ulid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{ulid}', [], ['ulid' => Requirement::ULID]))->compile()->getRegex(),\n            '/'.$ulid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-1000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-6fff-bfff-ffffffffffff'])]\n    #[TestWith(['8c670a1c-bc95-11ec-8422-0242ac120002'])]\n    #[TestWith(['61c86569-e477-3ed9-9e3b-1562edb03277'])]\n    #[TestWith(['e55a29be-ba25-46e0-a5e5-85b78a6f9a11'])]\n    #[TestWith(['bad98960-f1a1-530e-9a82-07d0b6c4e62f'])]\n    #[TestWith(['1ecbc9a8-432d-6b14-af93-715adc3b830c'])]\n    public function testUuidOK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['01802c74-d78c-b085-0cdf-7cbad87c70a3'])]\n    #[TestWith(['e55a29be-ba25-46e0-a5e5-85b78a6f9a1'])]\n    #[TestWith(['e55a29bh-ba25-46e0-a5e5-85b78a6f9a11'])]\n    #[TestWith(['e55a29beba2546e0a5e585b78a6f9a11'])]\n    #[TestWith(['21902510-bc96-21ec-8422-0242ac120002'])]\n    public function testUuidKO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-1000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-1fff-bfff-ffffffffffff'])]\n    #[TestWith(['21902510-bc96-11ec-8422-0242ac120002'])]\n    #[TestWith(['a8ff8f60-088e-1099-a09d-53afc49918d1'])]\n    #[TestWith(['b0ac612c-9117-17a1-901f-53afc49918d1'])]\n    public function testUuidV1OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V1]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['a3674b89-0170-3e30-8689-52939013e39c'])]\n    #[TestWith(['e0040090-3cb0-4bf9-a868-407770c964f9'])]\n    #[TestWith(['2e2b41d9-e08c-53d2-b435-818b9c323942'])]\n    #[TestWith(['2a37b67a-5eaa-6424-b5d6-ffc9ba0f2a13'])]\n    public function testUuidV1KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V1]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-3000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-3fff-bfff-ffffffffffff'])]\n    #[TestWith(['2b3f1427-33b2-30a9-8759-07355007c204'])]\n    #[TestWith(['c38e7b09-07f7-3901-843d-970b0186b873'])]\n    public function testUuidV3OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V3]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['e24d9c0e-bc98-11ec-9924-53afc49918d1'])]\n    #[TestWith(['1c240248-7d0b-41a4-9d20-61ad2915a58c'])]\n    #[TestWith(['4816b668-385b-5a65-808d-bca410f45090'])]\n    #[TestWith(['1d2f3104-dff6-64c6-92ff-0f74b1d0e2af'])]\n    public function testUuidV3KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V3]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-4000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-4fff-bfff-ffffffffffff'])]\n    #[TestWith(['b8f15bf4-46e2-4757-bbce-11ae83f7a6ea'])]\n    #[TestWith(['eaf51230-1ce2-40f1-ab18-649212b26198'])]\n    public function testUuidV4OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V4]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['15baaab2-f310-11d2-9ecf-53afc49918d1'])]\n    #[TestWith(['acd44dc8-d2cc-326c-9e3a-80a3305a25e8'])]\n    #[TestWith(['7fc2705f-a8a4-5b31-99a8-890686d64189'])]\n    #[TestWith(['1ecbc991-3552-6920-998e-efad54178a98'])]\n    public function testUuidV4KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V4]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-5000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-5fff-bfff-ffffffffffff'])]\n    #[TestWith(['49f4d32c-28b3-5802-8717-a2896180efbd'])]\n    #[TestWith(['58b3c62e-a7df-5a82-93a6-fbe5fda681c1'])]\n    public function testUuidV5OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V5]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['b99ad578-fdd3-1135-9d3b-53afc49918d1'])]\n    #[TestWith(['b3ee3071-7a2b-3e17-afdf-6b6aec3acf85'])]\n    #[TestWith(['2ab4f5a7-6412-46c1-b3ab-1fe1ed391e27'])]\n    #[TestWith(['135fdd3d-e193-653e-865d-67e88cf12e44'])]\n    public function testUuidV5KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V5]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-6000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-6fff-bfff-ffffffffffff'])]\n    #[TestWith(['2c51caad-c72f-66b2-b6d7-8766d36c73df'])]\n    #[TestWith(['17941ebb-48fa-6bfe-9bbd-43929f8784f5'])]\n    #[TestWith(['1ecbc993-f6c2-67f2-8fbe-295ed594b344'])]\n    public function testUuidV6OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V6]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['821040f4-7b67-12a3-9770-53afc49918d1'])]\n    #[TestWith(['802dc245-aaaa-3649-98c6-31c549b0df86'])]\n    #[TestWith(['92d2e5ad-bc4e-4947-a8d9-77706172ca83'])]\n    #[TestWith(['6e124559-d260-511e-afdc-e57c7025fed0'])]\n    public function testUuidV6KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V6]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-7000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-7fff-bfff-ffffffffffff'])]\n    #[TestWith(['01910577-4898-7c47-966e-68d127dde2ac'])]\n    public function testUuidV7OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V7]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['15baaab2-f310-11d2-9ecf-53afc49918d1'])]\n    #[TestWith(['acd44dc8-d2cc-326c-9e3a-80a3305a25e8'])]\n    #[TestWith(['7fc2705f-a8a4-5b31-99a8-890686d64189'])]\n    #[TestWith(['1ecbc991-3552-6920-998e-efad54178a98'])]\n    public function testUuidV7KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V7]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith(['00000000-0000-8000-8000-000000000000'])]\n    #[TestWith(['ffffffff-ffff-8fff-bfff-ffffffffffff'])]\n    #[TestWith(['01910577-4898-8c47-966e-68d127dde2ac'])]\n    public function testUuidV8OK(string $uuid)\n    {\n        $this->assertMatchesRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V8]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n\n    #[TestWith([''])]\n    #[TestWith(['foo'])]\n    #[TestWith(['15baaab2-f310-11d2-9ecf-53afc49918d1'])]\n    #[TestWith(['acd44dc8-d2cc-326c-9e3a-80a3305a25e8'])]\n    #[TestWith(['7fc2705f-a8a4-5b31-99a8-890686d64189'])]\n    #[TestWith(['1ecbc991-3552-6920-998e-efad54178a98'])]\n    public function testUuidV8KO(string $uuid)\n    {\n        $this->assertDoesNotMatchRegularExpression(\n            (new Route('/{uuid}', [], ['uuid' => Requirement::UUID_V8]))->compile()->getRegex(),\n            '/'.$uuid,\n        );\n    }\n}\n"
  },
  {
    "path": "Tests/RouteCollectionTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\Resource\\FileResource;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCollection;\n\nclass RouteCollectionTest extends TestCase\n{\n    public function testRoute()\n    {\n        $collection = new RouteCollection();\n        $route = new Route('/foo');\n        $collection->add('foo', $route);\n        $this->assertEquals(['foo' => $route], $collection->all(), '->add() adds a route');\n        $this->assertEquals($route, $collection->get('foo'), '->get() returns a route by name');\n        $this->assertNull($collection->get('bar'), '->get() returns null if a route does not exist');\n    }\n\n    public function testOverriddenRoute()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n        $collection->add('foo', new Route('/foo1'));\n\n        $this->assertEquals('/foo1', $collection->get('foo')->getPath());\n    }\n\n    public function testDeepOverriddenRoute()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $collection1 = new RouteCollection();\n        $collection1->add('foo', new Route('/foo1'));\n\n        $collection2 = new RouteCollection();\n        $collection2->add('foo', new Route('/foo2'));\n\n        $collection1->addCollection($collection2);\n        $collection->addCollection($collection1);\n\n        $this->assertEquals('/foo2', $collection1->get('foo')->getPath());\n        $this->assertEquals('/foo2', $collection->get('foo')->getPath());\n    }\n\n    public function testIterator()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $collection1 = new RouteCollection();\n        $collection1->add('bar', $bar = new Route('/bar'));\n        $collection1->add('foo', $foo = new Route('/foo-new'));\n        $collection->addCollection($collection1);\n        $collection->add('last', $last = new Route('/last'));\n\n        $this->assertInstanceOf(\\ArrayIterator::class, $collection->getIterator());\n        $this->assertSame(['bar' => $bar, 'foo' => $foo, 'last' => $last], $collection->getIterator()->getArrayCopy());\n    }\n\n    public function testCount()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $collection1 = new RouteCollection();\n        $collection1->add('bar', new Route('/bar'));\n        $collection->addCollection($collection1);\n\n        $this->assertCount(2, $collection);\n    }\n\n    public function testAddCollection()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $collection1 = new RouteCollection();\n        $collection1->add('bar', $bar = new Route('/bar'));\n        $collection1->add('foo', $foo = new Route('/foo-new'));\n\n        $collection2 = new RouteCollection();\n        $collection2->add('grandchild', $grandchild = new Route('/grandchild'));\n\n        $collection1->addCollection($collection2);\n        $collection->addCollection($collection1);\n        $collection->add('last', $last = new Route('/last'));\n\n        $this->assertSame(['bar' => $bar, 'foo' => $foo, 'grandchild' => $grandchild, 'last' => $last], $collection->all(),\n            '->addCollection() imports routes of another collection, overrides if necessary and adds them at the end');\n    }\n\n    public function testAddCollectionWithResources()\n    {\n        $collection = new RouteCollection();\n        $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/empty.yml'));\n        $collection1 = new RouteCollection();\n        $collection1->addResource($foo1 = new FileResource(__DIR__.'/Fixtures/file_resource.yml'));\n        $collection->addCollection($collection1);\n        $this->assertEquals([$foo, $foo1], $collection->getResources(), '->addCollection() merges resources');\n    }\n\n    public function testAddDefaultsAndRequirementsAndOptions()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/{placeholder}'));\n        $collection1 = new RouteCollection();\n        $collection1->add('bar', new Route('/{placeholder}',\n            ['_controller' => 'fixed', 'placeholder' => 'default'], ['placeholder' => '.+'], ['option' => 'value'])\n        );\n        $collection->addCollection($collection1);\n\n        $collection->addDefaults(['placeholder' => 'new-default']);\n        $this->assertEquals(['placeholder' => 'new-default'], $collection->get('foo')->getDefaults(), '->addDefaults() adds defaults to all routes');\n        $this->assertEquals(['_controller' => 'fixed', 'placeholder' => 'new-default'], $collection->get('bar')->getDefaults(),\n            '->addDefaults() adds defaults to all routes and overwrites existing ones');\n\n        $collection->addRequirements(['placeholder' => '\\d+']);\n        $this->assertEquals(['placeholder' => '\\d+'], $collection->get('foo')->getRequirements(), '->addRequirements() adds requirements to all routes');\n        $this->assertEquals(['placeholder' => '\\d+'], $collection->get('bar')->getRequirements(),\n            '->addRequirements() adds requirements to all routes and overwrites existing ones');\n\n        $collection->addOptions(['option' => 'new-value']);\n        $this->assertEquals(\n            ['option' => 'new-value', 'compiler_class' => 'Symfony\\\\Component\\\\Routing\\\\RouteCompiler'],\n            $collection->get('bar')->getOptions(), '->addOptions() adds options to all routes and overwrites existing ones'\n        );\n    }\n\n    public function testAddPrefix()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', $foo = new Route('/foo'));\n        $collection2 = new RouteCollection();\n        $collection2->add('bar', $bar = new Route('/bar'));\n        $collection->addCollection($collection2);\n        $collection->addPrefix(' / ');\n        $this->assertSame('/foo', $collection->get('foo')->getPath(), '->addPrefix() trims the prefix and a single slash has no effect');\n        $collection->addPrefix('/{admin}', ['admin' => 'admin'], ['admin' => '\\d+']);\n        $this->assertEquals('/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() adds a prefix to all routes');\n        $this->assertEquals('/{admin}/bar', $collection->get('bar')->getPath(), '->addPrefix() adds a prefix to all routes');\n        $this->assertEquals(['admin' => 'admin'], $collection->get('foo')->getDefaults(), '->addPrefix() adds defaults to all routes');\n        $this->assertEquals(['admin' => 'admin'], $collection->get('bar')->getDefaults(), '->addPrefix() adds defaults to all routes');\n        $this->assertEquals(['admin' => '\\d+'], $collection->get('foo')->getRequirements(), '->addPrefix() adds requirements to all routes');\n        $this->assertEquals(['admin' => '\\d+'], $collection->get('bar')->getRequirements(), '->addPrefix() adds requirements to all routes');\n        $collection->addPrefix('0');\n        $this->assertEquals('/0/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() ensures a prefix must start with a slash and must not end with a slash');\n        $collection->addPrefix('/ /');\n        $this->assertSame('/ /0/{admin}/foo', $collection->get('foo')->getPath(), '->addPrefix() can handle spaces if desired');\n        $this->assertSame('/ /0/{admin}/bar', $collection->get('bar')->getPath(), 'the route pattern of an added collection is in synch with the added prefix');\n    }\n\n    public function testAddPrefixOverridesDefaultsAndRequirements()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', $foo = new Route('/foo.{_format}'));\n        $collection->add('bar', $bar = new Route('/bar.{_format}', [], ['_format' => 'json']));\n        $collection->addPrefix('/admin', [], ['_format' => 'html']);\n\n        $this->assertEquals('html', $collection->get('foo')->getRequirement('_format'), '->addPrefix() overrides existing requirements');\n        $this->assertEquals('html', $collection->get('bar')->getRequirement('_format'), '->addPrefix() overrides existing requirements');\n    }\n\n    public function testResource()\n    {\n        $collection = new RouteCollection();\n        $collection->addResource($foo = new FileResource(__DIR__.'/Fixtures/empty.yml'));\n        $collection->addResource($bar = new FileResource(__DIR__.'/Fixtures/file_resource.yml'));\n        $collection->addResource(new FileResource(__DIR__.'/Fixtures/empty.yml'));\n\n        $this->assertEquals([$foo, $bar], $collection->getResources(),\n            '->addResource() adds a resource and getResources() only returns unique ones by comparing the string representation');\n    }\n\n    public function testUniqueRouteWithGivenName()\n    {\n        $collection1 = new RouteCollection();\n        $collection1->add('foo', new Route('/old'));\n        $collection2 = new RouteCollection();\n        $collection3 = new RouteCollection();\n        $collection3->add('foo', $new = new Route('/new'));\n\n        $collection2->addCollection($collection3);\n        $collection1->addCollection($collection2);\n\n        $this->assertSame($new, $collection1->get('foo'), '->get() returns new route that overrode previous one');\n        // size of 1 because collection1 contains /new but not /old anymore\n        $this->assertCount(1, $collection1->getIterator(), '->addCollection() removes previous routes when adding new routes with the same name');\n    }\n\n    public function testGet()\n    {\n        $collection1 = new RouteCollection();\n        $collection1->add('a', $a = new Route('/a'));\n        $collection2 = new RouteCollection();\n        $collection2->add('b', $b = new Route('/b'));\n        $collection1->addCollection($collection2);\n        $collection1->add('$péß^a|', $c = new Route('/special'));\n\n        $this->assertSame($b, $collection1->get('b'), '->get() returns correct route in child collection');\n        $this->assertSame($c, $collection1->get('$péß^a|'), '->get() can handle special characters');\n        $this->assertNull($collection2->get('a'), '->get() does not return the route defined in parent collection');\n        $this->assertNull($collection1->get('non-existent'), '->get() returns null when route does not exist');\n        $this->assertNull($collection1->get(0), '->get() does not disclose internal child RouteCollection');\n    }\n\n    public function testRemove()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo'));\n\n        $collection1 = new RouteCollection();\n        $collection1->add('bar', $bar = new Route('/bar'));\n        $collection->addCollection($collection1);\n        $collection->add('last', $last = new Route('/last'));\n        $collection->addAlias('alias_removed_when_removing_route_foo', 'foo');\n        $collection->addAlias('alias_directly_removed', 'bar');\n\n        $collection->remove('foo');\n        $this->assertSame(['bar' => $bar, 'last' => $last], $collection->all(), '->remove() can remove a single route');\n        $collection->remove('alias_directly_removed');\n        $this->assertNull($collection->getAlias('alias_directly_removed'));\n        $collection->remove(['bar', 'last']);\n        $this->assertSame([], $collection->all(), '->remove() accepts an array and can remove multiple routes at once');\n        $this->assertNull($collection->getAlias('alias_removed_when_removing_route_foo'));\n    }\n\n    public function testSetHost()\n    {\n        $collection = new RouteCollection();\n        $routea = new Route('/a');\n        $routeb = new Route('/b', [], [], [], '{locale}.example.net');\n        $collection->add('a', $routea);\n        $collection->add('b', $routeb);\n\n        $collection->setHost('{locale}.example.com');\n\n        $this->assertEquals('{locale}.example.com', $routea->getHost());\n        $this->assertEquals('{locale}.example.com', $routeb->getHost());\n    }\n\n    public function testSetCondition()\n    {\n        $collection = new RouteCollection();\n        $routea = new Route('/a');\n        $routeb = new Route('/b', [], [], [], '{locale}.example.net', [], [], 'context.getMethod() == \"GET\"');\n        $collection->add('a', $routea);\n        $collection->add('b', $routeb);\n\n        $collection->setCondition('context.getMethod() == \"POST\"');\n\n        $this->assertEquals('context.getMethod() == \"POST\"', $routea->getCondition());\n        $this->assertEquals('context.getMethod() == \"POST\"', $routeb->getCondition());\n    }\n\n    public function testClone()\n    {\n        $collection = new RouteCollection();\n        $collection->add('a', new Route('/a'));\n        $collection->add('b', new Route('/b', ['placeholder' => 'default'], ['placeholder' => '.+']));\n\n        $clonedCollection = clone $collection;\n\n        $this->assertCount(2, $clonedCollection);\n        $this->assertEquals($collection->get('a'), $clonedCollection->get('a'));\n        $this->assertNotSame($collection->get('a'), $clonedCollection->get('a'));\n        $this->assertEquals($collection->get('b'), $clonedCollection->get('b'));\n        $this->assertNotSame($collection->get('b'), $clonedCollection->get('b'));\n    }\n\n    public function testSetSchemes()\n    {\n        $collection = new RouteCollection();\n        $routea = new Route('/a', [], [], [], '', 'http');\n        $routeb = new Route('/b');\n        $collection->add('a', $routea);\n        $collection->add('b', $routeb);\n\n        $collection->setSchemes(['http', 'https']);\n\n        $this->assertEquals(['http', 'https'], $routea->getSchemes());\n        $this->assertEquals(['http', 'https'], $routeb->getSchemes());\n    }\n\n    public function testSetMethods()\n    {\n        $collection = new RouteCollection();\n        $routea = new Route('/a', [], [], [], '', [], ['GET', 'POST']);\n        $routeb = new Route('/b');\n        $collection->add('a', $routea);\n        $collection->add('b', $routeb);\n\n        $collection->setMethods('PUT');\n\n        $this->assertEquals(['PUT'], $routea->getMethods());\n        $this->assertEquals(['PUT'], $routeb->getMethods());\n    }\n\n    public function testAddNamePrefix()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', $foo = new Route('/foo'));\n        $collection->add('bar', $bar = new Route('/bar'));\n        $collection->add('api_foo', $apiFoo = new Route('/api/foo'));\n        $collection->addNamePrefix('api_');\n\n        $this->assertEquals($foo, $collection->get('api_foo'));\n        $this->assertEquals($bar, $collection->get('api_bar'));\n        $this->assertEquals($apiFoo, $collection->get('api_api_foo'));\n        $this->assertNull($collection->get('foo'));\n        $this->assertNull($collection->get('bar'));\n    }\n\n    public function testAddNamePrefixCanonicalRouteName()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', new Route('/foo', ['_canonical_route' => 'foo']));\n        $collection->add('bar', new Route('/bar', ['_canonical_route' => 'bar']));\n        $collection->add('api_foo', new Route('/api/foo', ['_canonical_route' => 'api_foo']));\n        $collection->addNamePrefix('api_');\n\n        $this->assertEquals('api_foo', $collection->get('api_foo')->getDefault('_canonical_route'));\n        $this->assertEquals('api_bar', $collection->get('api_bar')->getDefault('_canonical_route'));\n        $this->assertEquals('api_api_foo', $collection->get('api_api_foo')->getDefault('_canonical_route'));\n    }\n\n    public function testAddWithPriority()\n    {\n        $collection = new RouteCollection();\n        $collection->add('foo', $foo = new Route('/foo'), 0);\n        $collection->add('bar', $bar = new Route('/bar'), 1);\n        $collection->add('baz', $baz = new Route('/baz'));\n\n        $expected = [\n            'bar' => $bar,\n            'foo' => $foo,\n            'baz' => $baz,\n        ];\n\n        $this->assertSame($expected, $collection->all());\n\n        $collection2 = new RouteCollection();\n        $collection2->add('foo2', $foo2 = new Route('/foo'), 0);\n        $collection2->add('bar2', $bar2 = new Route('/bar'), 1);\n        $collection2->add('baz2', $baz2 = new Route('/baz'));\n        $collection2->addCollection($collection);\n\n        $expected = [\n            'bar2' => $bar2,\n            'bar' => $bar,\n            'foo2' => $foo2,\n            'baz2' => $baz2,\n            'foo' => $foo,\n            'baz' => $baz,\n        ];\n\n        $this->assertSame($expected, $collection2->all());\n    }\n\n    public function testAddWithPriorityAndPrefix()\n    {\n        $collection3 = new RouteCollection();\n        $collection3->add('foo3', $foo3 = new Route('/foo'), 0);\n        $collection3->add('bar3', $bar3 = new Route('/bar'), 1);\n        $collection3->add('baz3', $baz3 = new Route('/baz'));\n        $collection3->addNamePrefix('prefix_');\n\n        $expected = [\n            'prefix_bar3' => $bar3,\n            'prefix_foo3' => $foo3,\n            'prefix_baz3' => $baz3,\n        ];\n\n        $this->assertSame($expected, $collection3->all());\n    }\n\n    public function testAddNamePrefixDoesNotBreakExternalAliases()\n    {\n        $collection = new RouteCollection();\n        $collection->add('local_route', new Route('/local'));\n        $collection->addAlias('alias_to_local', 'local_route');\n        $collection->addAlias('alias_to_external', 'external_route');\n        $collection->addNamePrefix('prefix_');\n\n        $aliases = $collection->getAliases();\n\n        $this->assertEquals('prefix_local_route', $aliases['prefix_alias_to_local']->getId(), 'Alias to local route should have its target prefixed');\n        $this->assertEquals('external_route', $aliases['prefix_alias_to_external']->getId(), 'Alias to external route should NOT have its target prefixed');\n    }\n}\n"
  },
  {
    "path": "Tests/RouteCompilerTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\RouteCompiler;\n\nclass RouteCompilerTest extends TestCase\n{\n    #[DataProvider('provideCompileData')]\n    public function testCompile($name, $arguments, $prefix, $regex, $variables, $tokens)\n    {\n        $r = new \\ReflectionClass(Route::class);\n        $route = $r->newInstanceArgs($arguments);\n\n        $compiled = $route->compile();\n        $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');\n        $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)');\n        $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');\n        $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');\n    }\n\n    public static function provideCompileData()\n    {\n        return [\n            [\n                'Static route',\n                ['/foo'],\n                '/foo', '{^/foo$}sD', [], [\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with a variable',\n                ['/foo/{bar}'],\n                '/foo', '{^/foo/(?P<bar>[^/]++)$}sD', ['bar'], [\n                    ['variable', '/', '[^/]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with a variable that has a default value',\n                ['/foo/{bar}', ['bar' => 'bar']],\n                '/foo', '{^/foo(?:/(?P<bar>[^/]++))?$}sD', ['bar'], [\n                    ['variable', '/', '[^/]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with several variables',\n                ['/foo/{bar}/{foobar}'],\n                '/foo', '{^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$}sD', ['bar', 'foobar'], [\n                    ['variable', '/', '[^/]++', 'foobar'],\n                    ['variable', '/', '[^/]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with several variables that have default values',\n                ['/foo/{bar}/{foobar}', ['bar' => 'bar', 'foobar' => '']],\n                '/foo', '{^/foo(?:/(?P<bar>[^/]++)(?:/(?P<foobar>[^/]++))?)?$}sD', ['bar', 'foobar'], [\n                    ['variable', '/', '[^/]++', 'foobar'],\n                    ['variable', '/', '[^/]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with several variables but some of them have no default values',\n                ['/foo/{bar}/{foobar}', ['bar' => 'bar']],\n                '/foo', '{^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$}sD', ['bar', 'foobar'], [\n                    ['variable', '/', '[^/]++', 'foobar'],\n                    ['variable', '/', '[^/]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with an optional variable as the first segment',\n                ['/{bar}', ['bar' => 'bar']],\n                '', '{^/(?P<bar>[^/]++)?$}sD', ['bar'], [\n                    ['variable', '/', '[^/]++', 'bar'],\n                ],\n            ],\n\n            [\n                'Route with a requirement of 0',\n                ['/{bar}', ['bar' => null], ['bar' => '0']],\n                '', '{^/(?P<bar>0)?$}sD', ['bar'], [\n                    ['variable', '/', '0', 'bar'],\n                ],\n            ],\n\n            [\n                'Route with an optional variable as the first segment with requirements',\n                ['/{bar}', ['bar' => 'bar'], ['bar' => '(foo|bar)']],\n                '', '{^/(?P<bar>(?:foo|bar))?$}sD', ['bar'], [\n                    ['variable', '/', '(?:foo|bar)', 'bar'],\n                ],\n            ],\n\n            [\n                'Route with only optional variables',\n                ['/{foo}/{bar}', ['foo' => 'foo', 'bar' => 'bar']],\n                '', '{^/(?P<foo>[^/]++)?(?:/(?P<bar>[^/]++))?$}sD', ['foo', 'bar'], [\n                    ['variable', '/', '[^/]++', 'bar'],\n                    ['variable', '/', '[^/]++', 'foo'],\n                ],\n            ],\n\n            [\n                'Route with a variable in last position',\n                ['/foo-{bar}'],\n                '/foo-', '{^/foo\\-(?P<bar>[^/]++)$}sD', ['bar'], [\n                    ['variable', '-', '[^/]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Route with nested placeholders',\n                ['/{static{var}static}'],\n                '/{static', '{^/\\{static(?P<var>[^/]+)static\\}$}sD', ['var'], [\n                    ['text', 'static}'],\n                    ['variable', '', '[^/]+', 'var'],\n                    ['text', '/{static'],\n                ],\n            ],\n\n            [\n                'Route without separator between variables',\n                ['/{w}{x}{y}{z}.{_format}', ['z' => 'default-z', '_format' => 'html'], ['y' => '(y|Y)']],\n                '', '{^/(?P<w>[^/\\.]+)(?P<x>[^/\\.]+)(?P<y>(?:y|Y))(?:(?P<z>[^/\\.]++)(?:\\.(?P<_format>[^/]++))?)?$}sD', ['w', 'x', 'y', 'z', '_format'], [\n                    ['variable', '.', '[^/]++', '_format'],\n                    ['variable', '', '[^/\\.]++', 'z'],\n                    ['variable', '', '(?:y|Y)', 'y'],\n                    ['variable', '', '[^/\\.]+', 'x'],\n                    ['variable', '/', '[^/\\.]+', 'w'],\n                ],\n            ],\n\n            [\n                'Route with a format',\n                ['/foo/{bar}.{_format}'],\n                '/foo', '{^/foo/(?P<bar>[^/\\.]++)\\.(?P<_format>[^/]++)$}sD', ['bar', '_format'], [\n                    ['variable', '.', '[^/]++', '_format'],\n                    ['variable', '/', '[^/\\.]++', 'bar'],\n                    ['text', '/foo'],\n                ],\n            ],\n\n            [\n                'Static non UTF-8 route',\n                [\"/fo\\xE9\"],\n                \"/fo\\xE9\", \"{^/fo\\xE9$}sD\", [], [\n                    ['text', \"/fo\\xE9\"],\n                ],\n            ],\n\n            [\n                'Route with an explicit UTF-8 requirement',\n                ['/{bar}', ['bar' => null], ['bar' => '.'], ['utf8' => true]],\n                '', '{^/(?P<bar>.)?$}sDu', ['bar'], [\n                    ['variable', '/', '.', 'bar', true],\n                ],\n            ],\n        ];\n    }\n\n    #[DataProvider('provideCompileImplicitUtf8Data')]\n    public function testCompileImplicitUtf8Data($name, $arguments, $prefix, $regex, $variables, $tokens)\n    {\n        $this->expectException(\\LogicException::class);\n        $r = new \\ReflectionClass(Route::class);\n        $route = $r->newInstanceArgs($arguments);\n\n        $compiled = $route->compile();\n        $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');\n        $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)');\n        $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');\n        $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');\n    }\n\n    public static function provideCompileImplicitUtf8Data()\n    {\n        return [\n            [\n                'Static UTF-8 route',\n                ['/foé'],\n                '/foé',\n                '{^/foé$}sDu',\n                [],\n                [\n                    ['text', '/foé'],\n                ],\n            ],\n\n            [\n                'Route with an implicit UTF-8 requirement',\n                ['/{bar}', ['bar' => null], ['bar' => 'é']],\n                '',\n                '{^/(?P<bar>é)?$}sDu',\n                ['bar'],\n                [\n                    ['variable', '/', 'é', 'bar', true],\n                ],\n            ],\n\n            [\n                'Route with a UTF-8 class requirement',\n                ['/{bar}', ['bar' => null], ['bar' => '\\pM']],\n                '',\n                '{^/(?P<bar>\\pM)?$}sDu',\n                ['bar'],\n                [\n                    ['variable', '/', '\\pM', 'bar', true],\n                ],\n            ],\n\n            [\n                'Route with a UTF-8 separator',\n                ['/foo/{bar}§{_format}', [], [], ['compiler_class' => Utf8RouteCompiler::class]],\n                '/foo',\n                '{^/foo/(?P<bar>[^/§]++)§(?P<_format>[^/]++)$}sDu',\n                ['bar', '_format'],\n                [\n                    ['variable', '§', '[^/]++', '_format', true],\n                    ['variable', '/', '[^/§]++', 'bar', true],\n                    ['text', '/foo'],\n                ],\n            ],\n        ];\n    }\n\n    public function testRouteWithSameVariableTwice()\n    {\n        $this->expectException(\\LogicException::class);\n        $route = new Route('/{name}/{name}');\n\n        $route->compile();\n    }\n\n    public function testRouteCharsetMismatch()\n    {\n        $route = new Route(\"/\\xE9/{bar}\", [], ['bar' => '.'], ['utf8' => true]);\n\n        $this->expectException(\\LogicException::class);\n\n        $route->compile();\n    }\n\n    public function testRequirementCharsetMismatch()\n    {\n        $route = new Route('/foo/{bar}', [], ['bar' => \"\\xE9\"], ['utf8' => true]);\n\n        $this->expectException(\\LogicException::class);\n\n        $route->compile();\n    }\n\n    public function testRouteWithFragmentAsPathParameter()\n    {\n        $route = new Route('/{_fragment}');\n\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $route->compile();\n    }\n\n    #[DataProvider('getVariableNamesStartingWithADigit')]\n    public function testRouteWithVariableNameStartingWithADigit(string $name)\n    {\n        $this->expectException(\\DomainException::class);\n        $route = new Route('/{'.$name.'}');\n        $route->compile();\n    }\n\n    public static function getVariableNamesStartingWithADigit()\n    {\n        return [\n            ['09'],\n            ['123'],\n            ['1e2'],\n        ];\n    }\n\n    #[DataProvider('provideCompileWithHostData')]\n    public function testCompileWithHost(string $name, array $arguments, string $prefix, string $regex, array $variables, array $pathVariables, array $tokens, string $hostRegex, array $hostVariables, array $hostTokens)\n    {\n        $r = new \\ReflectionClass(Route::class);\n        $route = $r->newInstanceArgs($arguments);\n\n        $compiled = $route->compile();\n        $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)');\n        $this->assertEquals($regex, str_replace([\"\\n\", ' '], '', $compiled->getRegex()), $name.' (regex)');\n        $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)');\n        $this->assertEquals($pathVariables, $compiled->getPathVariables(), $name.' (path variables)');\n        $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)');\n        $this->assertEquals($hostRegex, str_replace([\"\\n\", ' '], '', $compiled->getHostRegex()), $name.' (host regex)');\n        $this->assertEquals($hostVariables, $compiled->getHostVariables(), $name.' (host variables)');\n        $this->assertEquals($hostTokens, $compiled->getHostTokens(), $name.' (host tokens)');\n    }\n\n    public static function provideCompileWithHostData()\n    {\n        return [\n            [\n                'Route with host pattern',\n                ['/hello', [], [], [], 'www.example.com'],\n                '/hello', '{^/hello$}sD', [], [], [\n                    ['text', '/hello'],\n                ],\n                '{^www\\.example\\.com$}sDi', [], [\n                    ['text', 'www.example.com'],\n                ],\n            ],\n            [\n                'Route with host pattern and some variables',\n                ['/hello/{name}', [], [], [], 'www.example.{tld}'],\n                '/hello', '{^/hello/(?P<name>[^/]++)$}sD', ['tld', 'name'], ['name'], [\n                    ['variable', '/', '[^/]++', 'name'],\n                    ['text', '/hello'],\n                ],\n                '{^www\\.example\\.(?P<tld>[^\\.]++)$}sDi', ['tld'], [\n                    ['variable', '.', '[^\\.]++', 'tld'],\n                    ['text', 'www.example'],\n                ],\n            ],\n            [\n                'Route with variable at beginning of host',\n                ['/hello', [], [], [], '{locale}.example.{tld}'],\n                '/hello', '{^/hello$}sD', ['locale', 'tld'], [], [\n                    ['text', '/hello'],\n                ],\n                '{^(?P<locale>[^\\.]++)\\.example\\.(?P<tld>[^\\.]++)$}sDi', ['locale', 'tld'], [\n                    ['variable', '.', '[^\\.]++', 'tld'],\n                    ['text', '.example'],\n                    ['variable', '', '[^\\.]++', 'locale'],\n                ],\n            ],\n            [\n                'Route with host variables that has a default value',\n                ['/hello', ['locale' => 'a', 'tld' => 'b'], [], [], '{locale}.example.{tld}'],\n                '/hello', '{^/hello$}sD', ['locale', 'tld'], [], [\n                    ['text', '/hello'],\n                ],\n                '{^(?P<locale>[^\\.]++)\\.example\\.(?P<tld>[^\\.]++)$}sDi', ['locale', 'tld'], [\n                    ['variable', '.', '[^\\.]++', 'tld'],\n                    ['text', '.example'],\n                    ['variable', '', '[^\\.]++', 'locale'],\n                ],\n            ],\n        ];\n    }\n\n    public function testRouteWithTooLongVariableName()\n    {\n        $route = new Route(\\sprintf('/{%s}', str_repeat('a', RouteCompiler::VARIABLE_MAXIMUM_LENGTH + 1)));\n\n        $this->expectException(\\DomainException::class);\n\n        $route->compile();\n    }\n\n    #[DataProvider('provideRemoveCapturingGroup')]\n    public function testRemoveCapturingGroup(string $regex, string $requirement)\n    {\n        $route = new Route('/{foo}', [], ['foo' => $requirement]);\n\n        $this->assertSame($regex, $route->compile()->getRegex());\n    }\n\n    public static function provideRemoveCapturingGroup()\n    {\n        yield ['{^/(?P<foo>a(?:b|c)(?:d|e)f)$}sD', 'a(b|c)(d|e)f'];\n        yield ['{^/(?P<foo>a\\(b\\)c)$}sD', 'a\\(b\\)c'];\n        yield ['{^/(?P<foo>(?:b))$}sD', '(?:b)'];\n        yield ['{^/(?P<foo>(?(b)b))$}sD', '(?(b)b)'];\n        yield ['{^/(?P<foo>(*F))$}sD', '(*F)'];\n        yield ['{^/(?P<foo>(?:(?:foo)))$}sD', '((foo))'];\n    }\n}\n\nclass Utf8RouteCompiler extends RouteCompiler\n{\n    public const SEPARATORS = '/§';\n}\n"
  },
  {
    "path": "Tests/RouteTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests;\n\nuse PHPUnit\\Framework\\Attributes\\DataProvider;\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Routing\\CompiledRoute;\nuse Symfony\\Component\\Routing\\Route;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\CustomCompiledRoute;\nuse Symfony\\Component\\Routing\\Tests\\Fixtures\\CustomRouteCompiler;\n\nclass RouteTest extends TestCase\n{\n    public function testConstructor()\n    {\n        $route = new Route('/{foo}', ['foo' => 'bar'], ['foo' => '\\d+'], ['foo' => 'bar'], '{locale}.example.com');\n        $this->assertEquals('/{foo}', $route->getPath(), '__construct() takes a path as its first argument');\n        $this->assertEquals(['foo' => 'bar'], $route->getDefaults(), '__construct() takes defaults as its second argument');\n        $this->assertEquals(['foo' => '\\d+'], $route->getRequirements(), '__construct() takes requirements as its third argument');\n        $this->assertEquals('bar', $route->getOption('foo'), '__construct() takes options as its fourth argument');\n        $this->assertEquals('{locale}.example.com', $route->getHost(), '__construct() takes a host pattern as its fifth argument');\n\n        $route = new Route('/', [], [], [], '', ['Https'], ['POST', 'put'], 'context.getMethod() == \"GET\"');\n        $this->assertEquals(['https'], $route->getSchemes(), '__construct() takes schemes as its sixth argument and lowercases it');\n        $this->assertEquals(['POST', 'PUT'], $route->getMethods(), '__construct() takes methods as its seventh argument and uppercases it');\n        $this->assertEquals('context.getMethod() == \"GET\"', $route->getCondition(), '__construct() takes a condition as its eight argument');\n\n        $route = new Route('/', [], [], [], '', 'Https', 'Post');\n        $this->assertEquals(['https'], $route->getSchemes(), '__construct() takes a single scheme as its sixth argument');\n        $this->assertEquals(['POST'], $route->getMethods(), '__construct() takes a single method as its seventh argument');\n    }\n\n    public function testPath()\n    {\n        $route = new Route('/{foo}');\n        $route->setPath('/{bar}');\n        $this->assertEquals('/{bar}', $route->getPath(), '->setPath() sets the path');\n        $route->setPath('');\n        $this->assertEquals('/', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed');\n        $route->setPath('bar');\n        $this->assertEquals('/bar', $route->getPath(), '->setPath() adds a / at the beginning of the path if needed');\n        $this->assertEquals($route, $route->setPath(''), '->setPath() implements a fluent interface');\n        $route->setPath('//path');\n        $this->assertEquals('/path', $route->getPath(), '->setPath() does not allow two slashes \"//\" at the beginning of the path as it would be confused with a network path when generating the path from the route');\n        $route->setPath('/path/{!foo}');\n        $this->assertEquals('/path/{!foo}', $route->getPath(), '->setPath() keeps ! to pass important params');\n        $route->setPath('/path/{bar<\\w++>}');\n        $this->assertEquals('/path/{bar}', $route->getPath(), '->setPath() removes inline requirements');\n        $route->setPath('/path/{foo?value}');\n        $this->assertEquals('/path/{foo}', $route->getPath(), '->setPath() removes inline defaults');\n        $route->setPath('/path/{!bar<\\d+>?value}');\n        $this->assertEquals('/path/{!bar}', $route->getPath(), '->setPath() removes all inline settings');\n    }\n\n    public function testOptions()\n    {\n        $route = new Route('/{foo}');\n        $route->setOptions(['foo' => 'bar']);\n        $this->assertEquals(array_merge([\n            'compiler_class' => 'Symfony\\\\Component\\\\Routing\\\\RouteCompiler',\n        ], ['foo' => 'bar']), $route->getOptions(), '->setOptions() sets the options');\n        $this->assertEquals($route, $route->setOptions([]), '->setOptions() implements a fluent interface');\n\n        $route->setOptions(['foo' => 'foo']);\n        $route->addOptions(['bar' => 'bar']);\n        $this->assertEquals($route, $route->addOptions([]), '->addOptions() implements a fluent interface');\n        $this->assertEquals(['foo' => 'foo', 'bar' => 'bar', 'compiler_class' => 'Symfony\\\\Component\\\\Routing\\\\RouteCompiler'], $route->getOptions(), '->addDefaults() keep previous defaults');\n    }\n\n    public function testOption()\n    {\n        $route = new Route('/{foo}');\n        $this->assertFalse($route->hasOption('foo'), '->hasOption() return false if option is not set');\n        $this->assertEquals($route, $route->setOption('foo', 'bar'), '->setOption() implements a fluent interface');\n        $this->assertEquals('bar', $route->getOption('foo'), '->setOption() sets the option');\n        $this->assertTrue($route->hasOption('foo'), '->hasOption() return true if option is set');\n    }\n\n    public function testDefaults()\n    {\n        $route = new Route('/{foo}');\n        $route->setDefaults(['foo' => 'bar']);\n        $this->assertEquals(['foo' => 'bar'], $route->getDefaults(), '->setDefaults() sets the defaults');\n        $this->assertEquals($route, $route->setDefaults([]), '->setDefaults() implements a fluent interface');\n\n        $route->setDefault('foo', 'bar');\n        $this->assertEquals('bar', $route->getDefault('foo'), '->setDefault() sets a default value');\n\n        $route->setDefault('foo2', 'bar2');\n        $this->assertEquals('bar2', $route->getDefault('foo2'), '->getDefault() return the default value');\n        $this->assertNull($route->getDefault('not_defined'), '->getDefault() return null if default value is not set');\n\n        $route->setDefault('_controller', $closure = static fn () => 'Hello');\n        $this->assertEquals($closure, $route->getDefault('_controller'), '->setDefault() sets a default value');\n\n        $route->setDefaults(['foo' => 'foo']);\n        $route->addDefaults(['bar' => 'bar']);\n        $this->assertEquals($route, $route->addDefaults([]), '->addDefaults() implements a fluent interface');\n        $this->assertEquals(['foo' => 'foo', 'bar' => 'bar'], $route->getDefaults(), '->addDefaults() keep previous defaults');\n    }\n\n    public function testRequirements()\n    {\n        $route = new Route('/{foo}');\n        $route->setRequirements(['foo' => '\\d+']);\n        $this->assertEquals(['foo' => '\\d+'], $route->getRequirements(), '->setRequirements() sets the requirements');\n        $this->assertEquals('\\d+', $route->getRequirement('foo'), '->getRequirement() returns a requirement');\n        $this->assertNull($route->getRequirement('bar'), '->getRequirement() returns null if a requirement is not defined');\n        $route->setRequirements(['foo' => '^\\d+$']);\n        $this->assertEquals('\\d+', $route->getRequirement('foo'), '->getRequirement() removes ^ and $ from the path');\n        $this->assertEquals($route, $route->setRequirements([]), '->setRequirements() implements a fluent interface');\n\n        $route->setRequirements(['foo' => '\\d+']);\n        $route->addRequirements(['bar' => '\\d+']);\n        $this->assertEquals($route, $route->addRequirements([]), '->addRequirements() implements a fluent interface');\n        $this->assertEquals(['foo' => '\\d+', 'bar' => '\\d+'], $route->getRequirements(), '->addRequirement() keep previous requirements');\n    }\n\n    public function testRequirement()\n    {\n        $route = new Route('/{foo}');\n        $this->assertFalse($route->hasRequirement('foo'), '->hasRequirement() return false if requirement is not set');\n        $route->setRequirement('foo', '^\\d+$');\n        $this->assertEquals('\\d+', $route->getRequirement('foo'), '->setRequirement() removes ^ and $ from the path');\n        $this->assertTrue($route->hasRequirement('foo'), '->hasRequirement() return true if requirement is set');\n    }\n\n    public function testRequirementAlternativeStartAndEndRegexSyntax()\n    {\n        $route = new Route('/{foo}');\n        $route->setRequirement('foo', '\\A\\d+\\z');\n        $this->assertEquals('\\d+', $route->getRequirement('foo'), '->setRequirement() removes \\A and \\z from the path');\n        $this->assertTrue($route->hasRequirement('foo'));\n    }\n\n    #[DataProvider('getInvalidRequirements')]\n    public function testSetInvalidRequirement($req)\n    {\n        $route = new Route('/{foo}');\n\n        $this->expectException(\\InvalidArgumentException::class);\n\n        $route->setRequirement('foo', $req);\n    }\n\n    public static function getInvalidRequirements()\n    {\n        return [\n            [''],\n            ['^$'],\n            ['^'],\n            ['$'],\n            ['\\A\\z'],\n            ['\\A'],\n            ['\\z'],\n        ];\n    }\n\n    public function testHost()\n    {\n        $route = new Route('/');\n        $route->setHost('{locale}.example.net');\n        $this->assertEquals('{locale}.example.net', $route->getHost(), '->setHost() sets the host pattern');\n    }\n\n    public function testScheme()\n    {\n        $route = new Route('/');\n        $this->assertEquals([], $route->getSchemes(), 'schemes is initialized with []');\n        $this->assertFalse($route->hasScheme('http'));\n        $route->setSchemes('hTTp');\n        $this->assertEquals(['http'], $route->getSchemes(), '->setSchemes() accepts a single scheme string and lowercases it');\n        $this->assertTrue($route->hasScheme('htTp'));\n        $this->assertFalse($route->hasScheme('httpS'));\n        $route->setSchemes(['HttpS', 'hTTp']);\n        $this->assertEquals(['https', 'http'], $route->getSchemes(), '->setSchemes() accepts an array of schemes and lowercases them');\n        $this->assertTrue($route->hasScheme('htTp'));\n        $this->assertTrue($route->hasScheme('httpS'));\n    }\n\n    public function testMethod()\n    {\n        $route = new Route('/');\n        $this->assertEquals([], $route->getMethods(), 'methods is initialized with []');\n        $route->setMethods('gEt');\n        $this->assertEquals(['GET'], $route->getMethods(), '->setMethods() accepts a single method string and uppercases it');\n        $route->setMethods(['gEt', 'PosT']);\n        $this->assertEquals(['GET', 'POST'], $route->getMethods(), '->setMethods() accepts an array of methods and uppercases them');\n    }\n\n    public function testCondition()\n    {\n        $route = new Route('/');\n        $this->assertSame('', $route->getCondition());\n        $route->setCondition('context.getMethod() == \"GET\"');\n        $this->assertSame('context.getMethod() == \"GET\"', $route->getCondition());\n    }\n\n    public function testCompile()\n    {\n        $route = new Route('/{foo}');\n        $this->assertInstanceOf(CompiledRoute::class, $compiled = $route->compile(), '->compile() returns a compiled route');\n        $this->assertSame($compiled, $route->compile(), '->compile() only compiled the route once if unchanged');\n        $route->setRequirement('foo', '.*');\n        $this->assertNotSame($compiled, $route->compile(), '->compile() recompiles if the route was modified');\n    }\n\n    public function testSerialize()\n    {\n        $route = new Route('/prefix/{foo}', ['foo' => 'default'], ['foo' => '\\d+']);\n\n        $serialized = serialize($route);\n        $unserialized = unserialize($serialized);\n\n        $this->assertEquals($route, $unserialized);\n        $this->assertNotSame($route, $unserialized);\n    }\n\n    #[DataProvider('provideInlineDefaultAndRequirementCases')]\n    public function testInlineDefaultAndRequirement(Route $route, string $expectedPath, string $expectedHost, array $expectedDefaults, array $expectedRequirements)\n    {\n        self::assertSame($expectedPath, $route->getPath());\n        self::assertSame($expectedHost, $route->getHost());\n        self::assertSame($expectedDefaults, $route->getDefaults());\n        self::assertSame($expectedRequirements, $route->getRequirements());\n    }\n\n    public static function provideInlineDefaultAndRequirementCases(): iterable\n    {\n        yield [new Route('/foo/{bar?}'), '/foo/{bar}', '', ['bar' => null], []];\n        yield [new Route('/foo/{bar?baz}'), '/foo/{bar}', '', ['bar' => 'baz'], []];\n        yield [new Route('/foo/{bar?baz<buz>}'), '/foo/{bar}', '', ['bar' => 'baz<buz>'], []];\n        yield [new Route('/foo/{!bar?baz<buz>}'), '/foo/{!bar}', '', ['bar' => 'baz<buz>'], []];\n        yield [new Route('/foo/{bar?}', ['bar' => 'baz']), '/foo/{bar}', '', ['bar' => 'baz'], []];\n\n        yield [new Route('/foo/{bar<.*>}'), '/foo/{bar}', '', [], ['bar' => '.*']];\n        yield [new Route('/foo/{bar<>>}'), '/foo/{bar}', '', [], ['bar' => '>']];\n        yield [new Route('/foo/{bar<.*>}', [], ['bar' => '\\d+']), '/foo/{bar}', '', [], ['bar' => '\\d+']];\n        yield [new Route('/foo/{bar<[a-z]{2}>}'), '/foo/{bar}', '', [], ['bar' => '[a-z]{2}']];\n        yield [new Route('/foo/{!bar<\\d+>}'), '/foo/{!bar}', '', [], ['bar' => '\\d+']];\n\n        yield [new Route('/foo/{bar<.*>?}'), '/foo/{bar}', '', ['bar' => null], ['bar' => '.*']];\n        yield [new Route('/foo/{bar<>>?<>}'), '/foo/{bar}', '', ['bar' => '<>'], ['bar' => '>']];\n\n        yield [new Route('/{foo<.>?\\}/{!bar<\\>?<>}'), '/{foo}/{!bar}', '', ['foo' => '\\\\', 'bar' => '<>'], ['foo' => '.', 'bar' => '\\\\']];\n\n        yield [new Route('/', host: '{bar?}'), '/', '{bar}', ['bar' => null], []];\n        yield [new Route('/', host: '{bar?baz}'), '/', '{bar}', ['bar' => 'baz'], []];\n        yield [new Route('/', host: '{bar?baz<buz>}'), '/', '{bar}', ['bar' => 'baz<buz>'], []];\n        yield [new Route('/', ['bar' => 'baz'], host: '{bar?}'), '/', '{bar}', ['bar' => null], []];\n\n        yield [new Route('/', host: '{bar<.*>}'), '/', '{bar}', [], ['bar' => '.*']];\n        yield [new Route('/', host: '{bar<>>}'), '/', '{bar}', [], ['bar' => '>']];\n        yield [new Route('/', [], ['bar' => '\\d+'], host: '{bar<.*>}'), '/', '{bar}', [], ['bar' => '.*']];\n        yield [new Route('/', host: '{bar<[a-z]{2}>}'), '/', '{bar}', [], ['bar' => '[a-z]{2}']];\n\n        yield [new Route('/', host: '{bar<.*>?}'), '/', '{bar}', ['bar' => null], ['bar' => '.*']];\n        yield [new Route('/', host: '{bar<>>?<>}'), '/', '{bar}', ['bar' => '<>'], ['bar' => '>']];\n    }\n\n    /**\n     * Tests that the compiled version is also serialized to prevent the overhead\n     * of compiling it again after unserialize.\n     */\n    public function testSerializeWhenCompiled()\n    {\n        $route = new Route('/prefix/{foo}', ['foo' => 'default'], ['foo' => '\\d+']);\n        $route->setHost('{locale}.example.net');\n        $route->compile();\n\n        $serialized = serialize($route);\n        $unserialized = unserialize($serialized);\n\n        $this->assertEquals($route, $unserialized);\n        $this->assertNotSame($route, $unserialized);\n    }\n\n    /**\n     * Tests that unserialization does not fail when the compiled Route is of a\n     * class other than CompiledRoute, such as a subclass of it.\n     */\n    public function testSerializeWhenCompiledWithClass()\n    {\n        $route = new Route('/', [], [], ['compiler_class' => CustomRouteCompiler::class]);\n        $this->assertInstanceOf(CustomCompiledRoute::class, $route->compile(), '->compile() returned a proper route');\n\n        $serialized = serialize($route);\n        try {\n            $unserialized = unserialize($serialized);\n            $this->assertInstanceOf(CustomCompiledRoute::class, $unserialized->compile(), 'the unserialized route compiled successfully');\n        } catch (\\Exception $e) {\n            $this->fail('unserializing a route which uses a custom compiled route class');\n        }\n    }\n\n    /**\n     * Tests that the serialized representation of a route in one symfony version\n     * also works in later symfony versions, i.e. the unserialized route is in the\n     * same state as another, semantically equivalent, route.\n     */\n    public function testSerializedRepresentationKeepsWorking()\n    {\n        $serialized = 'O:31:\"Symfony\\Component\\Routing\\Route\":9:{s:4:\"path\";s:13:\"/prefix/{foo}\";s:4:\"host\";s:20:\"{locale}.example.net\";s:8:\"defaults\";a:1:{s:3:\"foo\";s:7:\"default\";}s:12:\"requirements\";a:1:{s:3:\"foo\";s:3:\"\\d+\";}s:7:\"options\";a:1:{s:14:\"compiler_class\";s:39:\"Symfony\\Component\\Routing\\RouteCompiler\";}s:7:\"schemes\";a:0:{}s:7:\"methods\";a:0:{}s:9:\"condition\";s:0:\"\";s:8:\"compiled\";O:39:\"Symfony\\Component\\Routing\\CompiledRoute\":8:{s:4:\"vars\";a:2:{i:0;s:6:\"locale\";i:1;s:3:\"foo\";}s:11:\"path_prefix\";s:7:\"/prefix\";s:10:\"path_regex\";s:31:\"{^/prefix(?:/(?P<foo>\\d+))?$}sD\";s:11:\"path_tokens\";a:2:{i:0;a:4:{i:0;s:8:\"variable\";i:1;s:1:\"/\";i:2;s:3:\"\\d+\";i:3;s:3:\"foo\";}i:1;a:2:{i:0;s:4:\"text\";i:1;s:7:\"/prefix\";}}s:9:\"path_vars\";a:1:{i:0;s:3:\"foo\";}s:10:\"host_regex\";s:40:\"{^(?P<locale>[^\\.]++)\\.example\\.net$}sDi\";s:11:\"host_tokens\";a:2:{i:0;a:2:{i:0;s:4:\"text\";i:1;s:12:\".example.net\";}i:1;a:4:{i:0;s:8:\"variable\";i:1;s:0:\"\";i:2;s:7:\"[^\\.]++\";i:3;s:6:\"locale\";}}s:9:\"host_vars\";a:1:{i:0;s:6:\"locale\";}}}';\n        $unserialized = unserialize($serialized);\n\n        $route = new Route('/prefix/{foo}', ['foo' => 'default'], ['foo' => '\\d+']);\n        $route->setHost('{locale}.example.net');\n        $route->compile();\n\n        $this->assertEquals($route, $unserialized);\n        $this->assertNotSame($route, $unserialized);\n    }\n\n    #[DataProvider('provideNonLocalizedRoutes')]\n    public function testLocaleDefaultWithNonLocalizedRoutes(Route $route)\n    {\n        $this->assertNotSame('fr', $route->getDefault('_locale'));\n        $route->setDefault('_locale', 'fr');\n        $this->assertSame('fr', $route->getDefault('_locale'));\n    }\n\n    #[DataProvider('provideLocalizedRoutes')]\n    public function testLocaleDefaultWithLocalizedRoutes(Route $route)\n    {\n        $expected = $route->getDefault('_locale');\n        $this->assertIsString($expected);\n        $this->assertNotSame('fr', $expected);\n        $route->setDefault('_locale', 'fr');\n        $this->assertSame($expected, $route->getDefault('_locale'));\n    }\n\n    #[DataProvider('provideNonLocalizedRoutes')]\n    public function testLocaleRequirementWithNonLocalizedRoutes(Route $route)\n    {\n        $this->assertNotSame('fr', $route->getRequirement('_locale'));\n        $route->setRequirement('_locale', 'fr');\n        $this->assertSame('fr', $route->getRequirement('_locale'));\n    }\n\n    #[DataProvider('provideLocalizedRoutes')]\n    public function testLocaleRequirementWithLocalizedRoutes(Route $route)\n    {\n        $expected = $route->getRequirement('_locale');\n        $this->assertIsString($expected);\n        $this->assertNotSame('fr', $expected);\n        $route->setRequirement('_locale', 'fr');\n        $this->assertSame($expected, $route->getRequirement('_locale'));\n    }\n\n    public static function provideNonLocalizedRoutes()\n    {\n        return [\n            [new Route('/foo')],\n            [(new Route('/foo'))->setDefault('_locale', 'en')],\n            [(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')],\n            [(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'foobar')],\n        ];\n    }\n\n    public static function provideLocalizedRoutes()\n    {\n        return [\n            [(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en')],\n        ];\n    }\n}\n"
  },
  {
    "path": "Tests/RouterTest.php",
    "content": "<?php\n\n/*\n * This file is part of the Symfony package.\n *\n * (c) Fabien Potencier <fabien@symfony.com>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Symfony\\Component\\Routing\\Tests;\n\nuse PHPUnit\\Framework\\TestCase;\nuse Symfony\\Component\\Config\\Loader\\LoaderInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\nuse Symfony\\Component\\Routing\\Generator\\CompiledUrlGenerator;\nuse Symfony\\Component\\Routing\\Generator\\UrlGenerator;\nuse Symfony\\Component\\Routing\\Generator\\UrlGeneratorInterface;\nuse Symfony\\Component\\Routing\\Matcher\\RequestMatcherInterface;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcher;\nuse Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface;\nuse Symfony\\Component\\Routing\\RouteCollection;\nuse Symfony\\Component\\Routing\\Router;\n\nclass RouterTest extends TestCase\n{\n    private string $cacheDir;\n\n    protected function setUp(): void\n    {\n        $this->cacheDir = tempnam(sys_get_temp_dir(), 'sf_router_');\n        unlink($this->cacheDir);\n        mkdir($this->cacheDir);\n    }\n\n    protected function tearDown(): void\n    {\n        if (is_dir($this->cacheDir)) {\n            array_map('unlink', glob($this->cacheDir.\\DIRECTORY_SEPARATOR.'*'));\n            @rmdir($this->cacheDir);\n        }\n    }\n\n    public function testSetOptionsWithSupportedOptions()\n    {\n        $router = $this->getRouter();\n        $router->setOptions([\n            'cache_dir' => './cache',\n            'debug' => true,\n            'resource_type' => 'ResourceType',\n        ]);\n\n        $this->assertSame('./cache', $router->getOption('cache_dir'));\n        $this->assertTrue($router->getOption('debug'));\n        $this->assertSame('ResourceType', $router->getOption('resource_type'));\n    }\n\n    public function testSetOptionsWithUnsupportedOptions()\n    {\n        $router = $this->getRouter();\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('The Router does not support the following options: \"option_foo\", \"option_bar\"');\n        $router->setOptions([\n            'cache_dir' => './cache',\n            'option_foo' => true,\n            'option_bar' => 'baz',\n            'resource_type' => 'ResourceType',\n        ]);\n    }\n\n    public function testSetOptionWithSupportedOption()\n    {\n        $router = $this->getRouter();\n        $router->setOption('cache_dir', './cache');\n\n        $this->assertSame('./cache', $router->getOption('cache_dir'));\n    }\n\n    public function testSetOptionWithUnsupportedOption()\n    {\n        $router = $this->getRouter();\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('The Router does not support the \"option_foo\" option');\n        $router->setOption('option_foo', true);\n    }\n\n    public function testGetOptionWithUnsupportedOption()\n    {\n        $router = $this->getRouter();\n        $this->expectException(\\InvalidArgumentException::class);\n        $this->expectExceptionMessage('The Router does not support the \"option_foo\" option');\n        $router->getOption('option_foo');\n    }\n\n    public function testThatRouteCollectionIsLoaded()\n    {\n        $loader = $this->createMock(LoaderInterface::class);\n        $router = $this->getRouter($loader);\n        $router->setOption('resource_type', 'ResourceType');\n\n        $routeCollection = new RouteCollection();\n\n        $loader->expects($this->once())\n            ->method('load')->with('routing.yml', 'ResourceType')\n            ->willReturn($routeCollection);\n\n        $this->assertSame($routeCollection, $router->getRouteCollection());\n    }\n\n    public function testMatcherIsCreatedIfCacheIsNotConfigured()\n    {\n        $loader = $this->createMock(LoaderInterface::class);\n        $router = $this->getRouter($loader);\n        $router->setOption('cache_dir', null);\n\n        $loader->expects($this->once())\n            ->method('load')->with('routing.yml', null)\n            ->willReturn(new RouteCollection());\n\n        $this->assertInstanceOf(UrlMatcher::class, $router->getMatcher());\n    }\n\n    public function testGeneratorIsCreatedIfCacheIsNotConfigured()\n    {\n        $loader = $this->createMock(LoaderInterface::class);\n        $router = $this->getRouter($loader);\n        $router->setOption('cache_dir', null);\n\n        $loader->expects($this->once())\n            ->method('load')->with('routing.yml', null)\n            ->willReturn(new RouteCollection());\n\n        $this->assertInstanceOf(CompiledUrlGenerator::class, $router->getGenerator());\n    }\n\n    public function testGeneratorIsCreatedIfCacheIsNotConfiguredNotCompiled()\n    {\n        $loader = $this->createMock(LoaderInterface::class);\n        $router = $this->getRouter($loader);\n        $router->setOption('cache_dir', null);\n        $router->setOption('generator_class', UrlGenerator::class);\n\n        $loader->expects($this->once())\n            ->method('load')->with('routing.yml', null)\n            ->willReturn(new RouteCollection());\n\n        $this->assertInstanceOf(UrlGenerator::class, $router->getGenerator());\n        $this->assertNotInstanceOf(CompiledUrlGenerator::class, $router->getGenerator());\n    }\n\n    public function testMatchRequestWithUrlMatcherInterface()\n    {\n        $matcher = $this->createMock(UrlMatcherInterface::class);\n        $matcher->expects($this->once())->method('match');\n\n        $router = $this->getRouter();\n        $p = new \\ReflectionProperty($router, 'matcher');\n        $p->setValue($router, $matcher);\n\n        $router->matchRequest(Request::create('/'));\n    }\n\n    public function testMatchRequestWithRequestMatcherInterface()\n    {\n        $matcher = $this->createMock(RequestMatcherInterface::class);\n        $matcher->expects($this->once())->method('matchRequest');\n\n        $router = $this->getRouter();\n        $p = new \\ReflectionProperty($router, 'matcher');\n        $p->setValue($router, $matcher);\n\n        $router->matchRequest(Request::create('/'));\n    }\n\n    public function testDefaultLocaleIsPassedToGeneratorClass()\n    {\n        $loader = $this->createMock(LoaderInterface::class);\n        $loader->expects($this->once())\n            ->method('load')->with('routing.yml', null)\n            ->willReturn(new RouteCollection());\n\n        $router = new Router($loader, 'routing.yml', [\n            'cache_dir' => null,\n        ], null, null, 'hr');\n\n        $generator = $router->getGenerator();\n\n        $this->assertInstanceOf(UrlGeneratorInterface::class, $generator);\n\n        $p = new \\ReflectionProperty($generator, 'defaultLocale');\n\n        $this->assertSame('hr', $p->getValue($generator));\n    }\n\n    public function testDefaultLocaleIsPassedToCompiledGeneratorCacheClass()\n    {\n        $loader = $this->createMock(LoaderInterface::class);\n        $loader->expects($this->once())\n            ->method('load')->with('routing.yml', null)\n            ->willReturn(new RouteCollection());\n\n        $router = new Router($loader, 'routing.yml', [\n            'cache_dir' => $this->cacheDir,\n        ], null, null, 'hr');\n\n        $generator = $router->getGenerator();\n\n        $this->assertInstanceOf(UrlGeneratorInterface::class, $generator);\n\n        $p = new \\ReflectionProperty($generator, 'defaultLocale');\n\n        $this->assertSame('hr', $p->getValue($generator));\n    }\n\n    private function getRouter(?LoaderInterface $loader = null): Router\n    {\n        return new Router($loader ?? $this->createStub(LoaderInterface::class), 'routing.yml');\n    }\n}\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"symfony/routing\",\n    \"type\": \"library\",\n    \"description\": \"Maps an HTTP request to a set of configuration variables\",\n    \"keywords\": [\"routing\", \"router\", \"url\", \"uri\"],\n    \"homepage\": \"https://symfony.com\",\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Fabien Potencier\",\n            \"email\": \"fabien@symfony.com\"\n        },\n        {\n            \"name\": \"Symfony Community\",\n            \"homepage\": \"https://symfony.com/contributors\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=8.4\",\n        \"symfony/deprecation-contracts\": \"^2.5|^3\"\n    },\n    \"require-dev\": {\n        \"psr/log\": \"^1|^2|^3\",\n        \"symfony/config\": \"^7.4|^8.0\",\n        \"symfony/expression-language\": \"^7.4|^8.0\",\n        \"symfony/dependency-injection\": \"^7.4|^8.0\",\n        \"symfony/http-foundation\": \"^7.4|^8.0\",\n        \"symfony/yaml\": \"^7.4|^8.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": { \"Symfony\\\\Component\\\\Routing\\\\\": \"\" },\n        \"exclude-from-classmap\": [\n            \"/Tests/\"\n        ]\n    },\n    \"minimum-stability\": \"dev\"\n}\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"https://schema.phpunit.de/11.3/phpunit.xsd\"\n         backupGlobals=\"false\"\n         colors=\"true\"\n         bootstrap=\"vendor/autoload.php\"\n         failOnDeprecation=\"true\"\n         failOnRisky=\"true\"\n         failOnWarning=\"true\"\n>\n    <php>\n        <ini name=\"error_reporting\" value=\"-1\" />\n    </php>\n\n    <testsuites>\n        <testsuite name=\"Symfony Routing Component Test Suite\">\n            <directory>./Tests/</directory>\n        </testsuite>\n    </testsuites>\n\n    <source ignoreSuppressionOfDeprecations=\"true\">\n        <include>\n            <directory>./</directory>\n        </include>\n        <exclude>\n            <directory>./Tests</directory>\n            <directory>./vendor</directory>\n        </exclude>\n    </source>\n\n    <extensions>\n        <bootstrap class=\"Symfony\\Bridge\\PhpUnit\\SymfonyExtension\" />\n    </extensions>\n</phpunit>\n"
  }
]