 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class NullCoalesceNode extends Node
{
    public function __construct(Node $expr1, Node $expr2)
    {
        parent::__

(')
            ->compile($this->nodes['expr2'])
            ->raw('))')
        ;
    }

    public function evaluate(array $functions, array $values): mixed
    {
        if ($this->nodes['expr1'] instanceof GetAttrNode) {
            $this->addNullCoale

construct(['expr1' => $expr1, 'expr2' => $expr2]);
    }

    public function compile(Compiler $compiler): void
    {
        $compiler
            ->raw('((')
            ->compile($this->nodes['expr1'])
            ->raw(') ??


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

if ('cli' !== \PHP_SAPI) {
    throw new Exception('This script must be run from the command line.');
}

$operators = ['not', '!', 'or', '||', 'xor', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', 'c

Collisions of character operators:
    // - an operator that begins with a character must have a space or a parenthesis before or starting at the beginning of a string
    // - an operator that ends with a character must be followed by a whitespace or a pa

ontains', 'starts with', 'ends with', 'matches', '**', '<<', '>>'];
$operators = array_combine($operators, array_map('strlen', $operators));
arsort($operators);

$regex = [];
foreach ($operators as $operator => $length) {
    //


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\GenericEvent;

/**
 * Test class for Event.
 */
class GenericEventTest extends TestCase
{
    private GenericEvent $event;
    private \stdClass $subject;

    protected function setUp(): void
    {
        $this->subject = new \stdClass();
        $this

   * Tests Event->getArgs().
     */
    public function testGetArguments()
    {
        // test getting all
        $this->assertSame(['name' => 'Event'], $this->event->getArguments());
    }

    public function testSetArguments()
    {
        $result

->event = new GenericEvent($this->subject, ['name' => 'Event']);
    }

    public function testConstruct()
    {
        $this->assertEquals($this->event, new GenericEvent($this->subject, ['name' => 'Event']));
    }

    /**


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\Tests\Debug;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Debug\WrappedListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Comp

w WrappedListener($listener, null, new Stopwatch(), new EventDispatcher());

        $this->assertStringMatchesFormat($expected, $wrappedListener->getPretty());
    }

    public static function provideListenersToDescribe()
    {
        return [

onent\Stopwatch\StopwatchEvent;

class WrappedListenerTest extends TestCase
{
    #[DataProvider('provideListenersToDescribe')]
    public function testListenerDescription($listener, $expected)
    {
        $wrappedListener = ne


\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\EventDispatcher\DependencyInjection\AddEventAliasesPass;
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\Tests\Fixtures\CustomEvent;
use Symfony\Component\EventDispatcher\Tests\Fix

UnionTypeListener;

class RegisterListenersPassTest extends TestCase
{
    /**
     * Tests that event subscribers not implementing EventSubscriberInterface
     * trigger an exception.
     */
    public function testEventSubscriberWithoutInterface()

tures\DummyEvent;
use Symfony\Component\EventDispatcher\Tests\Fixtures\TaggedInvokableListener;
use Symfony\Component\EventDispatcher\Tests\Fixtures\TaggedMultiListener;
use Symfony\Component\EventDispatcher\Tests\Fixtures\Tagged


ntDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Contracts\Service\ResetInterface;

/**
 * Collects some data about event listeners.
 *
 * This event dispatcher delegates the dispatching to another one.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Tr

 array $wrappedListeners = [];
    private array $orphanedEvents = [];
    private array $dispatchDepth = [];
    private array $calledListenerInfos = [];
    private array $calledOriginalListeners = [];
    private string $currentRequestHash = '';

    pu

aceableEventDispatcher implements EventDispatcherInterface, ResetInterface
{
    /**
     * @var \SplObjectStorage<WrappedListener, array{string, string}>|null
     */
    private ?\SplObjectStorage $callStack = null;
    private


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * This pass allows bundles to extend the list of event aliases, hot-path events, and no-preload events.
 *
 * @author A

       $hotPathEvents
     * @param list<string>          $noPreloadEvents
     */
    public function __construct(
        private array $eventAliases = [],
        private array $hotPathEvents = [],
        private array $noPreloadEvents = [],
    ) {

lexander M. Turek <me@derrabus.de>
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AddEventAliasesPass implements CompilerPassInterface
{
    /**
     * @param array<string, string> $eventAliases
     * @param list<string>


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

use Symfony\Contracts\Service\ResetInterface;

/**
 * Compiles a node to PHP code.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Compiler implements ResetInterface
{
    private string $source = '';

    public function __construct(
        private array $func

string
    {
        return $this->source;
    }

    /**
     * @return $this
     */
    public function reset(): static
    {
        $this->source = '';

        return $this;
    }

    /**
     * Compiles a node.
     *
     * @return $this
     */

tions,
    ) {
    }

    public function getFunction(string $name): array
    {
        return $this->functions[$name];
    }

    /**
     * Gets the current PHP code after compilation.
     */
    public function getSource():


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

/**
 * Represents a function that can be used in an expression.
 *
 * A function is defined by two PHP callables. The callables are used
 * by the language to compile and/or evaluate the function.
 *
 * The "compiler" function is used at compilation time and must return a
 * PHP representation of the function call (it receive

es as a first argument and the function
 * arguments as remaining arguments).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ExpressionFunction
{
    private \Closure $compiler;
    private \Closure $evaluator;

    /**
     * @param string

s the function
 * arguments as arguments).
 *
 * The "evaluator" function is used for expression evaluation and must return
 * the value of the function call based on the values defined for the
 * expression (it receives the valu


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

/**
 * Lexes an expression.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Lexer
{
    /**
     * Tokenizes an expression.
     *
     * @throws SyntaxError
     */
    public function tokenize(string $expression): TokenStream
    {
        $expression = str_replace(["\r", "\n", "\t", "\v", "\f"], ' ', $express

ion);
        $cursor = 0;
        $tokens = [];
        $brackets = [];
        $end = \strlen($expression);

        while ($cursor < $end) {
            if (' ' == $expression[$cursor]) {
                ++$cursor;


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

use Symfony\Component\ExpressionLanguage\Node\Node;

/**
 * Represents an already serialized parsed expression.
 *
 * The serialized form passed to the constructor MUST come from a trusted source:
 * by contract, callers are expected to

 attacker-controlled bytes here at
 * your peril.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class SerializedParsedExpression extends ParsedExpression
{
    /**
     * @param string $expression An expression
     * @param string $nodes      Th

serialize their own ParsedExpression
 * instances and to keep the resulting bytes under their control. This class
 * does NOT validate the unserialize() allow-list and will instantiate any
 * class referenced by the payload. Pass


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

/**
 * Represents a token.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Token
{
    public const EOF_TYPE = 'end of expression';
    public const NAME_TYPE = 'name';
    public const NUMBER_TYPE = 'number';
    public co

ource
     */
    public function __construct(
        public string $type,
        public string|int|float|null $value,
        public ?int $cursor,
    ) {
    }

    /**
     * Returns a string representation of the token.
     */
    public function __

nst STRING_TYPE = 'string';
    public const OPERATOR_TYPE = 'operator';
    public const PUNCTUATION_TYPE = 'punctuation';

    /**
     * @param self::*_TYPE $type
     * @param int|null     $cursor The cursor position in the s


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

/**
 * Represents a token stream.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class TokenStream
{
    public Token $current;

    private int $position = 0;

    public function __construct(
        private array $tokens,
        private string $expression = '',

 /**
     * Sets the pointer to the next token and returns the old one.
     */
    public function next(): void
    {
        ++$this->position;

        if (!isset($this->tokens[$this->position])) {
            throw new SyntaxError('Unexpected end of ex

   ) {
        $this->current = $tokens[0];
    }

    /**
     * Returns a string representation of the token stream.
     */
    public function __toString(): string
    {
        return implode("\n", $this->tokens);
    }


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class ConditionalNode extends Node
{
    public function __construct(Node $expr1, Node $expr2, Node $expr3)

         ->compile($this->nodes['expr1'])
            ->raw(') ? (')
            ->compile($this->nodes['expr2'])
            ->raw(') : (')
            ->compile($this->nodes['expr3'])
            ->raw('))')
        ;
    }

    public function evaluate(

    {
        parent::__construct(
            ['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3]
        );
    }

    public function compile(Compiler $compiler): void
    {
        $compiler
            ->raw('((')


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * Represents a node in the AST.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Node
{
    public array $nodes = [];
    public array $attributes = [];

    /**
     * @param array $nodes      An arra

  }

    public function __toString(): string
    {
        $attributes = [];
        foreach ($this->attributes as $name => $value) {
            $attributes[] = \sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
        }

y of nodes
     * @param array $attributes An array of attributes
     */
    public function __construct(array $nodes = [], array $attributes = [])
    {
        $this->nodes = $nodes;
        $this->attributes = $attributes;


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class UnaryNode extends Node
{
    private const OPERATORS = [
        '!' => '!',
        'not' => '!',
        '+' =>

    }

    public function compile(Compiler $compiler): void
    {
        $compiler
            ->raw('(')
            ->raw(self::OPERATORS[$this->attributes['operator']])
            ->compile($this->nodes['node'])
            ->raw(')')
        ;

'+',
        '-' => '-',
        '~' => '~',
    ];

    public function __construct(string $operator, Node $node)
    {
        parent::__construct(
            ['node' => $node],
            ['operator' => $operator]
        );


    {
        $dispatcher = new EventDispatcher();
        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());

        $tdispatcher->addListener('foo', $listener = static function () {});
        $listeners = $dispatcher->getListeners('foo');
        $this->assertCount(1, $listeners);
        $this->assertSame($listener, $listeners[0]);

        $tdispatcher->removeListener('foo', $listener);
        $this->assertCount(0, $dispatcher->getListeners('foo'));
    }

    public function

);
        $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo'));
    }

    public function testHasListeners()
    {
        $dispatcher = new EventDispatcher();
        $tdispatcher = new TraceableEventDispatcher($dispatc

 testGetListeners()
    {
        $dispatcher = new EventDispatcher();
        $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch());

        $tdispatcher->addListener('foo', $listener = static function () {}


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\Debug;

use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\VarDumper\Caster\ClassStub;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class WrappedListener
{
    private string|array|objec

vate ClassStub|string $stub;
    private static bool $hasClassStub;

    public function __construct(
        callable|array $listener,
        ?string $name,
        private Stopwatch $stopwatch,
        private ?EventDispatcherInterface $dispatcher = nul

t $listener;
    private ?\Closure $optimizedListener;
    private string $name;
    private bool $called = false;
    private bool $stoppedPropagation = false;
    private string $pretty;
    private string $callableRef;
    pri


buted with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;

// Help opcache.preload discover always-needed symbols
class_exists(ParsedExpression::class);

/**
 * Allows to compile and evaluate expressions written in your own DSL.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ExpressionLanguage
{
    private CacheItemPoolInterface $cache;
    private Lexer $lexer;
    private Parser

e = null, iterable $providers = [])
    {
        $this->cache = $cache ?? new ArrayAdapter();
        $this->registerFunctions();
        foreach ($providers as $provider) {
            $this->registerProvider($provider);
        }
    }

    /**
     * C

 $parser;
    private Compiler $compiler;

    protected array $functions = [];

    /**
     * @param iterable<ExpressionFunctionProviderInterface> $providers
     */
    public function __construct(?CacheItemPoolInterface $cach


rivate array $binaryOperators;
    private array $names;
    private int $flags = 0;

    public function __construct(
        private array $functions,
    ) {
        $this->unaryOperators = [
            'not' => ['precedence' => 50],
            '!' => ['precedence' => 50],
            '-' => ['precedence' => 500],
            '+' => ['precedence' => 500],
            '~' => ['precedence' => 500],
        ];
        $this->binaryOperators = [
            'or' => ['precedence' => 10, 'associativity' => s

associativity' => self::OPERATOR_LEFT],
            '&&' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT],
            '|' => ['precedence' => 16, 'associativity' => self::OPERATOR_LEFT],
            '^' => ['precedence' => 17, 'associativit

elf::OPERATOR_LEFT],
            '||' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT],
            'xor' => ['precedence' => 12, 'associativity' => self::OPERATOR_LEFT],
            'and' => ['precedence' => 15, '


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage;

class SyntaxError extends \LogicException
{
    public function __construct(string $message, int $cursor = 0, string $expression = '', ?string $subject = null, ?array $proposals = null)
    {
        $message = \sprintf('%s around positi

roposals) {
            $minScore = \INF;
            foreach ($proposals as $proposal) {
                $distance = levenshtein($subject, $proposal);
                if ($distance < $minScore) {
                    $guess = $proposal;

on %d', rtrim($message, '.'), $cursor);
        if ($expression) {
            $message = \sprintf('%s for expression `%s`', $message, $expression);
        }
        $message .= '.';

        if (null !== $subject && null !== $p


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class ArrayNode extends Node
{
    protected int $index;

    public function __construct()
    {
        $this->index = -1;
    }

    public fun

unction compile(Compiler $compiler): void
    {
        $compiler->raw('[');
        $this->compileArguments($compiler);
        $compiler->raw(']');
    }

    public function evaluate(array $functions, array $values): array
    {
        $result = [];

ction addElement(Node $value, ?Node $key = null): void
    {
        $key ??= new ConstantNode(++$this->index);

        array_push($this->nodes, $key, $value);
    }

    /**
     * Compiles the node to PHP.
     */
    public f


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class FunctionNode extends Node
{
    public function __construct(string $name, Node $arguments)
    {
        parent::_

>nodes as $node) {
            $arguments[] = $compiler->subcompile($node);
        }

        $function = $compiler->getFunction($this->attributes['name']);

        $compiler->raw($function['compiler'](...$arguments));
    }

    public function evaluate

_construct(
            ['arguments' => $arguments],
            ['name' => $name]
        );
    }

    public function compile(Compiler $compiler): void
    {
        $arguments = [];
        foreach ($this->nodes['arguments']-


* This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class ArgumentsNode extends ArrayNode
{
    public function compile(Compiler $compiler): void
    {

    public function toArray(): array
    {
        $array = [];

        foreach ($this->getKeyValuePairs() as $pair) {
            $array[] = $pair['value'];
            $array[] = ', ';
        }
        array_pop($array);

        return $array;
    }
}

  $this->compileArguments($compiler, false);
    }


ony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Adam Kiss <hello@adamkiss.com>
 *
 * @internal
 */
class NullCoalescedNameNode extends Node
{
    public function __construct(string $name)
    {
        parent::__construct(
            [],
            ['name' => $name]
        );
    }

    publ

        $compiler->raw('$'.$this->attributes['name'].' ?? null');
    }

    public function evaluate(array $functions, array $values): null
    {
        return null;
    }

    public function toArray(): array
    {
        return [$this->attributes['nam

ic function compile(Compiler $compiler): void
    {


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
use Symfony\Contracts\EventDispatcher\Event;

face::class);
        $dispatcher = new ImmutableEventDispatcher($innerDispatcher);

        $event = new Event();
        $resultEvent = new Event();

        $innerDispatcher->expects($this->once())
            ->method('dispatch')
            ->with($ev

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class ImmutableEventDispatcherTest extends TestCase
{
    public function testDispatchDelegates()
    {
        $innerDispatcher = $this->createMock(EventDispatcherInter


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
use Symfony\Component\ExpressionLanguage\Node\UnaryNode;

class UnaryNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData(): array
    {
        retu

ew ConstantNode(true))],
            [-6, new UnaryNode('~', new ConstantNode(5))],
        ];
    }

    public static function getCompileData(): array
    {
        return [
            ['(-1)', new UnaryNode('-', new ConstantNode(1))],
            ['(+3

rn [
            [-1, new UnaryNode('-', new ConstantNode(1))],
            [3, new UnaryNode('+', new ConstantNode(3))],
            [false, new UnaryNode('!', new ConstantNode(true))],
            [false, new UnaryNode('not', n


$baseHref ?: $uri;
        $this->cachedNamespaces = new \ArrayObject();

        $this->add($node);
    }

    /**
     * Returns the current URI.
     */
    public function getUri(): ?string
    {
        return $this->uri;
    }

    /**
     * Returns base href.
     */
    public function getBaseHref(): ?string
    {
        return $this->baseHref;
    }

    /**
     * Removes all the nodes.
     */
    public function clear(): void
    {
        $this->nodes = [];
        $this->document = null;

     *
     * @param \DOMNodeList<\DOMNode>|\DOMNode|\DOMNode[]|string|null $node
     */
    public function add(\DOMNodeList|\DOMNode|array|string|null $node): void
    {
        if ($node instanceof \DOMNodeList) {
            $this->addNodeList($node)

     $this->cachedNamespaces = new \ArrayObject();
    }

    /**
     * Adds a node to the current list of nodes.
     *
     * This method uses the appropriate specialized add*() method based
     * on the type of the argument.


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler;

use Symfony\Component\DomCrawler\Field\FormField;

/**
 * This is an internal class that must not be used directly.
 *
 * @internal
 */
class FormFieldRegistry
{
    private array $fields = [];
    private string $base = '';

    /**
     * Adds a field to the registry.
     */
    public function add(FormField $field): void
    {

shift($segments);
            if ('' === $path) {
                $target = &$target[];
            } else {
                $target = &$target[$path];
            }
        }
        $target = $field;
    }

    /**
     * Removes a field based on the ful

      $segments = $this->getSegments($field->getName());

        $target = &$this->fields;
        while ($segments) {
            if (!\is_array($target)) {
                $target = [];
            }
            $path = array_


he Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler;

/**
 * Image represents an HTML image (an HTML img tag).
 */
class Image extends AbstractUriElement
{
    public function __construct(\DOMElement $node, ?string $currentUri = null)
    {
        parent::__construct($node, $currentUri, 'GET');
    }

    protected func

>node->getAttribute('src');
    }

    protected function setNode(\DOMElement $node): void
    {
        if ('img' !== $node->nodeName) {
            throw new \LogicException(\sprintf('Unable to visualize a "%s" tag.', $node->nodeName));
        }

tion getRawUri(): string
    {
        return $this-


 or radio inputs.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ChoiceFormField extends FormField
{
    private string $type;
    private bool $multiple;
    private array $options;
    private bool $validationDisabled = false;

    /**
     * Returns true if the field should be included in the submitted values.
     *
     * @return bool true if the field should be included in the submitted values, false otherwise
     */
    public function hasValue(): bool
    {
        // don't send a va

d option is disabled.
     */
    public function isDisabled(): bool
    {
        if ('checkbox' === $this->type) {
            return parent::isDisabled();
        }

        if (parent::isDisabled() && 'select' === $this->type) {
            return true

lue for unchecked checkboxes
        if (\in_array($this->type, ['checkbox', 'radio'], true) && null === $this->value) {
            return false;
        }

        return true;
    }

    /**
     * Check if the current selecte


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Field;

/**
 * FormField is the abstract class for all form fields.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class FormField
{
    protected string $name;
    protected string|array|null $value = null;
    protected \DOMDocument $document;
    protected \DOMXPat

e = $node->getAttribute('name');
        $this->xpath = new \DOMXPath($node->ownerDocument);

        $this->initialize();
    }

    /**
     * Returns the label tag associated to the field or null if none.
     */
    public function getLabel(): ?\DOMEle

h $xpath;
    protected bool $disabled = false;

    /**
     * @param \DOMElement $node The node associated with this field
     */
    public function __construct(
        protected \DOMElement $node,
    ) {
        $this->nam


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Field;

/**
 * TextareaFormField represents a textarea form field (an HTML textarea tag).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class TextareaFormField extends FormField
{
    /**
     * Initializes the form field.
     *
     * @throws \LogicException When node type is incorrect
     *

      if ('textarea' !== $this->node->nodeName) {
            throw new \LogicException(\sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName));
        }

        $this->value = '';
        foreach ($thi

/
    protected function initialize(): void
    {


awler->addHtmlContent($this->getDoctype().'
', 'UTF-8');
    }

    public function testAddHtmlContent()
    {
        $crawler = $this->createCrawler();
        $crawler->addHtmlContent($this->getDoctype().'
', 'UTF-8');

        $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->addHtmlContent() adds nodes from an HTML string');
    }

    public function testAddHtmlContentWithBaseTag()
    {
        $crawler = $this->crea

Path('//base')->attr('href'), '->addHtmlContent() adds nodes from an HTML string');
        $this->assertEquals('http://symfony.com/contact', $crawler->filterXPath('//a')->link()->getUri(), '->addHtmlContent() adds nodes from an HTML string');
    }

    #

teCrawler();
        $crawler->addHtmlContent($this->getDoctype().'<base href="http://symfony.com">', 'UTF-8');

        $this->assertEquals('http://symfony.com', $crawler->filterX


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler;

/**
 * Any HTML element that can link to an URI.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class AbstractUriElement
{
    protected \DOMElement $node;
    protected ?string $method;

    /**
     * @param \DOMElement $node       A \DOMElement instance
     * @param string|null $currentUri The URI of the page wh

on __construct(
        \DOMElement $node,
        protected ?string $currentUri = null,
        ?string $method = 'GET',
    ) {
        $this->setNode($node);
        $this->method = $method ? strtoupper($method) : null;

        $elementUriIsRelative =

ere the link is embedded (or the base href)
     * @param string|null $method     The method to use for the link (GET by default)
     *
     * @throws \InvalidArgumentException if the node is not a link
     */
    public functi


 file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler;

/**
 * Link represents an HTML link (an HTML a, area or link tag).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Link extends AbstractUriElement
{
    protected function getRawUri(): string
    {
        return $this->node->getAttribu

OMElement $node): void
    {
        if ('a' !== $node->nodeName && 'area' !== $node->nodeName && 'link' !== $node->nodeName) {
            throw new \LogicException(\sprintf('Unable to navigate from a "%s" tag.', $node->nodeName));
        }

        $thi

te('href');
    }

    protected function setNode(\D


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Field;

/**
 * FileFormField represents a file form field (an HTML file input tag).
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FileFormField extends FormField
{
    /**
     * Sets the PHP error code associated with the field.
     *
     * @param int $error The error code (one of UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM

rorCode(int $error): void
    {
        if (!\in_array($error, [\UPLOAD_ERR_INI_SIZE, \UPLOAD_ERR_FORM_SIZE, \UPLOAD_ERR_PARTIAL, \UPLOAD_ERR_NO_FILE, \UPLOAD_ERR_NO_TMP_DIR, \UPLOAD_ERR_CANT_WRITE, \UPLOAD_ERR_EXTENSION], true)) {
            throw new \I

_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, or UPLOAD_ERR_EXTENSION)
     *
     * @throws \InvalidArgumentException When error code doesn't exist
     */
    public function setEr


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Field;

/**
 * InputFormField represents an input form field (an HTML input tag).
 *
 * For inputs with type of file, checkbox, or radio, there are other more
 * specialized classes (cf. FileFormField and ChoiceFormField).
 *
 * @author Fabien Pot

id
    {
        if ('input' !== $this->node->nodeName && 'button' !== $this->node->nodeName) {
            throw new \LogicException(\sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName));

encier <fabien@symfony.com>
 */
class InputFormField extends FormField
{
    /**
     * Initializes the form field.
     *
     * @throws \LogicException When node type is incorrect
     */
    protected function initialize(): vo


cyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
 * Compiler pass to register tagged services for an event dispatcher.
 */
class RegisterListenersPass implem

ublic function setHotPathEvents(array $hotPathEvents): static
    {
        trigger_deprecation('symfony/event-dispatcher', '8.1', 'The "%s()" method is deprecated, register an "%s" compiler pass with the hot-path events instead.', __METHOD__, AddEventAlia

ents CompilerPassInterface
{
    private array $hotPathEvents = [];
    private array $noPreloadEvents = [];

    /**
     * @return $this
     *
     * @deprecated since Symfony 8.1, use AddEventAliasesPass instead
     */
    p


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler;

/**
 * The UriResolver class takes an URI (relative, absolute, fragment, etc.)
 * and turns it into an absolute URI against another given base URI.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class UriResolver
{
    /**
     * Resolves a URI according to a base URI.
     *

 resolve(string $uri, ?string $baseUri): string
    {
        $uri = trim($uri);

        // absolute URL?
        if (null !== parse_url(\strlen($uri) !== strcspn($uri, '?#') ? $uri : $uri.'#', \PHP_URL_SCHEME)) {
            return $uri;
        }

    * For example if $uri=/foo/bar and $baseUri=https://symfony.com it will
     * return https://symfony.com/foo/bar
     *
     * If the $uri is not absolute you must pass an absolute $baseUri
     */
    public static function


try {
            new Form($nodes->item(1), 'http://example.com');
            $this->fail('__construct() throws a \\LogicException if the input type is not submit, button, or image');
        } catch (\LogicException $e) {
            $this->assertTrue(true, '__construct() throws a \\LogicException if the input type is not submit, button, or image');
        }

        $nodes = $dom->getElementsByTagName('button');

        try {
            new Form($nodes->item(0), 'http://example.com');
            $thi

stor');
        }
    }

    /**
     * __construct() should throw a \LogicException if the form attribute is invalid.
     */
    #[DataProvider('constructorThrowsExceptionIfNoRelatedFormProvider')]
    public function testConstructorThrowsExceptionIfNoRe

s->fail('__construct() throws a \\LogicException if the node has no form ancestor');
        } catch (\LogicException $e) {
            $this->assertTrue(true, '__construct() throws a \\LogicException if the node has no form ance


an HTML form.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Form extends Link implements \ArrayAccess
{
    private \DOMElement $button;
    private FormFieldRegistry $fields;

    /**
     * @param \DOMElement $node       A \DOMElement instance
     * @param string|null $currentUri The URI of the page where the form is embedded
     * @param string|null $method     The method to use for the link (if null, it defaults to the method defined by the form)
     * @param string|null $baseHref   T

  ?string $currentUri = null,
        ?string $method = null,
        private ?string $baseHref = null,
    ) {
        parent::__construct($node, $currentUri, $method);

        $this->initialize();
    }

    /**
     * Gets the form node associated with

he URI of the <base> used for relative links, but not for empty action
     *
     * @throws \LogicException if the node is not a button inside a form tag
     */
    public function __construct(
        \DOMElement $node,


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\DomCrawler\Crawler;

final class CrawlerSelectorTextSame extends Constraint
{
    public function __construct(
        private string $selector,
        pri

aram Crawler $crawler
     */
    protected function matches($crawler): bool
    {
        $crawler = $crawler->filter($this->selector);
        if (!\count($crawler)) {
            return false;
        }

        return $this->expectedText === trim($craw

vate string $expectedText,
    ) {
    }

    public function toString(): string
    {
        return \sprintf('has a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText);
    }

    /**
     * @p


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * Exception class for when a resource cannot be loaded or imported.
 *
 * @author Ryan Weaver <ryan@thatsquality.com>
 */
class LoaderLoadException extends \Exception
{
    /**
     * @param mixed           $resource       The resource that could not be imported
     * @param string|null     $sourceResource The original re

     */
    public function __construct(mixed $resource, ?string $sourceResource = null, int $code = 0, ?\Throwable $previous = null, ?string $type = null)
    {
        if (!\is_string($resource)) {
            try {
                $resource = json_encod

source importing the new resource
     * @param int             $code           The error code
     * @param \Throwable|null $previous       A previous exception
     * @param string|null     $type           The type of resource


use Symfony\Component\Filesystem\Filesystem;

/**
 * XMLUtils is a bunch of utility methods to XML operations.
 *
 * This class contains static methods only and is not meant to be instantiated.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Martin Hasoň <martin.hason@gmail.com>
 * @author Ole Rößner <ole@roessner.it>
 */
class XmlUtils
{
    /**
     * This class should not be instantiated.
     */
    private function __construct()
    {
    }

    /**
     * Parses an XML string.
     *

hen parsing of XML file returns error
     * @throws InvalidXmlException When parsing of XML with schema or callable produces any errors unrelated to the XML parsing itself
     * @throws \RuntimeException   When DOM extension is missing
     */
    public

    * @param string               $content          An XML string
     * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation
     *
     * @throws XmlParsingException W


buted with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * ClassExistenceResource represents a class existence.
 * Freshness is only evaluated against resource existence.
 *
 * The resource must be a fully-qualified class name.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class ClassExistenceResource implements SelfCheckingResourceInterface
{
    private ?array $exists = null;

    private static int $autoloadLevel = 0;
    private static ?string $autoload

/
    public function __construct(
        private string $resource,
        ?bool $exists = null,
    ) {
        if (null !== $exists) {
            $this->exists = [$exists, null];
        }
    }

    public function __toString(): string
    {

edClass = null;
    private static array $existsCache = [];

    /**
     * @param string    $resource The fully-qualified class name
     * @param bool|null $exists   Boolean when the existence check has already been done
     *


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * ComposerResource tracks the PHP version and Composer dependencies.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @final
 */
class ComposerResource implements SelfCheckingResourceInterface
{
    private array $vendors;

    private static arr

    }

    public function __toString(): string
    {
        return __CLASS__;
    }

    public function isFresh(int $timestamp): bool
    {
        self::refresh();

        return array_values(self::$runtimeVendors) === array_values($this->vendors);

ay $runtimeVendors;

    public function __construct()
    {
        self::refresh();
        $this->vendors = self::$runtimeVendors;
    }

    public function getVendors(): array
    {
        return array_keys($this->vendors);


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * DirectoryResource represents a resources stored in a subdirectory tree.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class DirectoryResource implements SelfCheckingResourceInterface
{
    private string $resource;

    /**
     * @param string

        private ?string $pattern = null,
    ) {
        $resolvedResource = realpath($resource) ?: (file_exists($resource) ? $resource : false);

        if (false === $resolvedResource || !is_dir($resolvedResource)) {
            throw new \InvalidArgum

 $resource The file path to the resource
     * @param string|null $pattern  A pattern to restrict monitored files
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(
        string $resource,


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * FileExistenceResource represents a resource stored on the filesystem.
 * Freshness is only evaluated against resource creation or deletion.
 *
 * The resource can be a file or a directory.
 *
 * @author Charles-Henri Bruyand <charles

unction __construct(
        private string $resource,
    ) {
        $this->exists = file_exists($resource);
    }

    public function __toString(): string
    {
        return 'existence.'.$this->resource;
    }

    public function getResource(): stri

henri.bruyand@gmail.com>
 *
 * @final
 */
class FileExistenceResource implements SelfCheckingResourceInterface
{
    private bool $exists;

    /**
     * @param string $resource The file path to the resource
     */
    public f


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * FileResource represents a resource stored on the filesystem.
 *
 * The resource can be a file or a directory.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class FileResource implements SelfCheckingResourceInterface
{
    p

rce = realpath($resource) ?: (file_exists($resource) ? $resource : false);

        if (false === $resolvedResource) {
            throw new \InvalidArgumentException(\sprintf('The file "%s" does not exist.', $resource));
        }

        $this->resource

rivate string $resource;

    /**
     * @param string $resource The file path to the resource
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(string $resource)
    {
        $resolvedResou


buted with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\Glob;

/**
 * GlobResource represents a set of resources stored on the filesystem.
 *
 * Only existence/removal is tracked (not mtimes.)
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @final
 *
 * @implements \IteratorAggregate<string, \SplFileInfo>
 */
class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
{
    private string $prefix

ve Whether directories should be scanned recursively or not
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(
        string $prefix,
        private string $pattern,
        private bool $recursive,
        private b

;
    private string $hash;
    private array $excludedPrefixes;
    private int $globBrace;

    /**
     * @param string $prefix    A directory prefix
     * @param string $pattern   A glob pattern
     * @param bool   $recursi


buted with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormTypeExtensionInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

/**
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @final
 */
class ReflectionClassResource implements SelfCheckingResourceInterface
{
    private array $files = [];
    private string $className;
    private array $excludedVendors = [];
    private str

dedVendors;
    }

    public function isFresh(int $timestamp): bool
    {
        if (!isset($this->hash)) {
            $this->hash = $this->computeHash();
            $this->loadFiles($this->classReflector);
        }

        foreach ($this->files as $

ing $hash;

    public function __construct(
        private \ReflectionClass $classReflector,
        array $excludedVendors = [],
    ) {
        $this->className = $classReflector->name;
        $this->excludedVendors = $exclu


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

/**
 * ResourceInterface is the interface that must be implemented by all Resource classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface ResourceInterface extends \Stringable
{
    /**
     * Returns a string representation of the Resource.
     *
     * This method is necessa

 by means
     * of array_unique(). The string returned need not have a particular meaning, but has
     * to be identical for different ResourceInterface instances referring to the same
     * resource; and it should be unlikely to collide with that of ot

ry to allow for resource de-duplication, for example


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\Config\ResourceCheckerInterface;

/**
 * Resource checker for instances of SelfCheckingResourceInterface.
 *
 * As these resources perform the actual check themselves, we can provide
 * this class as a standard way of

tions. For example, when using the full stack framework, the router
    // and the container have their own cache. But they may check the very same
    // resources
    private static array $cache = [];

    public function supports(ResourceInterface $meta

validating them.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class SelfCheckingResourceChecker implements ResourceCheckerInterface
{
    // Common shared cache, because this checker can be used in different
    // situa


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Resource;

use Symfony\Component\Config\ResourceCheckerInterface;

class SkippingResourceChecker implements ResourceCheckerInterface
{
    private array $skippedResourceTypes;

    /**
     * @param class-string<ResourceInterface>[] $skippedReso

bool
    {
        return !$this->skippedResourceTypes || isset($this->skippedResourceTypes[$metadata::class]);
    }

    public function isFresh(ResourceInterface $resource, int $timestamp): bool
    {
        return true;
    }

    public function __se

urceTypes
     */
    public function __construct(array $skippedResourceTypes = [])
    {
        $this->skippedResourceTypes = array_flip($skippedResourceTypes);
    }

    public function supports(ResourceInterface $metadata):


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\LoaderLoadException;

/**
 * DelegatingLoader delegates loading to other loaders using a loader resolver.
 *
 * This loader acts as an array of LoaderInterface objects - each having
 * a chance to

s->resolver = $resolver;
    }

    public function load(mixed $resource, ?string $type = null): mixed
    {
        if (false === $loader = $this->resolver->resolve($resource, $type)) {
            throw new LoaderLoadException($resource, null, 0, null, $

load a given resource (handled by the resolver)
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DelegatingLoader extends Loader
{
    public function __construct(LoaderResolverInterface $resolver)
    {
        $thi


buted with this source code.
 */

namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\Config\Exception\LoaderLoadException;
use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Config\Resource\GlobResource;

/**
 * FileLoader is the abstract class used by all b

c function __construct(
        protected FileLocatorInterface $locator,
        ?string $env = null,
    ) {
        parent::__construct($env);
    }

    /**
     * Sets the current directory.
     */
    public function setCurrentDir(string $dir): void

uilt-in loaders that are file based.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class FileLoader extends Loader
{
    protected static array $loading = [];

    private ?string $currentDir = null;

    publi


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

use Symfony\Component\Config\Exception\LoaderLoadException;
use Symfony\Component\Config\Exception\LogicException;

/**
 * Loader is the abstract class used by all built-in loaders.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Lo

nterface
    {
        if (null === $this->resolver) {
            throw new LogicException('Cannot get a resolver if none was set.');
        }

        return $this->resolver;
    }

    public function setResolver(LoaderResolverInterface $resolver): voi

ader implements LoaderInterface
{
    protected ?LoaderResolverInterface $resolver = null;

    public function __construct(
        protected ?string $env = null,
    ) {
    }

    public function getResolver(): LoaderResolverI


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * LoaderInterface is the interface implemented by all loader classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface LoaderInterface
{
    /**
     * Loads a resource.
     *
     * @throws \Exception If som

 public function supports(mixed $resource, ?string $type = null): bool;

    /**
     * Gets the loader resolver.
     */
    public function getResolver(): LoaderResolverInterface;

    /**
     * Sets the loader resolver.
     */
    public function setR

ething went wrong
     */
    public function load(mixed $resource, ?string $type = null): mixed;

    /**
     * Returns whether this class supports the given resource.
     *
     * @param mixed $resource A resource
     */


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Loader;

/**
 * LoaderResolver selects a loader for a given resource.
 *
 * A resource can be anything (e.g. a full path to a config file or a Closure).
 * Each loader determines whether it can load a resource and how.
 *
 * @author Fabien Potencier <fabien@symfon

ders An array of loaders
     */
    public function __construct(array $loaders = [])
    {
        foreach ($loaders as $loader) {
            $this->addLoader($loader);
        }
    }

    public function resolve(mixed $resource, ?string $type = null):

y.com>
 */
class LoaderResolver implements LoaderResolverInterface
{
    /**
     * @var LoaderInterface[] An array of LoaderInterface objects
     */
    private array $loaders = [];

    /**
     * @param LoaderInterface[] $loa


ception\InvalidTypeException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;

/**
 * Represents an Array node in the config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ArrayNode extends BaseNode implements PrototypeNodeInterface
{
    protected array $xmlRemappings = [];
    protected array $children = [];
    protected bool $allowFalse = false;
    protected bool $allowNewKeys = true;
    protected bool $addIfNotSet = false;
    protected bool $performDeep

is->normalizeKeys = $normalizeKeys;
    }

    /**
     * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
     * After running this method, all keys are normalized to foo_bar.
     *
     * If you have a mixed key like foo-bar_moo, i

Merging = true;
    protected bool $ignoreExtraKeys = false;
    protected bool $removeExtraKeys = true;
    protected bool $normalizeKeys = true;

    public function setNormalizeKeys(bool $normalizeKeys): void
    {
        $th


buted with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Builder\ExprBuilder;
use Symfony\Component\Config\Loader\ParamConfigurator;

/**
 * @author Alexandre Daubois <alex.daubois@gmail.com>
 */
final class ArrayShapeGenerator
{
    public static function generate(NodeInterface $node): string
    {
        return str_replace("\n", "\n * ", self::doGeneratePhpDoc($node));
    }

    private static function doGeneratePhpDoc(NodeInterface $node,

() ? 'bool|null' : 'bool',
                $node instanceof StringNode => 'string',
                $node instanceof NumericNode => self::handleNumericNode($node),
                $node instanceof EnumNode => $node->getPermissibleValues('|', false),

 int $nestingLevel = 1): string
    {
        if (!$node instanceof ArrayNode) {
            $typeString = match (true) {
                $node instanceof BooleanNode => $node->hasDefaultValue() && null === $node->getDefaultValue


se Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
use Symfony\Component\Config\Exception\LogicException;

/**
 * The base node class.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
abstract class BaseNode implements NodeInterface
{
    public const

ray $normalizedTypes = [];
    protected array $finalValidationClosures = [];
    protected bool $allowOverwrite = true;
    protected bool $required = false;
    protected array $deprecation = [];
    protected array $equivalentValues = [];
    protected

 DEFAULT_PATH_SEPARATOR = '.';

    private static array $placeholderUniquePrefixes = [];
    private static array $placeholders = [];

    protected string $name;
    protected array $normalizationClosures = [];
    protected ar


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a Boolean value in the config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class BooleanNode extends ScalarNode
{
    public fun

rent, $pathSeparator);
    }

    protected function validateType(mixed $value): void
    {
        if (!\is_bool($value)) {
            if (null === $value && $this->nullable) {
                return;
            }

            $ex = new InvalidTypeExcep

ction __construct(
        ?string $name,
        ?NodeInterface $parent = null,
        string $pathSeparator = self::DEFAULT_PATH_SEPARATOR,
        private bool $nullable = false,
    ) {
        parent::__construct($name, $pa


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
use Symfony\Component\Config\Definition\Loader\DefinitionFileLoader;
use Symfony\Component\Config\Fi

        private ConfigurableInterface $subject,
        private ?ContainerBuilder $container,
        private string $alias,
    ) {
    }

    /**
     * @return TreeBuilder<'array'>
     */
    public function getConfigTreeBuilder(): TreeBuilder
    {

leLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * @author Yonel Ceruto <yonelceruto@gmail.com>
 *
 * @final
 */
class Configuration implements ConfigurationInterface
{
    public function __construct(


buted with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
 * Node which only allows a finite set of values.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class EnumNode extends ScalarNode
{
    private array $values;
    private ?string $enumFqcn = null;

    /**
     * @param class-string<\UnitEnum>|null $enumFqcn
     */
    public function __construct(?string $name, ?NodeInterface

tain at least one element.');
        }

        if ($values && $enumFqcn) {
            throw new \InvalidArgumentException('$values or $enumFqcn cannot be both set.');
        }

        if (null !== $enumFqcn) {
            if (!enum_exists($enumFqcn))

$parent = null, array $values = [], string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR, ?string $enumFqcn = null)
    {
        if (!$values && !$enumFqcn) {
            throw new \InvalidArgumentException('$values must con


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a float value in the config tree.
 *
 * @author Jeanmonod David <david.jeanmonod@gmail.com>
 */
class FloatNode extends NumericNode

e)) {
            $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "float", but got "%s".', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);

{
    protected function validateType(mixed $value): void
    {
        // Integers are also accepted, we just cast them
        if (\is_int($value)) {
            $value = (float) $value;
        }

        if (!\is_float($valu


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents an integer value in the config tree.
 *
 * @author Jeanmonod David <david.jeanmonod@gmail.com>
 */
class IntegerNode extends N

tPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    protected function getValidPlaceholde

umericNode
{
    protected function validateType(mixed $value): void
    {
        if (!\is_int($value)) {
            $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "int", but got "%s".', $this->ge


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * Common Interface among all nodes.
 *

 the node.
     */
    public function getName(): string;

    /**
     * Returns the path of the node.
     */
    public function getPath(): string;

    /**
     * Returns true when the node is required.
     */
    public function isRequired(): bool;

 * In most cases, it is better to inherit from BaseNode instead of implementing
 * this interface yourself.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
interface NodeInterface
{
    /**
     * Returns the name of


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
 * This node represents a numeric value in the config tree.
 *
 * @author David Jeanmonod <david.jeanmonod@gmail.com>
 */
class NumericNode extends ScalarNode
{
    public function __construc

{
        parent::__construct($name, $parent, $pathSeparator);
    }

    protected function finalizeValue(mixed $value): mixed
    {
        $value = parent::finalizeValue($value);

        if ($this->isHandlingPlaceholder()) {
            return $value;

t(
        ?string $name,
        ?NodeInterface $parent = null,
        protected int|float|null $min = null,
        protected int|float|null $max = null,
        string $pathSeparator = BaseNode::DEFAULT_PATH_SEPARATOR,
    )


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

/**
 * This class is the entry point for config normalization/merging/finalization.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 *
 * @final
 */
class Processor
{
    /**
     * Processes an array of configurations.
     *
     * @param array $configs An array of

rmalize($config);
            $currentConfig = $configTree->merge($currentConfig, $config);
        }

        return $configTree->finalize($currentConfig);
    }

    /**
     * Processes an array of configurations.
     *
     * @param array $configs An

configuration items to process
     */
    public function process(NodeInterface $configTree, array $configs): array
    {
        $currentConfig = [];
        foreach ($configs as $config) {
            $config = $configTree->no


Exception;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Exception\UnsetKeyException;

/**
 * Represents a prototyped Array node in the config tree.
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class PrototypedArrayNode extends ArrayNode
{
    protected PrototypeNodeInterface $prototype;
    protected ?string $keyAttribute = null;
    protected bool $removeKeyAttribute = false;
    protected int $minNumberOfElements =

 = [];
    private bool $defaultToNull = false;

    /**
     * Sets the minimum number of elements that a prototype based node must
     * contain. By default this is zero, meaning no elements.
     */
    public function setMinNumberOfElements(int $numbe

 0;
    protected array $defaultValue = [];
    protected ?array $defaultChildren = null;

    /**
     * @var NodeInterface[] An array of the prototypes of the simplified value children
     */
    private array $valuePrototypes


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a scalar value in the config tree.
 *
 * The following values are considered scalars:
 *   * booleans
 *   * strings
 *   * null
 *   * integers
 *

         $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "scalar", but got "%s".', $this->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }

* floats
 *
 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 */
class ScalarNode extends VariableNode
{
    protected function validateType(mixed $value): void
    {
        if (!\is_scalar($value) && null !== $value) {


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidTypeException;

/**
 * This node represents a String value in the config tree.
 *
 * @author Raffaele Carelle <raffaele.carelle@gmail.com>
 */
class StringNode extends Sc

->getPath(), get_debug_type($value)));
            if ($hint = $this->getInfo()) {
                $ex->addHint($hint);
            }
            $ex->setPath($this->getPath());

            throw $ex;
        }
    }

    protected function getValidPlaceh

alarNode
{
    protected function validateType(mixed $value): void
    {
        if (!\is_string($value)) {
            $ex = new InvalidTypeException(\sprintf('Invalid type for path "%s". Expected "string", but got "%s".', $this


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Definition;

use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;

/**
 * This node represents a value of variable type in the config tree.
 *
 * This node is intended for values of arbitrary type.
 * Any PHP type is accepted as a value.
 *
 * @author Jeremy Mikola <jmikola@gmail.com>
 */
class VariableNode exte

): void
    {
        $this->defaultValueSet = true;
        $this->defaultValue = $value;
    }

    public function hasDefaultValue(): bool
    {
        return $this->defaultValueSet;
    }

    public function getDefaultValue(): mixed
    {
        $v

nds BaseNode implements PrototypeNodeInterface
{
    protected bool $defaultValueSet = false;
    protected mixed $defaultValue = null;
    protected bool $allowEmptyValue = true;

    public function setDefaultValue(mixed $value


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

/**
 * Basic implementation of ConfigCacheFactoryInterface that
 * creates an instance of the default ConfigCache.
 *
 * This factory and/or cache do not support cache validation
 * by means of ResourceChecker instances (that is, serv

on __construct(
        private bool $debug,
    ) {
    }

    /**
     * @param-immediately-invoked-callable $callback
     */
    public function cache(string $file, callable $callback): ConfigCacheInterface
    {
        $cache = new ConfigCache($file,

ice-based).
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ConfigCacheFactory implements ConfigCacheFactoryInterface
{
    /**
     * @param bool $debug The debug flag to pass to ConfigCache
     */
    public functi


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
 * Interface for ConfigCache.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
interface ConfigCacheInterface
{
    /**
     * Gets the cache file path.
     */
    public func

     * Writes the given content into the cache file. Metadata will be stored
     * independently and can be used to check cache freshness at a later time.
     *
     * @param string                   $content  The content to write into the cache
     * @

tion getPath(): string;

    /**
     * Checks if the cache is still fresh.
     *
     * This check should take the metadata passed to the write() method into consideration.
     */
    public function isFresh(): bool;

    /**


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface FileLocatorInterface
{
    /**
     * Returns a full path for a given file name.
     *
     * @param

 string|string[] The full path to the file or an array of file paths
     *
     * @psalm-return ($first is true ? string : string[])
     *
     * @throws \InvalidArgumentException        If $name is empty
     * @throws FileLocatorFileNotFoundException I

string      $name        The file name to locate
     * @param string|null $currentPath The current path
     * @param bool        $first       Whether to return the first occurrence or an array of filenames
     *
     * @return


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

/**
 * A ConfigCacheFactory implementation that validates the
 * cache with an arbitrary set of ResourceCheckers.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryI

-invoked-callable $callable
     */
    public function cache(string $file, callable $callable): ConfigCacheInterface
    {
        $cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers);
        if (!$cache->isFresh()) {
            $call

nterface
{
    /**
     * @param iterable<int, ResourceCheckerInterface> $resourceCheckers
     */
    public function __construct(
        private iterable $resourceCheckers = [],
    ) {
    }

    /**
     * @param-immediately


is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * Exception class for when a circular reference is detected when importing resources.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FileLoaderImportCircularReferenceException extends LoaderLoadException
{
    public function __co

 $previous = null)
    {
        $message = \sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);

        \Exception::__construct($message, $code, $previous);
    }

nstruct(array $resources, int $code = 0, ?\Throwable


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Image;

class ImageTest extends TestCase
{
    public function testConstructorWithANonImgTag()
    {
        $this->expectException(\LogicException::class);
        $

sAbsolute()
    {
        $dom = new \DOMDocument();
        $dom->loadHTML('');

        $image = new Image($dom->getElementsByTagName('img')->item(0));
        $this->assertSame('https://example

dom = new \DOMDocument();
        $dom->loadHTML('

');

        new Image($dom->getElementsByTagName('div')->item(0), 'http://www.example.com/');
    }

    public function testBaseUriIsOptionalWhenImageUrlI


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\UriResolver;

class UriResolverTest extends TestCase
{
    #[DataProvider('provideResolverTests')]
    public function testResolver(string $uri, string $baseUri, string $expected)
    {
        $this->assertEquals($ex

//localhost/bar/foo', 'http://localhost/foo'],
            ['
            /foo', 'http://localhost/bar/foo/', 'http://localhost/foo'],
            ['/foo
            ', 'http://localhost/bar/foo', 'http://localhost/foo'],

            ['foo', 'http://local

pected, UriResolver::resolve($uri, $baseUri));
    }

    public static function provideResolverTests()
    {
        return [
            ['/foo', 'http://localhost/bar/foo/', 'http://localhost/foo'],
            ['/foo', 'http:


      }

        $node = $this->createNode('input', '', ['type' => 'text']);
        try {
            new ChoiceFormField($node);
            $this->fail('->initialize() throws a \LogicException if the node is an input with a type different from checkbox or radio');
        } catch (\LogicException $e) {
            $this->assertTrue(true, '->initialize() throws a \LogicException if the node is an input with a type different from checkbox or radio');
        }
    }

    public function testGetType()
    {

radio for radio buttons');

        $node = $this->createNode('input', '', ['type' => 'checkbox', 'name' => 'name', 'value' => 'foo']);
        $field = new ChoiceFormField($node);

        $this->assertEquals('checkbox', $field->getType(), '->getType() re

        $node = $this->createNode('input', '', ['type' => 'radio', 'name' => 'name', 'value' => 'foo']);
        $field = new ChoiceFormField($node);

        $this->assertEquals('radio', $field->getType(), '->getType() returns


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Field;

use Symfony\Component\DomCrawler\Field\InputFormField;

class InputFormFieldTest extends FormFieldTestCase
{
    public function testInitialize()
    {
        $node = $this->createNode('input', '', ['type' => 'text', 'name' => 'name', 'value' =>

tarea', '');
        try {
            new InputFormField($node);
            $this->fail('->initialize() throws a \LogicException if the node is not an input');
        } catch (\LogicException $e) {
            $this->assertTrue(true, '->initialize() thr

 'value']);
        $field = new InputFormField($node);

        $this->assertEquals('value', $field->getValue(), '->initialize() sets the value of the field to the value attribute value');

        $node = $this->createNode('tex


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextContains;

class CrawlerAnySelectorTextCo

', true));
        self::assertTrue($constraint->evaluate(new Crawler('

Bar

Foo'), '', true));
        self::assertTrue($constraint->evaluate(new Crawler('

Bar

Foo Bar Baz'), '', true));
        self::assertFalse($constraint->

ntainsTest extends TestCase
{
    public function testConstraint()
    {
        $constraint = new CrawlerAnySelectorTextContains('ul li', 'Foo');

        self::assertTrue($constraint->evaluate(new Crawler('

Foo
'), '


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerAnySelectorTextSame;

final class CrawlerAn

i>'), '', true));
        self::assertTrue($constraint->evaluate(new Crawler('

Bar

Foo'), '', true));
        self::assertFalse($constraint->evaluate(new Crawler('

Bar

Foo Bar Baz'), '', true));
        self::assertFalse($cons

ySelectorTextSameTest extends TestCase
{
    public function testConstraint()
    {
        $constraint = new CrawlerAnySelectorTextSame('ul li', 'Foo');

        self::assertTrue($constraint->evaluate(new Crawler('

Foo</l


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorTextContains;

class CrawlerSelectorTextContains

', true));
        $this->assertFalse($constraint->evaluate(new Crawler('<html><head><title>Bar'), '', true));
        $this->assertFalse($constraint->evaluate(new Crawler('<html><head></head><body>Bar'), '', true));
    }

    public function testDoesNotM

Test extends TestCase
{
    public function testConstraint()
    {
        $constraint = new CrawlerSelectorTextContains('title', 'Foo');
        $this->assertTrue($constraint->evaluate(new Crawler('<html><head><title>Foobar'), '


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorTextSame;

class CrawlerSelec

), '', true));
        $this->assertFalse($constraint->evaluate(new Crawler('<html><head><title>Bar'), '', true));

        $this->expectException(ExpectationFailedException::class);
        $this->expectExceptionMessage('Failed asserting that the Crawler

torTextSameTest extends TestCase
{
    public function testConstraint()
    {
        $constraint = new CrawlerSelectorTextSame('title', 'Foo');
        $this->assertTrue($constraint->evaluate(new Crawler('<html><head><title>Foo'


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\DomCrawler\Crawler;

final class CrawlerSelectorAttributeValueSame extends Constraint
{
    public function __construct(
        private string $selector,

elector, $this->attribute, $this->expectedText);
    }

    /**
     * @param Crawler $crawler
     */
    protected function matches($crawler): bool
    {
        $crawler = $crawler->filter($this->selector);
        if (!\count($crawler)) {
            r

 private string $attribute,
        private string $expectedText,
    ) {
    }

    public function toString(): string
    {
        return \sprintf('has a node matching selector "%s" with attribute "%s" of value "%s"', $this->s


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\DomCrawler\Crawler;

final class CrawlerSelectorExists extends Constraint
{
    public function __construct(
        private string $selector,
    ) {
    }

    public function toString(): string
    {
        return \s

  }

    /**
     * @param Crawler $crawler
     */
    protected function matches($crawler): bool
    {
        return 0 < \count($crawler->filter($this->selector));
    }

    /**
     * @param Crawler $crawler
     */
    protected function failureDescr

printf('matches selector "%s"', $this->selector);


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Config\Resource\SelfCheckingResourceChecker;
use Symfony\Component\Config\Resource\SkippingResourceChecker;

/**
 * ConfigCache caches arbitrary content in files on disk.
 *
 * When in debug mode, those metada

ory.de>
 */
class ConfigCache extends ResourceCheckerConfigCache
{
    /**
     * @param string                                 $file                 The absolute cache path
     * @param bool                                   $debug                Whether

ta resources that implement
 * \Symfony\Component\Config\Resource\SelfCheckingResourceInterface will
 * be used to check cache freshness.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Matthias Pigulla <mp@webfact


<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

/**
 * Interface for a ConfigCache factory. This factory creates
 * an instance of ConfigCacheInterface and initializes the
 * cache if necessary.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
interface ConfigCacheFactoryInterfac

able $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback
     */
    public function cache(string $file, callable $callable): ConfigCacheInterface;
}

e
{
    /**
     * Creates a cache instance and (re-)initializes it if necessary.
     *
     * @param-immediately-invoked-callable $callable
     *
     * @param string   $file     The absolute cache file path
     * @param call


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
 * Interface for ResourceCheckers.
 *
 * When a ResourceCheckerConfigCache instance is checked for freshness, all its associated
 * metadata resources are passed to ResourceCheckers

 ResourceCheckerInterface
{
    /**
     * Queries the ResourceChecker whether it can validate a given
     * resource or not.
     */
    public function supports(ResourceInterface $metadata): bool;

    /**
     * Validates the resource.
     *
     * @p

. The ResourceCheckers
 * can then inspect the resources and decide whether the cache can be considered
 * fresh or not.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 * @author Benjamin Klotz <bk@webfactory.de>
 */
interface


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Config\Exception;

/**
 * File locator exception if a file does not exist.
 *
 * @author Leo Feyer <https://github.com/leofeyer>
 */
class FileLocatorFileNotFoundException extends \InvalidArgumentException
{
    public function __construct(

age = '',
        int $code = 0,
        ?\Throwable $previous = null,
        private array $paths = [],
    ) {
        parent::__construct($message, $code, $previous);
    }

    public function getPaths(): array
    {
        return $this->paths;
    }


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Field;

use PHPUnit\Framework\Attributes\DataProvider;
use Symfony\Component\DomCrawler\Field\FileFormField;

class FileFormFieldTest extends FormFieldTestCase
{
    public function testInitialize()
    {
        $node = $this->createNode('input', '', ['type' => 'file']);
        $field = new FileFormField($node);

        $this-

'textarea', '');
        try {
            new FileFormField($node);
            $this->fail('->initialize() throws a \LogicException if the node is not an input field');
        } catch (\LogicException $e) {
            $this->assertTrue(true, '->initial

>assertEquals(['name' => '', 'type' => '', 'tmp_name' => '', 'error' => \UPLOAD_ERR_NO_FILE, 'size' => 0], $field->getValue(), '->initialize() sets the value of the field to no file uploaded');

        $node = $this->createNode(


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Field;

use Symfony\Component\DomCrawler\Field\TextareaFormField;

class TextareaFormFieldTest extends FormFieldTestCase
{
    public function testInitialize()
    {
        $node = $this->createNode('textarea', 'foo bar');
        $field = new TextareaF

 TextareaFormField($node);
            $this->fail('->initialize() throws a \LogicException if the node is not a textarea');
        } catch (\LogicException $e) {
            $this->assertTrue(true, '->initialize() throws a \LogicException if the node is

ormField($node);

        $this->assertEquals('foo bar', $field->getValue(), '->initialize() sets the value of the field to the textarea node value');

        $node = $this->createNode('input', '');
        try {
            new


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorExists;

class CrawlerSelecto

       $constraint = new CrawlerSelectorExists('h1');
        $this->assertFalse($constraint->evaluate(new Crawler('<html><head><title>'), '', true));

        $this->expectException(ExpectationFailedException::class);
        $this->expectExceptionMessage

rExistsTest extends TestCase
{
    public function testConstraint()
    {
        $constraint = new CrawlerSelectorExists('title');
        $this->assertTrue($constraint->evaluate(new Crawler('<html><head><title>'), '', true));


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\DomCrawler\Crawler;

final class CrawlerAnySelectorTextSame extends Constraint
{
    public function __construct(
        private string $selector,
        private string $exp

atches($other): bool
    {
        if (!$other instanceof Crawler) {
            throw new \InvalidArgumentException(\sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other)));
        }

ectedText,
    ) {
    }

    public function toString(): string
    {
        return \sprintf('has at least a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText);
    }

    protected function m


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Test\Constraint;

use PHPUnit\Framework\Constraint\Constraint;
use Symfony\Component\DomCrawler\Crawler;

final class CrawlerSelectorTextContains extends Constraint
{
    private bool $hasNode = false;
    private string $nodeText;

    public function __const

ng selector "%s" contains "%s"', $this->nodeText, $this->selector, $this->expectedText);
        }

        return \sprintf('the Crawler has a node matching selector "%s"', $this->selector);
    }

    /**
     * @param Crawler $crawler
     */
    protect

ruct(
        private string $selector,
        private string $expectedText,
    ) {
    }

    public function toString(): string
    {
        if ($this->hasNode) {
            return \sprintf('the text "%s" of the node matchi


buted with this source code.
 */

namespace Symfony\Component\Config;

use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;

/**
 * ResourceCheckerConfigCache uses instances of ResourceCheckerInterface
 * to check whether cached data is still fresh.
 *
 * @author Matthias Pigulla <mp@webfactory.de>
 */
class ResourceCheckerConfigCache implements ConfigCacheInterface
{
    private string $metaFile;

    /

   * @param string|null                               $metaFile         The absolute path to the meta file, defaults to $file.meta if null
     */
    public function __construct(
        private string $file,
        private iterable $resourceCheckers = [

**
     * @param string                                    $file             The absolute cache path
     * @param iterable<mixed, ResourceCheckerInterface> $resourceCheckers The ResourceCheckers to use for the freshness check


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Field;

use Symfony\Component\DomCrawler\Field\InputFormField;

class FormFieldTest extends FormFieldTestCase
{
    public function testGetName()
    {
        $node = $this->createNode('input', '', ['type' => 'text', 'name' => 'name', 'value' => 'value']);
        $field = new I

pe' => 'text', 'name' => 'name', 'value' => 'value']);
        $field = new InputFormField($node);

        $this->assertEquals('value', $field->getValue(), '->getValue() returns the value of the field');

        $field->setValue('foo');
        $this->as

nputFormField($node);

        $this->assertEquals('name', $field->getName(), '->getName() returns the name of the field');
    }

    public function testGetSetHasValue()
    {
        $node = $this->createNode('input', '', ['ty


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\DomCrawler\Tests\Test\Constraint;

use PHPUnit\Framework\ExpectationFailedException;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Test\Constraint\CrawlerSelectorAttributeValueSame;

class CrawlerS

traint->evaluate(new Crawler('<html><body><form><input type="text" name="username" value="Fabien">'), '', true));
        $this->assertFalse($constraint->evaluate(new Crawler('<html><body><form><input type="text" name="username">'), '', true));
        $th

electorAttributeValueSameTest extends TestCase
{
    public function testConstraint()
    {
        $constraint = new CrawlerSelectorAttributeValueSame('input[name="username"]', 'value', 'Fabien');
        $this->assertTrue($cons