Repository: symfony/ux
Pull request #2316 (2024-11-01 01:46:24)

[TwigComponent] Optimize TwigPreLexer
| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| Issues        | Fix #...
| License       | MIT

Refactor the following methods:
* `check`
* `consume`
* `consumeComponentName`
* `consumeUntil`
* `consumeWhitespace`

Remove the following methods:
* `addDefaultBlock`
* `consumeAttributeName`
* `doesStringEventuallyExist`




Patch:
diff --git a/.github/ISSUE_TEMPLATE/1-bug_report.md b/.github/ISSUE_TEMPLATE/1-bug_report.md
index 36713b35..03391625 100644
--- a/.github/ISSUE_TEMPLATE/1-bug_report.md
+++ b/.github/ISSUE_TEMPLATE/1-bug_report.md
@@ -2,31 +2,7 @@
 name: '🐞 Bug Report'
 about: Report a bug in existing features
 title: ''
-labels: ['Bug']
+labels: 'bug'
 assignees: ''
 
 ---
-
-<!-- ======================== Guidelines ============================
-
-Thank you for taking the time to report a bug! 🙏
-
-Please follow these guidelines to help us understand & fix the issue:
-
-Describe Your Problem 🎯
-- Clearly explain the problem you're facing;
-- Describe what you expected to happen versus what actually occurred;
-- List the steps to reproduce the bug.
-	
-Provide Detailed Information 📋
-- Share relevant details: Component version, errors, screenshots;
-- If possible, provide a minimal reproducer in a GitHub repository.
-
-Be Kind and Respectful 🙂
-- Stay patient & open to feedback, and act with kindness and respect;
-- Remember that this is a volunteer-driven project.
-
-============================= Guidelines ======================== -->
-
-
-
diff --git a/.github/ISSUE_TEMPLATE/2-feature_request.md b/.github/ISSUE_TEMPLATE/2-feature_request.md
index ca32d4ee..a6e92dc1 100644
--- a/.github/ISSUE_TEMPLATE/2-feature_request.md
+++ b/.github/ISSUE_TEMPLATE/2-feature_request.md
@@ -2,7 +2,7 @@
 name: '🚀 Feature Request'
 about: Suggest ideas for new features or enhancements
 title: ''
-labels: ['RFC']
+labels: 'RFC'
 assignees: ''
 
 ---
diff --git a/.github/generate-dist-files-size-diff.mjs b/.github/generate-dist-files-size-diff.mjs
deleted file mode 100644
index 3f9022d1..00000000
--- a/.github/generate-dist-files-size-diff.mjs
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * Generate a markdown table with the difference in size of the dist files between the base and the PR.
- */
-
-/*
-Usage:
-```shell
-BASE_DIST_FILES='{"src/Autocomplete/assets/dist/controller.js":{"size":15382,"size_gz":3716},"src/Chartjs/assets/dist/controller.js":{"size":2281,"size_gz":771},"src/Cropperjs/assets/dist/controller.js":{"size":1044,"size_gz":475}}' \
-PR_DIST_FILES='{"src/Chartjs/assets/dist/controller.js":{"size":1281,"size_gz":171},"src/Cropperjs/assets/dist/controller.js":{"size":1044,"size_gz":475},"src/Cropperjs/assets/dist/style.min.css":{"size":32,"size_gz":66},"src/Dropzone/assets/dist/controller.js":{"size":3199,"size_gz":816},"src/Map/src/Bridge/Google/assets/dist/foo.js":{"size":3199,"size_gz":816}}' \
-GITHUB_REPOSITORY='symfony/ux' \
-GITHUB_HEAD_REF='my-branch-name' \
-  node .github/generate-dist-files-size-diff.mjs
-```
- */
-
-if (!process.env.BASE_DIST_FILES) {
-    throw new Error('Missing or invalid "BASE_DIST_FILES" env variable.');
-}
-
-if (!process.env.PR_DIST_FILES) {
-    throw new Error('Missing or invalid "PR_DIST_FILES" env variable.');
-}
-
-if (!process.env.GITHUB_REPOSITORY) {
-    throw new Error('Missing or invalid "GITHUB_REPOSITORY" env variable.');
-}
-
-if (!process.env.GITHUB_HEAD_REF) {
-    throw new Error('Missing or invalid "GITHUB_HEAD_REF" env variable.');
-}
-
-/**
- * Adapted from https://gist.github.com/zentala/1e6f72438796d74531803cc3833c039c?permalink_comment_id=4455218#gistcomment-4455218
- * @param {number} bytes
- * @param {number} digits
- * @returns {string}
- */
-function formatBytes(bytes, digits = 2) {
-    if (bytes === 0) {
-        return '0 B';
-    }
-    const sizes = [`B`, 'kB', 'MB'];
-    const i = Math.floor(Math.log(bytes) / Math.log(1024));
-
-    return parseFloat((bytes / Math.pow(1024, i)).toFixed(digits)) + ' ' + sizes[i];
-}
-
-/**
- * @param {number} from
- * @param {number} to
- * @returns {number}
- */
-function computeDiffPercent(from, to) {
-    if (from === to) {
-        return 0;
-    }
-
-    return Math.round((from - to) / from * -100);
-}
-
-/**
- * @param {number} percent
- * @returns {string}
- */
-function formatDiffPercent(percent) {
-    return percent > 0 ? `+${percent}% 📈` : percent < 0 ? `${percent}% 📉` : `${percent}%`;
-}
-
-export function main() {
-    const repoUrl = `https://github.com/${process.env.GITHUB_REPOSITORY}`;
-    /** @type {Record<string, {size: number, size_gz: number}>} */
-    const base = JSON.parse(process.env.BASE_DIST_FILES);
-    /** @type {Record<string, {size: number, size_gz: number}>} */
-    const pr = JSON.parse(process.env.PR_DIST_FILES);
-    let output = '<h1>📊 Packages dist files size difference</h1>\n\n';
-
-    /**
-     * @type {Map<string, {
-     *     meta: {
-     *         packageName: string,
-     *         bridgeName: string,
-     *         url: string,
-     *     },
-     *     files: Set<{
-     *         state: 'added' | 'removed' | 'changed',
-     *         before: {size: number, sizeGz: number},
-     *         after: {size: number, sizeGz: number},
-     *         diffPercent: {size: number, sizeGz: number},
-     *         meta: {fileNameShort: string, fileNameUrl: string}
-     *     }>
-     * }>}
-     */
-    const packagesFiles = [...new Set([...Object.keys(pr), ...Object.keys(base)])]
-        .sort()
-        .reduce((acc, file) => {
-            const beforeSize = base[file]?.size || 0;
-            const afterSize = pr[file]?.size || 0;
-            const beforeSizeGz = base[file]?.size_gz || 0;
-            const afterSizeGz = pr[file]?.size_gz || 0;
-
-            if (beforeSize !== afterSize) {
-                const isBridge = file.includes('src/Bridge'); // we assume that's enough for now
-                const packageName = file.split('/')[1];
-                const bridgeName = isBridge ? file.split('/')[4] : '';
-                const key = isBridge ? `${packageName} (Bridge ${bridgeName})` : packageName;
-                if (!acc.has(key)) {
-                    acc.set(key, {
-                        meta: {
-                            packageName,
-                            bridgeName,
-                            url: isBridge ? `${repoUrl}/tree/${process.env.GITHUB_HEAD_REF}/src/${packageName}/src/Bridge/${bridgeName}/assets/dist` : `${repoUrl}/tree/${process.env.GITHUB_HEAD_REF}/src/${packageName}/assets/dist`,
-                        }, files: new Set(),
-                    });
-                }
-
-                const added = !base[file] && pr[file];
-                const removed = base[file] && !pr[file];
-
-                acc.get(key).files.add({
-                    state: added ? 'added' : (removed ? 'removed' : 'changed'),
-                    before: { size: beforeSize, sizeGz: beforeSizeGz },
-                    after: { size: afterSize, sizeGz: afterSizeGz },
-                    diffPercent: {
-                        size: removed ? -100 : (added ? 100 : computeDiffPercent(beforeSize, afterSize)),
-                        sizeGz: removed ? -100 : (added ? 100 : computeDiffPercent(beforeSizeGz, afterSizeGz)),
-                    },
-                    meta: {
-                        fileNameShort: file.replace(isBridge ? `src/${file.split('/')[1]}/src/Bridge/${file.split('/')[4]}/assets/dist/` : `src/${file.split('/')[1]}/assets/dist/`, ''),
-                        fileNameUrl: `${repoUrl}/blob/${process.env.GITHUB_HEAD_REF}/${file}`,
-                    },
-                });
-            }
-
-            return acc;
-        }, new Map);
-
-    if (packagesFiles.size === 0) {
-        output += 'ℹ️ No difference in dist packagesFiles.\n';
-        return output;
-    }
-
-    output += 'Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.\n';
-    output += 'Please review the changes and make sure they are expected.\n\n';
-    output += `<table>
-    <thead><tr><th>File</th><th>Before (Size / Gzip)</th><th>After (Size / Gzip)</th></tr></thead>
-    <tbody>`;
-    for (const [pkgKey, pkg] of packagesFiles.entries()) {
-        output += `<tr><td colspan="3"><a href="${pkg.meta.url}"><b>${pkgKey}</b></a></td></tr>`;
-        for (const file of pkg.files) {
-            output += `<tr>
-                <td><a href="${file.meta.fileNameUrl}"><code>${file.meta.fileNameShort}</code></a></td>
-            `;
-            output += file.state === 'added' 
-                ? `<td><em>Added</em></td>`
-                : `<td>
-                    <code>${formatBytes(file.before.size)}</code>
-                    / <code>${formatBytes(file.before.sizeGz)}</code> 
-                </td>`; 
-            output += file.state === 'removed'
-                ? `<td><em>Removed</em></td>`
-                : `<td>
-                    <code>${formatBytes(file.after.size)}</code>${file.state === 'changed' ? `<sup>${formatDiffPercent(file.diffPercent.size)}</sup>` : ''}
-                    / <code>${formatBytes(file.after.sizeGz)}</code>${file.state === 'changed' ? `<sup>${formatDiffPercent(file.diffPercent.sizeGz)}</sup>` : ''}
-                </td>`;
-            output += `</tr>`;
-        }
-    }
-    output += `</tbody>
-</table>
-`;
-
-    return output;
-}
-
-if (!process.env.CI) {
-    console.log(main());
-}
diff --git a/.github/workflows/dist-files-size-diff-comment.yaml b/.github/workflows/dist-files-size-diff-comment.yaml
deleted file mode 100644
index 95134499..00000000
--- a/.github/workflows/dist-files-size-diff-comment.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-name: Dist Files Size Diff (Comment)
-
-on:
-  workflow_run:
-    workflows: ["Dist Files Size Diff"]
-    types:
-      - completed
-
-jobs:
-    dist-files-size-diff:
-        runs-on: ubuntu-latest
-        steps:
-          - name: Download artifacts
-            uses: actions/download-artifact@v4
-            with:
-              name: dist-size-diff
-              run-id: ${{ github.event.workflow_run.id }}
-              github-token: ${{ secrets.GITHUB_TOKEN }}
-              
-          - name: Read pr-number artifact to env var
-            id: read-pr-number
-            run: |
-              echo "pr-number=$(cat ./pr-number)" >> $GITHUB_OUTPUT
-              
-          - name: Comment on the pull request (if success)
-            uses: marocchino/sticky-pull-request-comment@v2
-            with:
-              number: ${{ steps.read-pr-number.outputs.pr-number }}
-              path: ./diff.md
diff --git a/.github/workflows/dist-files-size-diff.yaml b/.github/workflows/dist-files-size-diff.yaml
deleted file mode 100644
index ef80d89a..00000000
--- a/.github/workflows/dist-files-size-diff.yaml
+++ /dev/null
@@ -1,74 +0,0 @@
-name: Dist Files Size Diff
-
-on:
-  pull_request:
-    types: [opened, synchronize]
-    paths:
-      - 'src/*/assets/dist/**'
-      - 'src/*/src/Bridge/*/assets/dist/**'
-
-jobs:
-    dist-files-size-diff:
-        runs-on: ubuntu-latest
-        steps:
-          - name: Configure git
-            run: |
-              git config --global user.email ""
-              git config --global user.name "github-action[bot]"
-              
-          - uses: actions/checkout@v4
-            with:
-              ref: ${{ github.base_ref }}
-
-          - name: Get dist files size (from base branch)
-            id: base-dist-files
-            run: |
-              set -e
-              
-              FILES=$(find src -mindepth 2 -type f -path '*/assets/dist/*' -not \( -path '*/tests/*' -o -path '*/public/*' -o -path '*/vendor/*' \) | sort | while read -r file; do
-                  echo "{\"$file\": {\"size\": $(wc -c < "$file"), \"size_gz\": $(gzip -c "$file" | wc -c)}}"
-              done | jq -s 'add' -c)
-              
-              echo "files=$FILES" >> $GITHUB_OUTPUT
-
-          - uses: actions/checkout@v4
-              
-          - name: Get dist files size (from pull request)
-            id: pr-dist-files
-            run: |
-              set -e
-              
-              FILES=$(find src -mindepth 2 -type f -path '*/assets/dist/*' -not \( -path '*/tests/*' -o -path '*/public/*' -o -path '*/vendor/*' \) | sort | while read -r file; do
-                  echo "{\"$file\": {\"size\": $(wc -c < "$file"), \"size_gz\": $(gzip -c "$file" | wc -c)}}"
-              done | jq -s 'add' -c)
-              
-              echo "files=$FILES" >> $GITHUB_OUTPUT
-
-          - name: Generate the diff
-            id: diff
-            uses: actions/github-script@v7
-            env:
-                BASE_DIST_FILES: ${{ steps.base-dist-files.outputs.files }}
-                PR_DIST_FILES: ${{ steps.pr-dist-files.outputs.files }}
-            with:
-              result-encoding: string
-              script: |
-                const fs = require('fs')
-                const { main } = await import('${{ github.workspace }}/.github/generate-dist-files-size-diff.mjs')
-                
-                const diff = await main()
-                console.log(diff);
-                
-                fs.writeFileSync(process.env.GITHUB_WORKSPACE + '/diff.md', diff)
-
-          - name: Save PR number
-            run: |
-              echo "${{ github.event.number }}" > pr-number
-
-          - name: Upload artifacts
-            uses: actions/upload-artifact@v4
-            with:
-              name: dist-size-diff
-              path: |
-                ./diff.md
-                ./pr-number
diff --git a/bin/build_javascript.js b/bin/build_javascript.js
new file mode 100644
index 00000000..7f176223
--- /dev/null
+++ b/bin/build_javascript.js
@@ -0,0 +1,43 @@
+/**
+ * This file is used to compile the TypeScript files in the assets/src directory
+ * of each package.
+ *
+ * It allows each package to spawn its own rollup process, which is necessary
+ * to keep memory usage down.
+ */
+const { spawnSync } = require('child_process');
+const glob = require('glob');
+
+const files = [
+    // custom handling for React
+    'src/React/assets/src/loader.ts',
+    'src/React/assets/src/components.ts',
+    // custom handling for Svelte
+    'src/Svelte/assets/src/loader.ts',
+    'src/Svelte/assets/src/components.ts',
+    // custom handling for Vue
+    'src/Vue/assets/src/loader.ts',
+    'src/Vue/assets/src/components.ts',
+    // custom handling for StimulusBundle
+    'src/StimulusBundle/assets/src/loader.ts',
+    'src/StimulusBundle/assets/src/controllers.ts',
+    // custom handling for Bridge
+    ...glob.sync('src/*/src/Bridge/*/assets/src/*controller.ts'),
+    ...glob.sync('src/*/assets/src/*controller.ts'),
+];
+
+files.forEach((file) => {
+    const result = spawnSync('node', [
+        'node_modules/.bin/rollup',
+        '-c',
+        '--environment',
+        `INPUT_FILE:${file}`,
+    ], {
+        stdio: 'inherit',
+        shell: true
+    });
+
+    if (result.error) {
+        console.error(`Error compiling ${file}:`, result.error);
+    }
+});
diff --git a/bin/build_package.js b/bin/build_package.js
deleted file mode 100644
index ee3054d2..00000000
--- a/bin/build_package.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * This file is used to compile the assets from an UX package.
- */
-
-const { parseArgs } = require('node:util');
-const path = require('node:path');
-const fs = require('node:fs');
-const glob = require('glob');
-const rollup = require('rollup');
-const CleanCSS = require('clean-css');
-const { getRollupConfiguration } = require('./rollup');
-
-const args = parseArgs({
-    allowPositionals: true,
-    options: {
-        watch: {
-            type: 'boolean',
-            description: 'Watch the source files for changes and rebuild when necessary.',
-        },
-    },
-});
-
-async function main() {
-    const packageRoot = path.resolve(process.cwd(), args.positionals[0]);
-
-    if (!fs.existsSync(packageRoot)) {
-        console.error(`The package directory "${packageRoot}" does not exist.`);
-        process.exit(1);
-    }
-
-    if (!fs.existsSync(path.join(packageRoot, 'package.json'))) {
-        console.error(`The package directory "${packageRoot}" does not contain a package.json file.`);
-        process.exit(1);
-    }
-
-    const packageData = require(path.join(packageRoot, 'package.json'));
-    const packageName = packageData.name;
-    const srcDir = path.join(packageRoot, 'src');
-    const distDir = path.join(packageRoot, 'dist');
-
-    if (!fs.existsSync(srcDir)) {
-        console.error(`The package directory "${packageRoot}" does not contain a "src" directory.`);
-        process.exit(1);
-    }
-
-    if (fs.existsSync(distDir)) {
-        console.log(`Cleaning up the "${distDir}" directory...`);
-        await fs.promises.rm(distDir, { recursive: true });
-        await fs.promises.mkdir(distDir);
-    }
-
-    const inputScriptFiles = [
-        ...glob.sync(path.join(srcDir, '*controller.ts')),
-        ...(['@symfony/ux-react', '@symfony/ux-vue', '@symfony/ux-svelte'].includes(packageName)
-            ? [path.join(srcDir, 'loader.ts'), path.join(srcDir, 'components.ts')]
-            : []),
-        ...(packageName === '@symfony/stimulus-bundle'
-            ? [path.join(srcDir, 'loader.ts'), path.join(srcDir, 'controllers.ts')]
-            : []),
-    ];
-
-    const inputStyleFile = packageData.config?.css_source;
-    const buildCss = async () => {
-        const inputStyleFileDist = inputStyleFile
-            ? path.resolve(distDir, `${path.basename(inputStyleFile, '.css')}.min.css`)
-            : undefined;
-        if (!inputStyleFile) {
-            return;
-        }
-
-        console.log('Minifying CSS...');
-        const css = await fs.promises.readFile(inputStyleFile, 'utf-8');
-        const minified = new CleanCSS().minify(css).styles;
-        await fs.promises.writeFile(inputStyleFileDist, minified);
-    };
-
-    if (inputScriptFiles.length === 0) {
-        console.error(
-            `No input files found for package "${packageName}" (directory "${packageRoot}").\nEnsure you have at least a file matching the pattern "src/*_controller.ts", or manually specify input files in "${__filename}" file.`
-        );
-        process.exit(1);
-    }
-
-    const rollupConfig = getRollupConfiguration({ packageRoot, inputFiles: inputScriptFiles });
-
-    if (args.values.watch) {
-        console.log(
-            `Watching for JavaScript${inputStyleFile ? ' and CSS' : ''} files modifications in "${srcDir}" directory...`
-        );
-
-        if (inputStyleFile) {
-            rollupConfig.plugins = (rollupConfig.plugins || []).concat({
-                name: 'watcher',
-                buildStart() {
-                    this.addWatchFile(inputStyleFile);
-                },
-            });
-        }
-
-        const watcher = rollup.watch(rollupConfig);
-        watcher.on('event', ({ result }) => {
-            if (result) {
-                result.close();
-            }
-        });
-        watcher.on('change', async (id, { event }) => {
-            if (event === 'update') {
-                console.log('Files were modified, rebuilding...');
-            }
-
-            if (inputStyleFile && id === inputStyleFile) {
-                await buildCss();
-            }
-        });
-    } else {
-        console.log(`Building JavaScript files from ${packageName} package...`);
-        const start = Date.now();
-
-        const bundle = await rollup.rollup(rollupConfig);
-        await bundle.write(rollupConfig.output);
-
-        await buildCss();
-
-        console.log(`Done in ${((Date.now() - start) / 1000).toFixed(3)} seconds.`);
-    }
-}
-
-main();
diff --git a/bin/build_styles.js b/bin/build_styles.js
new file mode 100644
index 00000000..ad45bb34
--- /dev/null
+++ b/bin/build_styles.js
@@ -0,0 +1,46 @@
+/**
+ * Script to "build" the source CSS files to their final destination.
+ */
+
+const glob = require('glob');
+const { exec } = require('child_process');
+const path = require('path');
+const fs = require('fs');
+
+let pattern = 'src/*/assets/package.json';
+
+// Use glob to find all matching package.json files
+glob(pattern, function (err, files) {
+    if (err) {
+        console.error('Error while finding package.json files:', err);
+        process.exit(1);
+    }
+
+    // Loop over all files
+    files.forEach(file => {
+        // Read the package.json file
+        const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
+
+        // Get the css source
+        const cssSourceRelative = pkg.config && pkg.config.css_source;
+
+        if (!cssSourceRelative) {
+            return;
+        }
+        // Construct the output path
+        const cssSource = path.join(path.dirname(file), cssSourceRelative);
+        const outputDir = path.join(path.dirname(file), 'dist');
+        const outputFilename = path.basename(cssSource, '.css') + '.min.css';
+        const output = path.join(outputDir, outputFilename);
+
+        // Run the clean-css-cli command
+        exec(`yarn run cleancss -o ${output} ${cssSource}`, function (err) {
+            if (err) {
+                console.error(`Error while minifying ${cssSource}:`, err);
+                return;
+            }
+
+            console.log(`Minified ${cssSource} to ${output}`);
+        });
+    });
+});
diff --git a/bin/rollup.js b/bin/rollup.js
deleted file mode 100644
index a75c3036..00000000
--- a/bin/rollup.js
+++ /dev/null
@@ -1,134 +0,0 @@
-const fs = require('node:fs');
-const path = require('node:path');
-const resolve = require('@rollup/plugin-node-resolve');
-const commonjs = require('@rollup/plugin-commonjs');
-const typescript = require('@rollup/plugin-typescript');
-const glob = require('glob');
-
-/**
- * Guarantees that any files imported from a peer dependency are treated as an external.
- *
- * For example, if we import `chart.js/auto`, that would not normally
- * match the "chart.js" we pass to the "externals" config. This plugin
- * catches that case and adds it as an external.
- *
- * Inspired by https://github.com/oat-sa/rollup-plugin-wildcard-external
- */
-const wildcardExternalsPlugin = (peerDependencies) => ({
-    name: 'wildcard-externals',
-    resolveId(source, importer) {
-        if (importer) {
-            let matchesExternal = false;
-            peerDependencies.forEach((peerDependency) => {
-                if (source.includes(`/${peerDependency}/`)) {
-                    matchesExternal = true;
-                }
-            });
-
-            if (matchesExternal) {
-                return {
-                    id: source,
-                    external: true,
-                    moduleSideEffects: true,
-                };
-            }
-        }
-
-        return null; // other ids should be handled as usually
-    },
-});
-
-/**
- * Moves the generated TypeScript declaration files to the correct location.
- *
- * This could probably be configured in the TypeScript plugin.
- */
-const moveTypescriptDeclarationsPlugin = (packageRoot) => ({
-    name: 'move-ts-declarations',
-    writeBundle: async () => {
-        const isBridge = packageRoot.includes('src/Bridge');
-        const globPattern = path.join('dist', '**', 'assets', 'src', '**/*.d.ts');
-        const files = glob.sync(globPattern);
-
-        files.forEach((file) => {
-            const relativePath = file;
-            // a bit odd, but remove first 7 or 4 directories, which will leave only the relative path to the file
-            // ex: dist/Chartjs/assets/src/controller.d.ts' => 'dist/controller.d.ts'
-            const targetFile = relativePath.replace(
-                `${relativePath
-                    .split('/')
-                    .slice(1, isBridge ? 7 : 4)
-                    .join('/')}/`,
-                ''
-            );
-            if (!fs.existsSync(path.dirname(targetFile))) {
-                fs.mkdirSync(path.dirname(targetFile), { recursive: true });
-            }
-            fs.renameSync(file, targetFile);
-        });
-    },
-});
-
-/**
- * @param {String} packageRoot
- * @param {Array<String>} inputFiles
- */
-function getRollupConfiguration({ packageRoot, inputFiles }) {
-    const packagePath = path.join(packageRoot, 'package.json');
-    const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
-    const peerDependencies = [
-        '@hotwired/stimulus',
-        ...(packageData.peerDependencies ? Object.keys(packageData.peerDependencies) : []),
-    ];
-
-    inputFiles.forEach((file) => {
-        // custom handling for StimulusBundle
-        if (file.includes('StimulusBundle/assets/src/loader.ts')) {
-            peerDependencies.push('./controllers.js');
-        }
-
-        // React, Vue
-        if (file.includes('assets/src/loader.ts')) {
-            peerDependencies.push('./components.js');
-        }
-    });
-
-    const outDir = path.join(packageRoot, 'dist');
-
-    return {
-        input: inputFiles,
-        output: {
-            dir: outDir,
-            entryFileNames: '[name].js',
-            format: 'esm',
-        },
-        external: peerDependencies,
-        plugins: [
-            resolve(),
-            typescript({
-                filterRoot: '.',
-                tsconfig: path.join(__dirname, '..', 'tsconfig.json'),
-                include: [
-                    'src/**/*.ts',
-                    // TODO: Remove for the next major release
-                    // "@rollup/plugin-typescript" v11.0.0 fixed an issue (https://github.com/rollup/plugins/pull/1310) that
-                    // cause a breaking change for UX React users, the dist file requires "react-dom/client" instead of "react-dom"
-                    // and it will break for users using the Symfony AssetMapper without Symfony Flex (for automatic "importmap.php" upgrade).
-                    '**/node_modules/react-dom/client.js',
-                ],
-                compilerOptions: {
-                    outDir: outDir,
-                    declaration: true,
-                    emitDeclarationOnly: true,
-                },
-            }),
-            commonjs(),
-            wildcardExternalsPlugin(peerDependencies),
-            moveTypescriptDeclarationsPlugin(packageRoot),
-        ],
-    };
-}
-
-module.exports = {
-    getRollupConfiguration,
-};
diff --git a/biome.json b/biome.json
index 36d42169..a4f7f0f3 100644
--- a/biome.json
+++ b/biome.json
@@ -4,8 +4,6 @@
         "include": [
             "*.json",
             "*.md",
-            "bin/*.js",
-            "test/*.js",
             "src/*/*.json",
             "src/*/*/md",
             "src/*/assets/src/**",
@@ -15,7 +13,7 @@
             "src/*/src/Bridge/*/assets/src/**",
             "src/*/src/Bridge/*/assets/test/**"
         ],
-        "ignore": ["**/composer.json", "**/vendor", "**/package.json", "**/node_modules", "**/var"]
+        "ignore": ["**/composer.json", "**/vendor", "**/package.json", "**/node_modules"]
     },
     "linter": {
         "rules": {
diff --git a/package.json b/package.json
index 0952bdd9..3811ae9c 100644
--- a/package.json
+++ b/package.json
@@ -6,8 +6,8 @@
         "src/*/src/Bridge/*/assets"
     ],
     "scripts": {
-        "build": "yarn workspaces foreach -Apt run build",
-        "test": "yarn workspaces foreach -Apt run test",
+        "build": "node bin/build_javascript.js && node bin/build_styles.js",
+        "test": "bin/run-vitest-all.sh",
         "lint": "biome lint --write",
         "format": "biome format --write",
         "check-lint": "biome lint",
@@ -24,7 +24,7 @@
         "@rollup/plugin-typescript": "^11.1.6",
         "@symfony/stimulus-testing": "^2.0.1",
         "@vitest/browser": "^2.1.1",
-        "clean-css": "^5.3.3",
+        "clean-css-cli": "^5.6.2",
         "playwright": "^1.47.0",
         "rollup": "^4.22.5",
         "tslib": "^2.6.3",
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 00000000..7ab3b404
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,115 @@
+const resolve = require('@rollup/plugin-node-resolve');
+const commonjs = require('@rollup/plugin-commonjs');
+const typescript = require('@rollup/plugin-typescript');
+const fs = require('fs');
+const glob = require('glob');
+const path = require('path');
+
+/**
+ * Guarantees that any files imported from a peer dependency are treated as an external.
+ *
+ * For example, if we import `chart.js/auto`, that would not normally
+ * match the "chart.js" we pass to the "externals" config. This plugin
+ * catches that case and adds it as an external.
+ *
+ * Inspired by https://github.com/oat-sa/rollup-plugin-wildcard-external
+ */
+const wildcardExternalsPlugin = (peerDependencies) => ({
+    name: 'wildcard-externals',
+    resolveId(source, importer) {
+        if (importer) {
+            let matchesExternal = false;
+            peerDependencies.forEach((peerDependency) => {
+                if (source.includes(`/${peerDependency}/`)) {
+                    matchesExternal = true;
+                }
+            });
+
+            if (matchesExternal) {
+                return {
+                    id: source,
+                    external: true,
+                    moduleSideEffects: true
+                };
+            }
+        }
+
+        return null; // other ids should be handled as usually
+    }
+});
+
+/**
+ * Moves the generated TypeScript declaration files to the correct location.
+ *
+ * This could probably be configured in the TypeScript plugin.
+ */
+const moveTypescriptDeclarationsPlugin = (packagePath) => ({
+    name: 'move-ts-declarations',
+    writeBundle: async () => {
+        const isBridge = packagePath.includes('src/Bridge');
+        const globPattern = isBridge
+            ? path.join(packagePath, 'dist', packagePath.replace(/^src\//, ''), '**/*.d.ts')
+            : path.join(packagePath, 'dist', '*', 'assets', 'src', '**/*.d.ts')
+        const files = glob.sync(globPattern);
+        files.forEach((file) => {
+            // a bit odd, but remove first 7 or 13 directories, which will leave
+            // only the relative path to the file
+            const relativePath = file.split('/').slice(isBridge ? 13 : 7).join('/');
+
+            const targetFile = path.join(packagePath, 'dist', relativePath);
+            if (!fs.existsSync(path.dirname(targetFile))) {
+                fs.mkdirSync(path.dirname(targetFile), { recursive: true });
+            }
+            fs.renameSync(file, targetFile);
+        });
+    }
+});
+
+const file = process.env.INPUT_FILE;
+const packageRoot = path.join(file, '..', '..');
+const packagePath = path.join(packageRoot, 'package.json');
+const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
+const peerDependencies = [
+    '@hotwired/stimulus',
+    ...(packageData.peerDependencies ? Object.keys(packageData.peerDependencies) : [])
+];
+
+// custom handling for StimulusBundle
+if (file.includes('StimulusBundle/assets/src/loader.ts')) {
+    peerDependencies.push('./controllers.js');
+}
+// React, Vue
+if (file.includes('assets/src/loader.ts')) {
+    peerDependencies.push('./components.js');
+}
+
+module.exports = {
+    input: file,
+    output: {
+        file: path.join(packageRoot, 'dist', path.basename(file, '.ts') + '.js'),
+        format: 'esm',
+    },
+    external: peerDependencies,
+    plugins: [
+        resolve(),
+        typescript({
+            filterRoot: packageRoot,
+            include: [
+                'src/**/*.ts', 
+                // TODO: Remove for the next major release
+                // "@rollup/plugin-typescript" v11.0.0 fixed an issue (https://github.com/rollup/plugins/pull/1310) that 
+                // cause a breaking change for UX React users, the dist file requires "react-dom/client" instead of "react-dom"
+                // and it will break for users using the Symfony AssetMapper without Symfony Flex (for automatic "importmap.php" upgrade).
+                '**/node_modules/react-dom/client.js'
+            ],
+            compilerOptions: {
+                outDir: '.',
+                declaration: true,
+                emitDeclarationOnly: true,
+            }
+        }),
+        commonjs(),
+        wildcardExternalsPlugin(peerDependencies),
+        moveTypescriptDeclarationsPlugin(packageRoot),
+    ],
+};
diff --git a/src/Autocomplete/assets/package.json b/src/Autocomplete/assets/package.json
index a7a238c5..8af1c434 100644
--- a/src/Autocomplete/assets/package.json
+++ b/src/Autocomplete/assets/package.json
@@ -5,15 +5,6 @@
     "types": "dist/controller.d.ts",
     "version": "1.0.0",
     "license": "MIT",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "autocomplete": {
diff --git a/src/Chartjs/assets/package.json b/src/Chartjs/assets/package.json
index bfbab3f8..ed730622 100644
--- a/src/Chartjs/assets/package.json
+++ b/src/Chartjs/assets/package.json
@@ -6,15 +6,6 @@
     "type": "module",
     "main": "dist/controller.js",
     "types": "dist/controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "chart": {
diff --git a/src/Cropperjs/assets/package.json b/src/Cropperjs/assets/package.json
index ee4b4e29..2133ce56 100644
--- a/src/Cropperjs/assets/package.json
+++ b/src/Cropperjs/assets/package.json
@@ -8,15 +8,6 @@
     "config": {
         "css_source": "src/style.css"
     },
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "cropper": {
diff --git a/src/Dropzone/assets/package.json b/src/Dropzone/assets/package.json
index 03c23dca..1fc19df7 100644
--- a/src/Dropzone/assets/package.json
+++ b/src/Dropzone/assets/package.json
@@ -8,15 +8,6 @@
     "config": {
         "css_source": "src/style.css"
     },
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "dropzone": {
diff --git a/src/LazyImage/assets/package.json b/src/LazyImage/assets/package.json
index 7f2c8d85..cc320117 100644
--- a/src/LazyImage/assets/package.json
+++ b/src/LazyImage/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.1.0",
     "main": "dist/controller.js",
     "types": "dist/controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "lazy-image": {
diff --git a/src/LiveComponent/assets/dist/Component/plugins/QueryStringPluging.d.ts b/src/LiveComponent/assets/dist/Component/plugins/QueryStringPluging.d.ts
new file mode 100644
index 00000000..6f9feeed
--- /dev/null
+++ b/src/LiveComponent/assets/dist/Component/plugins/QueryStringPluging.d.ts
@@ -0,0 +1,9 @@
+import Component from '../index';
+import { PluginInterface } from './PluginInterface';
+export default class implements PluginInterface {
+    private element;
+    private mapping;
+    attachToComponent(component: Component): void;
+    private registerBindings;
+    private updateUrl;
+}
diff --git a/src/LiveComponent/assets/package.json b/src/LiveComponent/assets/package.json
index 8e5ece78..a0d5dba4 100644
--- a/src/LiveComponent/assets/package.json
+++ b/src/LiveComponent/assets/package.json
@@ -8,15 +8,6 @@
         "css_source": "styles/live.css"
     },
     "license": "MIT",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "live": {
diff --git a/src/Map/assets/package.json b/src/Map/assets/package.json
index 69ebc71b..4cd6dd52 100644
--- a/src/Map/assets/package.json
+++ b/src/Map/assets/package.json
@@ -6,15 +6,6 @@
     "type": "module",
     "main": "dist/abstract_map_controller.js",
     "types": "dist/abstract_map_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "importmap": {
             "@hotwired/stimulus": "^3.0.0"
diff --git a/src/Map/doc/index.rst b/src/Map/doc/index.rst
index 799578b4..d950ebfe 100644
--- a/src/Map/doc/index.rst
+++ b/src/Map/doc/index.rst
@@ -37,18 +37,9 @@ Configuration is done in your ``config/packages/ux_map.yaml`` file:
 
 The ``UX_MAP_DSN`` environment variable configure which renderer to use.
 
-Map renderers
-~~~~~~~~~~~~~
-
-The Symfony UX Map bundle supports multiple renderers. A map renderer is a
-service that provides the code and graphic assets required to render and 
-interact with a map in the browser. 
-
 Available renderers
 ~~~~~~~~~~~~~~~~~~~
 
-UX Map ships with two renderers: `Google Maps`_ and `Leaflet`_.
-
 ==============  ===============================================================
 Renderer
 ==============  ===============================================================
@@ -58,173 +49,104 @@ Renderer
                 **DSN**: ``UX_MAP_DSN=leaflet://default`` \
 ==============  ===============================================================
 
-.. tip::
-
-    Read the `Symfony UX Map Leaflet bridge docs`_ and the
-    `Symfony UX Map Google Maps brige docs`_ to learn about the configuration
-    options available for each renderer.
+Usage
+-----
 
-Create a map
-------------
+Creating and rendering
+~~~~~~~~~~~~~~~~~~~~~~
 
-A map is created by calling ``new Map()``. You can configure the center, zoom, and add markers.
-Start by creating a new map instance::
+A map is created by calling ``new Map()``. You can configure the center, zoom, and add markers::
     
+    namespace App\Controller;
+    
+    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+    use Symfony\Component\HttpFoundation\Response;
+    use Symfony\Component\Routing\Attribute\Route;
+    use Symfony\UX\Map\InfoWindow;
     use Symfony\UX\Map\Map;
-
-    // Create a new map instance
-    $myMap = (new Map());
-
-Center and zoom
-~~~~~~~~~~~~~~~
-
-You can set the center and zoom of the map using the ``center()`` and ``zoom()`` methods:
-
-    use Symfony\UX\Map\Map;
+    use Symfony\UX\Map\Marker;
     use Symfony\UX\Map\Point;
     
-    $myMap
+    final class HomeController extends AbstractController
+    {
+        #[Route('/')]
+        public function __invoke(): Response
+        {
+            // 1. Create a new map instance
+            $myMap = (new Map())
+                // Explicitly set the center and zoom
+                ->center(new Point(46.903354, 1.888334))
+                ->zoom(6)
+                // Or automatically fit the bounds to the markers
+                ->fitBoundsToMarkers()
+            ;
     
-        // Explicitly set the center and zoom
-        ->center(new Point(46.903354, 1.888334))
-        ->zoom(6)
-        
-        // Or automatically fit the bounds to the markers
-        ->fitBoundsToMarkers()
-    ;
-
-Add markers
-~~~~~~~~~~~
-
-You can add markers to a map using the ``addMarker()`` method:
-
-    $myMap
-        ->addMarker(new Marker(
-            position: new Point(48.8566, 2.3522), 
-            title: 'Paris'
-        ))
-
-        // With an info window associated to the marker:
-        ->addMarker(new Marker(
-            position: new Point(45.7640, 4.8357), 
-            title: 'Lyon',
-            infoWindow: new InfoWindow(
-                headerContent: '<b>Lyon</b>',
-                content: 'The French town in the historic Rhône-Alpes region, located at the junction of the Rhône and Saône rivers.'
-            )
-        ))
-
-        // You can also pass arbitrary data via the `extra` option in both the marker
-        // and the infoWindow; you can later use this data in your custom Stimulus controllers
-        ->addMarker(new Marker(
-            // ...
-            extra: [
-                'icon_mask_url' => 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/tree_pinlet.svg',
-            ],
-            infoWindow: new InfoWindow(
-                // ...
-                extra: [
-                    'num_items' => 3,
-                    'includes_link' => true,
+            // 2. You can add markers
+            $myMap
+                ->addMarker(new Marker(
+                    position: new Point(48.8566, 2.3522), 
+                    title: 'Paris'
+                ))
+
+                // With an info window associated to the marker:
+                ->addMarker(new Marker(
+                    position: new Point(45.7640, 4.8357), 
+                    title: 'Lyon',
+                    infoWindow: new InfoWindow(
+                        headerContent: '<b>Lyon</b>',
+                        content: 'The French town in the historic Rhône-Alpes region, located at the junction of the Rhône and Saône rivers.'
+                    )
+                ))
+
+                // You can also pass arbitrary data via the `extra` option in both the marker
+                // and the infoWindow; you can later use this data in your custom Stimulus controllers
+                ->addMarker(new Marker(
+                    // ...
+                    extra: [
+                        'icon_mask_url' => 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/tree_pinlet.svg',
+                    ],
+                    infoWindow: new InfoWindow(
+                        // ...
+                        extra: [
+                            'num_items' => 3,
+                            'includes_link' => true,
+                        ],
+                    ),
+                )
+            ;
+
+            // 3. You can also add Polygons, which represents an area enclosed by a series of `Point` instances
+            $myMap->addPolygon(new Polygon(
+                points: [
+                    new Point(48.8566, 2.3522),
+                    new Point(45.7640, 4.8357),
+                    new Point(43.2965, 5.3698),
+                    new Point(44.8378, -0.5792),
                 ],
-            ),
-        )
-    ;
-
-Add Polygons
-~~~~~~~~~~~~
-
-You can also add Polygons, which represents an area enclosed by a series of ``Point`` instances:
-
-    $myMap->addPolygon(new Polygon(
-        points: [
-            new Point(48.8566, 2.3522),
-            new Point(45.7640, 4.8357),
-            new Point(43.2965, 5.3698),
-            new Point(44.8378, -0.5792),
-        ],
-        infoWindow: new InfoWindow(
-            content: 'Paris, Lyon, Marseille, Bordeaux',
-        ),
-    ));
-
-Render a map
-------------
+                infoWindow: new InfoWindow(
+                    content: 'Paris, Lyon, Marseille, Bordeaux',
+                ),
+            ));
+
+            // 4. And inject the map in your template to render it
+            return $this->render('contact/index.html.twig', [
+                'my_map' => $myMap,
+            ]);
+        }
+    }
 
 To render a map in your Twig template, use the ``ux_map`` Twig function, e.g.:
 
-To be visible, the map must have a defined height:
-
 .. code-block:: twig
 
+    {# to be visible, the map must have a defined height #}
     {{ ux_map(my_map, { style: 'height: 300px' }) }}
 
-You can add custom HTML attributes too:
-
-.. code-block:: twig
-
+    {# you can add custom HTML attributes too #}
     {{ ux_map(my_map, { style: 'height: 300px', id: 'events-map', class: 'mb-3' }) }}
 
-
-Twig Function ``ux_map()``
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``ux_map()`` Twig function allows you to create and render a map in your Twig 
-templates. The function accepts the same arguments as the ``Map`` class:
-
-.. code-block:: html+twig
-
-    {{ ux_map(
-        center: [51.5074, 0.1278],
-        zoom: 3,
-        markers: [
-            { position: [51.5074, 0.1278], title: 'London' },
-            { position: [48.8566, 2.3522], title: 'Paris' },
-            {
-                position: [40.7128, -74.0060],
-                title: 'New York',
-                infoWindow: { content: 'Welcome to <b>New York</b>' }
-            },
-        ],
-        attributes: {
-            class: 'foo',
-            style: 'height: 800px; width: 100%; border: 4px solid red; margin-block: 10vh;',
-        }
-    ) }}
-
-Twig Component ``<twig:ux:map />``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Alternatively, you can use the ``<twig:ux:map />`` component.
-
-.. code-block:: html+twig
-
-    <twig:ux:map
-        center="[51.5074, 0.1278]"
-        zoom="3"
-        markers='[
-            {"position": [51.5074, 0.1278], "title": "London"},
-            {"position": [48.8566, 2.3522], "title": "Paris"},
-            {
-                "position": [40.7128, -74.0060],
-                "title": "New York",
-                "infoWindow": {"content": "Welcome to <b>New York</b>"}
-            }
-        ]'
-        attributes='{
-            "class": "foo",
-            "style": "height: 800px; width: 100%; border: 4px solid red; margin-block: 10vh;"
-        }'
-    />
-
-The ``<twig:ux:map />`` component requires the `Twig Component`_ package.
-
-.. code-block:: terminal
-
-    $ composer require symfony/ux-twig-component
-
-Interact with the map
-~~~~~~~~~~~~~~~~~~~~~
+Extend the default behavior
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Symfony UX Map allows you to extend its default behavior using a custom Stimulus controller:
 
@@ -297,6 +219,11 @@ Symfony UX Map allows you to extend its default behavior using a custom Stimulus
         }
     }
 
+.. tip::
+
+    Read the `Symfony UX Map Leaflet bridge docs`_ and the
+    `Symfony UX Map Google Maps brige docs`_ to learn about the exact code
+    needed to customize the markers.
 
 Then, you can use this controller in your template:
 
@@ -304,12 +231,6 @@ Then, you can use this controller in your template:
     
     {{ ux_map(my_map, { 'data-controller': 'mymap', style: 'height: 300px' }) }}
 
-.. tip::
-
-    Read the `Symfony UX Map Leaflet bridge docs`_ and the
-    `Symfony UX Map Google Maps brige docs`_ to learn about the exact code
-    needed to customize the markers.
-
 Backward Compatibility promise
 ------------------------------
 
diff --git a/src/Map/src/Bridge/Google/assets/package.json b/src/Map/src/Bridge/Google/assets/package.json
index 17322cf9..8b8dfdbc 100644
--- a/src/Map/src/Bridge/Google/assets/package.json
+++ b/src/Map/src/Bridge/Google/assets/package.json
@@ -6,15 +6,6 @@
     "type": "module",
     "main": "dist/map_controller.js",
     "types": "dist/map_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../../../../bin/build_package.js .",
-        "watch": "node ../../../../../../bin/build_package.js . --watch",
-        "test": "../../../../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "map": {
diff --git a/src/Map/src/Bridge/Leaflet/assets/package.json b/src/Map/src/Bridge/Leaflet/assets/package.json
index 1ac16b1d..3dd5663a 100644
--- a/src/Map/src/Bridge/Leaflet/assets/package.json
+++ b/src/Map/src/Bridge/Leaflet/assets/package.json
@@ -6,15 +6,6 @@
     "type": "module",
     "main": "dist/map_controller.js",
     "types": "dist/map_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../../../../bin/build_package.js .",
-        "watch": "node ../../../../../../bin/build_package.js . --watch",
-        "test": "../../../../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "map": {
diff --git a/src/Notify/assets/package.json b/src/Notify/assets/package.json
index 37c98d79..5f47e196 100644
--- a/src/Notify/assets/package.json
+++ b/src/Notify/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.0.0",
     "main": "dist/controller.js",
     "types": "dist/controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "notify": {
diff --git a/src/React/assets/package.json b/src/React/assets/package.json
index 8f1b3d50..a4f7f675 100644
--- a/src/React/assets/package.json
+++ b/src/React/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.0.0",
     "main": "dist/register_controller.js",
     "types": "dist/register_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "react": {
diff --git a/src/StimulusBundle/assets/package.json b/src/StimulusBundle/assets/package.json
index 4d0d2b40..03cf5905 100644
--- a/src/StimulusBundle/assets/package.json
+++ b/src/StimulusBundle/assets/package.json
@@ -4,15 +4,6 @@
     "version": "1.0.0",
     "license": "MIT",
     "main": "dist/loader.js",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "needsPackageAsADependency": false,
         "importmap": {
diff --git a/src/Svelte/assets/package.json b/src/Svelte/assets/package.json
index 7b80877f..95eabf51 100644
--- a/src/Svelte/assets/package.json
+++ b/src/Svelte/assets/package.json
@@ -4,15 +4,6 @@
     "main": "dist/register_controller.js",
     "version": "1.0.0",
     "license": "MIT",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "svelte": {
diff --git a/src/Swup/assets/package.json b/src/Swup/assets/package.json
index 1cabd23f..5e45461f 100644
--- a/src/Swup/assets/package.json
+++ b/src/Swup/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.1.0",
     "main": "dist/controller.js",
     "types": "dist/controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "swup": {
diff --git a/src/TogglePassword/assets/package.json b/src/TogglePassword/assets/package.json
index 2e27fec2..928dd1ad 100644
--- a/src/TogglePassword/assets/package.json
+++ b/src/TogglePassword/assets/package.json
@@ -8,15 +8,6 @@
     "config": {
         "css_source": "src/style.css"
     },
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "toggle-password": {
diff --git a/src/Translator/assets/package.json b/src/Translator/assets/package.json
index 6fd84918..53c12bbc 100644
--- a/src/Translator/assets/package.json
+++ b/src/Translator/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.0.0",
     "main": "dist/translator_controller.js",
     "types": "dist/translator_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "importmap": {
             "intl-messageformat": "^10.5.11",
diff --git a/src/Turbo/assets/package.json b/src/Turbo/assets/package.json
index bf086784..395ac24c 100644
--- a/src/Turbo/assets/package.json
+++ b/src/Turbo/assets/package.json
@@ -6,15 +6,6 @@
     "version": "0.1.0",
     "main": "dist/turbo_controller.js",
     "types": "dist/turbo_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "turbo-core": {
diff --git a/src/TwigComponent/config/cache.php b/src/TwigComponent/config/cache.php
deleted file mode 100644
index e8f62ee2..00000000
--- a/src/TwigComponent/config/cache.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?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\UX\TwigComponent\DependencyInjection\Loader\Configurator;
-
-use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
-
-return static function (ContainerConfigurator $container): void {
-    $container->services()
-        ->set('cache.ux.twig_component')
-            ->parent('cache.system')
-            ->private()
-            ->tag('cache.pool')
-    ;
-};
diff --git a/src/TwigComponent/src/CacheWarmer/TwigComponentCacheWarmer.php b/src/TwigComponent/src/CacheWarmer/TwigComponentCacheWarmer.php
deleted file mode 100644
index fad5c74c..00000000
--- a/src/TwigComponent/src/CacheWarmer/TwigComponentCacheWarmer.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?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\UX\TwigComponent\CacheWarmer;
-
-use Psr\Container\ContainerInterface;
-use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
-use Symfony\Contracts\Service\ServiceSubscriberInterface;
-use Symfony\UX\TwigComponent\ComponentProperties;
-
-/**
- * Warm the TwigComponent metadata caches.
- *
- * @author Simon André <smn.andre@gmail.com>
- *
- * @internal
- */
-final class TwigComponentCacheWarmer implements CacheWarmerInterface, ServiceSubscriberInterface
-{
-    /**
-     * As this cache warmer is optional, dependencies should be lazy-loaded, that's why a container should be injected.
-     */
-    public function __construct(
-        private readonly ContainerInterface $container,
-    ) {
-    }
-
-    public static function getSubscribedServices(): array
-    {
-        return [
-            'ux.twig_component.component_properties' => ComponentProperties::class,
-        ];
-    }
-
-    public function warmUp(string $cacheDir, ?string $buildDir = null): array
-    {
-        $properties = $this->container->get('ux.twig_component.component_properties');
-        $properties->warmup();
-
-        return [];
-    }
-
-    public function isOptional(): bool
-    {
-        return true;
-    }
-}
diff --git a/src/TwigComponent/src/ComponentProperties.php b/src/TwigComponent/src/ComponentProperties.php
deleted file mode 100644
index abb8c733..00000000
--- a/src/TwigComponent/src/ComponentProperties.php
+++ /dev/null
@@ -1,148 +0,0 @@
-<?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\UX\TwigComponent;
-
-use Symfony\Component\Cache\Adapter\AdapterInterface;
-use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
-use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
-
-/**
- * @author Simon André <smn.andre@gmail.com>
- *
- * @internal
- */
-final class ComponentProperties
-{
-    private const CACHE_KEY = 'ux.twig_component.component_properties';
-
-    /**
-     * @var array<class-string, array{
-     *     properties: array<class-string, array{string, array{string, string, bool}, bool}>,
-     *     methods: array<class-string, array{string, array{string, bool}}>,
-     *  }|null>
-     */
-    private array $classMetadata;
-
-    public function __construct(
-        private readonly PropertyAccessorInterface $propertyAccessor,
-        ?array $classMetadata = [],
-        private readonly ?AdapterInterface $cache = null,
-    ) {
-        $cacheItem = $this->cache?->getItem(self::CACHE_KEY);
-
-        $this->classMetadata = $cacheItem?->isHit() ? [...$cacheItem->get(), ...$classMetadata] : $classMetadata;
-    }
-
-    /**
-     * @return array<string, mixed>
-     */
-    public function getProperties(object $component, bool $publicProps = false): array
-    {
-        return iterator_to_array($this->extractProperties($component, $publicProps));
-    }
-
-    public function warmup(): void
-    {
-        if (!$this->cache) {
-            return;
-        }
-
-        foreach ($this->classMetadata as $class => $metadata) {
-            if (null === $metadata) {
-                $this->classMetadata[$class] = $this->loadClassMetadata($class);
-            }
-        }
-
-        $this->cache->save($this->cache->getItem(self::CACHE_KEY)->set($this->classMetadata));
-    }
-
-    /**
-     * @return \Generator<string, mixed>
-     */
-    private function extractProperties(object $component, bool $publicProps): \Generator
-    {
-        yield from $publicProps ? get_object_vars($component) : [];
-
-        $metadata = $this->classMetadata[$component::class] ??= $this->loadClassMetadata($component::class);
-
-        foreach ($metadata['properties'] as $propertyName => $property) {
-            $value = $property['getter'] ? $component->{$property['getter']}() : $this->propertyAccessor->getValue($component, $propertyName);
-            if ($property['destruct'] ?? false) {
-                yield from $value;
-            } else {
-                yield $property['name'] => $value;
-            }
-        }
-
-        foreach ($metadata['methods'] as $methodName => $method) {
-            if ($method['destruct'] ?? false) {
-                yield from $component->{$methodName}();
-            } else {
-                yield $method['name'] => $component->{$methodName}();
-            }
-        }
-    }
-
-    /**
-     * @param class-string $class
-     *
-     * @return array{
-     *   properties: array<string, array{
-     *     name?: string,
-     *     getter?: string,
-     *     destruct?: bool
-     *   }>,
-     *   methods: array<string, array{
-     *     name?: string,
-     *     destruct?: bool
-     *   }>,
-     * }
-     */
-    private function loadClassMetadata(string $class): array
-    {
-        $refClass = new \ReflectionClass($class);
-
-        $properties = [];
-        foreach ($refClass->getProperties() as $property) {
-            if (!$attributes = $property->getAttributes(ExposeInTemplate::class)) {
-                continue;
-            }
-            $attribute = $attributes[0]->newInstance();
-            $properties[$property->name] = [
-                'name' => $attribute->name ?? $property->name,
-                'getter' => $attribute->getter ? rtrim($attribute->getter, '()') : null,
-            ];
-            if ($attribute->destruct) {
-                unset($properties[$property->name]['name']);
-                $properties[$property->name]['destruct'] = true;
-            }
-        }
-
-        $methods = [];
-        foreach ($refClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
-            if (!$attributes = $method->getAttributes(ExposeInTemplate::class)) {
-                continue;
-            }
-            if ($method->getNumberOfRequiredParameters()) {
-                throw new \LogicException(\sprintf('Cannot use "%s" on methods with required parameters (%s::%s).', ExposeInTemplate::class, $class, $method->name));
-            }
-            $attribute = $attributes[0]->newInstance();
-            $name = $attribute->name ?? (str_starts_with($method->name, 'get') ? lcfirst(substr($method->name, 3)) : $method->name);
-            $methods[$method->name] = $attribute->destruct ? ['destruct' => true] : ['name' => $name];
-        }
-
-        return [
-            'properties' => $properties,
-            'methods' => $methods,
-        ];
-    }
-}
diff --git a/src/TwigComponent/src/ComponentRenderer.php b/src/TwigComponent/src/ComponentRenderer.php
index fb6a01ff..3273ba51 100644
--- a/src/TwigComponent/src/ComponentRenderer.php
+++ b/src/TwigComponent/src/ComponentRenderer.php
@@ -11,7 +11,9 @@
 
 namespace Symfony\UX\TwigComponent;
 
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
+use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
 use Symfony\UX\TwigComponent\Event\PostRenderEvent;
 use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent;
 use Symfony\UX\TwigComponent\Event\PreRenderEvent;
@@ -28,7 +30,7 @@ final class ComponentRenderer implements ComponentRendererInterface
         private Environment $twig,
         private EventDispatcherInterface $dispatcher,
         private ComponentFactory $factory,
-        private ComponentProperties $componentProperties,
+        private PropertyAccessorInterface $propertyAccessor,
         private ComponentStack $componentStack,
     ) {
     }
@@ -105,11 +107,9 @@ final class ComponentRenderer implements ComponentRendererInterface
     {
         $component = $mounted->getComponent();
         $metadata = $this->factory->metadataFor($mounted->getName());
+        $isAnonymous = $mounted->getComponent() instanceof AnonymousComponent;
 
-        $classProps = [];
-        if (!$metadata->isAnonymous()) {
-            $classProps = $this->componentProperties->getProperties($component, $metadata->isPublicPropsExposed());
-        }
+        $classProps = $isAnonymous ? [] : iterator_to_array($this->exposedVariables($component, $metadata->isPublicPropsExposed()));
 
         // expose public properties and properties marked with ExposeInTemplate attribute
         $props = [...$mounted->getInputProps(), ...$classProps];
@@ -137,4 +137,57 @@ final class ComponentRenderer implements ComponentRendererInterface
 
         return $event;
     }
+
+    private function exposedVariables(object $component, bool $exposePublicProps): \Iterator
+    {
+        if ($exposePublicProps) {
+            yield from get_object_vars($component);
+        }
+
+        $class = new \ReflectionClass($component);
+
+        foreach ($class->getProperties() as $property) {
+            if (!$attribute = $property->getAttributes(ExposeInTemplate::class)[0] ?? null) {
+                continue;
+            }
+
+            $attribute = $attribute->newInstance();
+
+            /** @var ExposeInTemplate $attribute */
+            $value = $attribute->getter ? $component->{rtrim($attribute->getter, '()')}() : $this->propertyAccessor->getValue($component, $property->name);
+
+            if ($attribute->destruct) {
+                foreach ($value as $key => $destructedValue) {
+                    yield $key => $destructedValue;
+                }
+            }
+
+            yield $attribute->name ?? $property->name => $value;
+        }
+
+        foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
+            if (!$attribute = $method->getAttributes(ExposeInTemplate::class)[0] ?? null) {
+                continue;
+            }
+
+            $attribute = $attribute->newInstance();
+
+            /** @var ExposeInTemplate $attribute */
+            $name = $attribute->name ?? (str_starts_with($method->name, 'get') ? lcfirst(substr($method->name, 3)) : $method->name);
+
+            if ($method->getNumberOfRequiredParameters()) {
+                throw new \LogicException(\sprintf('Cannot use "%s" on methods with required parameters (%s::%s).', ExposeInTemplate::class, $component::class, $method->name));
+            }
+
+            if ($attribute->destruct) {
+                foreach ($component->{$method->name}() as $prop => $value) {
+                    yield $prop => $value;
+                }
+
+                return;
+            }
+
+            yield $name => $component->{$method->name}();
+        }
+    }
 }
diff --git a/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php b/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php
index faf86afe..2a4ec1b0 100644
--- a/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php
+++ b/src/TwigComponent/src/DependencyInjection/Compiler/TwigComponentPass.php
@@ -80,9 +80,6 @@ final class TwigComponentPass implements CompilerPassInterface
         $factoryDefinition->setArgument(4, $componentConfig);
         $factoryDefinition->setArgument(5, $componentClassMap);
 
-        $componentPropertiesDefinition = $container->findDefinition('ux.twig_component.component_properties');
-        $componentPropertiesDefinition->setArgument(1, array_fill_keys(array_keys($componentClassMap), null));
-
         $debugCommandDefinition = $container->findDefinition('ux.twig_component.command.debug');
         $debugCommandDefinition->setArgument(3, $componentClassMap);
     }
diff --git a/src/TwigComponent/src/DependencyInjection/TwigComponentExtension.php b/src/TwigComponent/src/DependencyInjection/TwigComponentExtension.php
index 0ee72306..72cd6f26 100644
--- a/src/TwigComponent/src/DependencyInjection/TwigComponentExtension.php
+++ b/src/TwigComponent/src/DependencyInjection/TwigComponentExtension.php
@@ -21,17 +21,14 @@ use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
 use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
 use Symfony\Component\DependencyInjection\ChildDefinition;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Exception\LogicException;
 use Symfony\Component\DependencyInjection\Extension\Extension;
 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
 use Symfony\Component\DependencyInjection\Parameter;
 use Symfony\Component\DependencyInjection\Reference;
 use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
-use Symfony\UX\TwigComponent\CacheWarmer\TwigComponentCacheWarmer;
 use Symfony\UX\TwigComponent\Command\TwigComponentDebugCommand;
 use Symfony\UX\TwigComponent\ComponentFactory;
-use Symfony\UX\TwigComponent\ComponentProperties;
 use Symfony\UX\TwigComponent\ComponentRenderer;
 use Symfony\UX\TwigComponent\ComponentRendererInterface;
 use Symfony\UX\TwigComponent\ComponentStack;
@@ -87,29 +84,21 @@ final class TwigComponentExtension extends Extension implements ConfigurationInt
         $container->register('ux.twig_component.component_factory', ComponentFactory::class)
             ->setArguments([
                 new Reference('ux.twig_component.component_template_finder'),
-                new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)),
+                class_exists(AbstractArgument::class) ? new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)) : null,
                 new Reference('property_accessor'),
                 new Reference('event_dispatcher'),
-                new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)),
+                class_exists(AbstractArgument::class) ? new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)) : [],
             ])
         ;
 
         $container->register('ux.twig_component.component_stack', ComponentStack::class);
 
-        $container->register('ux.twig_component.component_properties', ComponentProperties::class)
-            ->setArguments([
-                new Reference('property_accessor'),
-                new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)),
-                new Reference('cache.ux.twig_component', ContainerInterface::IGNORE_ON_INVALID_REFERENCE),
-            ])
-        ;
-
         $container->register('ux.twig_component.component_renderer', ComponentRenderer::class)
             ->setArguments([
                 new Reference('twig'),
                 new Reference('event_dispatcher'),
                 new Reference('ux.twig_component.component_factory'),
-                new Reference('ux.twig_component.component_properties'),
+                new Reference('property_accessor'),
                 new Reference('ux.twig_component.component_stack'),
             ])
         ;
@@ -118,7 +107,7 @@ final class TwigComponentExtension extends Extension implements ConfigurationInt
             ->addTag('twig.extension')
         ;
 
-        $container->register('ux.twig_component.twig.component_runtime', ComponentRuntime::class)
+        $container->register('.ux.twig_component.twig.component_runtime', ComponentRuntime::class)
             ->setArguments([
                 new Reference('ux.twig_component.component_renderer'),
                 new ServiceLocatorArgument(new TaggedIteratorArgument('ux.twig_component.twig_renderer', indexAttribute: 'key', needsIndexes: true)),
@@ -137,7 +126,7 @@ final class TwigComponentExtension extends Extension implements ConfigurationInt
                 new Parameter('twig.default_path'),
                 new Reference('ux.twig_component.component_factory'),
                 new Reference('twig'),
-                new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)),
+                class_exists(AbstractArgument::class) ? new AbstractArgument(\sprintf('Added in %s.', TwigComponentPass::class)) : [],
                 $config['anonymous_template_directory'],
             ])
             ->addTag('console.command')
@@ -149,14 +138,6 @@ final class TwigComponentExtension extends Extension implements ConfigurationInt
         if ($container->getParameter('kernel.debug') && $config['profiler']) {
             $loader->load('debug.php');
         }
-
-        $loader->load('cache.php');
-
-        $container->register('ux.twig_component.cache_warmer', TwigComponentCacheWarmer::class)
-            ->setArguments([new Reference(\Psr\Container\ContainerInterface::class)])
-            ->addTag('kernel.cache_warmer')
-            ->addTag('container.service_subscriber', ['id' => 'ux.twig_component.component_properties'])
-        ;
     }
 
     public function getConfigTreeBuilder(): TreeBuilder
diff --git a/src/TwigComponent/src/Twig/TwigPreLexer.php b/src/TwigComponent/src/Twig/TwigPreLexer.php
index 2e0fdbe7..5d6d41f3 100644
--- a/src/TwigComponent/src/Twig/TwigPreLexer.php
+++ b/src/TwigComponent/src/Twig/TwigPreLexer.php
@@ -39,7 +39,7 @@ class TwigPreLexer
             return $input;
         }
 
-        $this->input = $input;
+        $this->input = $input = str_replace(["\r\n", "\r"], "\n", $input);
         $this->length = \strlen($input);
         $output = '';
 
@@ -126,7 +126,8 @@ class TwigPreLexer
                 // open the default block
                 if (!empty($this->currentComponents)
                     && !$this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock']) {
-                    $output .= $this->addDefaultBlock();
+                    $output .= '{% block content %}';
+                    $this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = true;
                 }
 
                 $attributes = $this->consumeAttributes($componentName);
@@ -182,7 +183,8 @@ class TwigPreLexer
                 && preg_match('/\S/', $char)
                 && !$this->check('{% block')
             ) {
-                $output .= $this->addDefaultBlock();
+                $this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = true;
+                $output .= '{% block content %}';
             }
 
             $output .= $char;
@@ -199,29 +201,14 @@ class TwigPreLexer
 
     private function consumeComponentName(?string $customExceptionMessage = null): string
     {
-        $start = $this->position;
-        while ($this->position < $this->length && preg_match('/[A-Za-z0-9_:@\-.]/', $this->input[$this->position])) {
-            ++$this->position;
-        }
+        if (preg_match('/\G[A-Za-z0-9_:@\-.]+/', $this->input, $matches, 0, $this->position)) {
+            $componentName = $matches[0];
+            $this->position += \strlen($componentName);
 
-        $componentName = substr($this->input, $start, $this->position - $start);
-
-        if (empty($componentName)) {
-            $exceptionMessage = $customExceptionMessage;
-            if (null == $exceptionMessage) {
-                $exceptionMessage = 'Expected component name when resolving the "<twig:" syntax.';
-            }
-            throw new SyntaxError($exceptionMessage, $this->line);
+            return $componentName;
         }
 
-        return $componentName;
-    }
-
-    private function consumeAttributeName(string $componentName): string
-    {
-        $message = \sprintf('Expected attribute name when parsing the "<twig:%s" syntax.', $componentName);
-
-        return $this->consumeComponentName($message);
+        throw new SyntaxError($customExceptionMessage ?? 'Expected component name when resolving the "<twig:" syntax.', $this->line);
     }
 
     private function consumeAttributes(string $componentName): string
@@ -251,7 +238,9 @@ class TwigPreLexer
                 $isAttributeDynamic = true;
             }
 
-            $key = $this->consumeAttributeName($componentName);
+            $message = \sprintf('Expected attribute name when parsing the "<twig:%s" syntax.', $componentName);
+            // was called 'consumeAttributeName'
+            $key = $this->consumeComponentName($message);
 
             // <twig:component someProp> -> someProp: true
             if (!$this->check('=')) {
@@ -290,9 +279,8 @@ class TwigPreLexer
      */
     private function consume(string $string): bool
     {
-        $stringLength = \strlen($string);
-        if (substr($this->input, $this->position, $stringLength) === $string) {
-            $this->position += $stringLength;
+        if (str_starts_with(substr($this->input, $this->position), $string)) {
+            $this->position += \strlen($string);
 
             return true;
         }
@@ -325,31 +313,25 @@ class TwigPreLexer
      */
     private function consumeUntil(string $endString): string
     {
-        $start = $this->position;
-        $endCharLength = \strlen($endString);
+        if (false === $endPosition = strpos($this->input, $endString, $this->position)) {
+            $start = $this->position;
+            $this->position = $this->length;
 
-        while ($this->position < $this->length) {
-            if (substr($this->input, $this->position, $endCharLength) === $endString) {
-                break;
-            }
-
-            if ("\n" === $this->input[$this->position]) {
-                ++$this->line;
-            }
-            ++$this->position;
+            return substr($this->input, $start);
         }
 
-        return substr($this->input, $start, $this->position - $start);
+        $content = substr($this->input, $this->position, $endPosition - $this->position);
+        $this->line += substr_count($content, "\n");
+        $this->position = $endPosition;
+
+        return $content;
     }
 
     private function consumeWhitespace(): void
     {
-        while ($this->position < $this->length && preg_match('/\s/', $this->input[$this->position])) {
-            if ("\n" === $this->input[$this->position]) {
-                ++$this->line;
-            }
-            ++$this->position;
-        }
+        $whitespace = substr($this->input, $this->position, strspn($this->input, " \t\n\r\0\x0B", $this->position));
+        $this->line += substr_count($whitespace, "\n");
+        $this->position += \strlen($whitespace);
     }
 
     /**
@@ -374,18 +356,8 @@ class TwigPreLexer
 
     private function check(string $chars): bool
     {
-        $charsLength = \strlen($chars);
-        if ($this->position + $charsLength > $this->length) {
-            return false;
-        }
-
-        for ($i = 0; $i < $charsLength; ++$i) {
-            if ($this->input[$this->position + $i] !== $chars[$i]) {
-                return false;
-            }
-        }
-
-        return true;
+        return $this->position + \strlen($chars) <= $this->length
+            && 0 === substr_compare($this->input, $chars, $this->position, \strlen($chars));
     }
 
     private function consumeBlock(string $componentName): string
@@ -409,7 +381,7 @@ class TwigPreLexer
         $output = "{% block {$blockName} %}";
 
         $closingTag = '</twig:block>';
-        if (!$this->doesStringEventuallyExist($closingTag)) {
+        if (false === strpos($this->input, $closingTag, $this->position)) {
             throw new SyntaxError("Expected closing tag '{$closingTag}' for block '{$blockName}'.", $this->line);
         }
         $blockContents = $this->consumeUntilEndBlock();
@@ -448,7 +420,8 @@ class TwigPreLexer
             if (!$inComment && '{% endblock %}' === substr($this->input, $this->position, 14)) {
                 if (1 === $depth) {
                     // in this case, we want to advance ALL the way beyond the endblock
-                    $this->position += 14 /* strlen('{% endblock %}') */;
+                    // strlen('{% endblock %}') = 14
+                    $this->position += 14;
                     break;
                 } else {
                     --$depth;
@@ -512,18 +485,4 @@ class TwigPreLexer
 
         return implode('~', $parts);
     }
-
-    private function doesStringEventuallyExist(string $needle): bool
-    {
-        $remainingString = substr($this->input, $this->position);
-
-        return str_contains($remainingString, $needle);
-    }
-
-    private function addDefaultBlock(): string
-    {
-        $this->currentComponents[\count($this->currentComponents) - 1]['hasDefaultBlock'] = true;
-
-        return '{% block content %}';
-    }
 }
diff --git a/src/Typed/assets/package.json b/src/Typed/assets/package.json
index d146fb63..e187dcab 100644
--- a/src/Typed/assets/package.json
+++ b/src/Typed/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.0.0",
     "main": "dist/controller.js",
     "types": "dist/controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "typed": {
diff --git a/src/Vue/assets/package.json b/src/Vue/assets/package.json
index 9b20a09f..05ec27f6 100644
--- a/src/Vue/assets/package.json
+++ b/src/Vue/assets/package.json
@@ -5,15 +5,6 @@
     "version": "1.0.0",
     "main": "dist/register_controller.js",
     "types": "dist/register_controller.d.ts",
-    "scripts": {
-        "build": "node ../../../bin/build_package.js .",
-        "watch": "node ../../../bin/build_package.js . --watch",
-        "test": "../../../bin/test_package.sh .",
-        "lint": "biome lint --write",
-        "format": "biome format --write",
-        "check-lint": "biome lint",
-        "check-format": "biome format"
-    },
     "symfony": {
         "controllers": {
             "vue": {
diff --git a/ux.symfony.com/.symfony.local.yaml b/ux.symfony.com/.symfony.local.yaml
index 4257e69b..cc6d3fe3 100644
--- a/ux.symfony.com/.symfony.local.yaml
+++ b/ux.symfony.com/.symfony.local.yaml
@@ -2,6 +2,3 @@ workers:
     docker_compose: ~
     sass:
         cmd: ['symfony', 'console', 'sass:build', '--watch']
-
-http:
-    use_gzip: true
diff --git a/ux.symfony.com/assets/styles/app/_font.scss b/ux.symfony.com/assets/styles/app/_font.scss
index 8430dad7..22285408 100644
--- a/ux.symfony.com/assets/styles/app/_font.scss
+++ b/ux.symfony.com/assets/styles/app/_font.scss
@@ -20,17 +20,3 @@
         url("https://cdn.jsdelivr.net/npm/@fontsource/ubuntu@5.0.8/files/ubuntu-latin-700-normal.woff2") format('woff2');
   unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
 }
-/* ubuntu-sans-latin-wght-normal */
-@font-face {
-  font-family: 'Ubuntu Sans';
-  font-style: normal;
-  font-display: swap;
-  font-weight: 100 800;
-  src:  local("Ubuntu Sans"),
-        local("Ubuntu-Sans"),
-        local("Ubuntu-Sans-Variable"),
-        local("UbuntuSans"),
-        local("UbuntuSans-Variable"),
-        url(https://cdn.jsdelivr.net/fontsource/fonts/ubuntu-sans:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
-  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
-}
diff --git a/ux.symfony.com/assets/styles/app/_root.scss b/ux.symfony.com/assets/styles/app/_root.scss
index 9514471f..ba8fcd7a 100644
--- a/ux.symfony.com/assets/styles/app/_root.scss
+++ b/ux.symfony.com/assets/styles/app/_root.scss
@@ -14,7 +14,7 @@
   --space-larger: 2rem;
 
   // Fonts
-  --font-family-title: "Ubuntu Sans", "Ubuntu", system-ui, sans-serif;
+  --font-family-title: "Ubuntu", "Helvetica Neue", sans-serif;
   --font-family-text: system-ui, sans-serif;
   --font-family-code: ui-monospace, "SF Mono", SFMono-Regular, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
 
diff --git a/ux.symfony.com/composer.json b/ux.symfony.com/composer.json
index bd7335ca..1931679b 100644
--- a/ux.symfony.com/composer.json
+++ b/ux.symfony.com/composer.json
@@ -7,31 +7,31 @@
         "php": ">=8.3",
         "ext-ctype": "*",
         "ext-iconv": "*",
-        "composer/semver": "^3.4.3",
+        "composer/semver": "^3.4",
         "doctrine/doctrine-bundle": "^2.13",
         "doctrine/doctrine-migrations-bundle": "^3.3.1",
-        "doctrine/orm": "^2.20.0",
+        "doctrine/orm": "^2.19.7",
         "intervention/image": "^2.7.2",
         "kornrunner/blurhash": "^1.2.2",
-        "league/commonmark": "^2.5.3",
-        "symfony/asset": "7.2.*",
-        "symfony/asset-mapper": "7.2.*",
-        "symfony/console": "7.2.*",
-        "symfony/dotenv": "7.2.*",
-        "symfony/expression-language": "7.2.*",
-        "symfony/flex": "^2.4.7",
-        "symfony/form": "7.2.*",
-        "symfony/framework-bundle": "7.2.*",
-        "symfony/http-client": "7.2.*",
+        "league/commonmark": "^2.5",
+        "symfony/asset": "7.1.*",
+        "symfony/asset-mapper": "7.1.*",
+        "symfony/console": "7.1.*",
+        "symfony/dotenv": "7.1.*",
+        "symfony/expression-language": "7.1.*",
+        "symfony/flex": "^2.4",
+        "symfony/form": "7.1.*",
+        "symfony/framework-bundle": "7.1.*",
+        "symfony/http-client": "7.1.*",
         "symfony/mercure-bundle": "^0.3.9",
-        "symfony/monolog-bundle": "^3.10",
-        "symfony/notifier": "7.2.*",
-        "symfony/runtime": "7.2.*",
-        "symfony/serializer": "7.2.*",
+        "symfony/monolog-bundle": "^3.11",
+        "symfony/notifier": "7.1.*",
+        "symfony/runtime": "7.1.*",
+        "symfony/serializer": "7.1.*",
         "symfony/stimulus-bundle": "2.x-dev",
-        "symfony/translation": "7.2.*",
-        "symfony/twig-bundle": "7.2.*",
-        "symfony/uid": "7.2.*",
+        "symfony/translation": "7.1.*",
+        "symfony/twig-bundle": "7.1.*",
+        "symfony/uid": "7.1.*",
         "symfony/ux-autocomplete": "2.x-dev",
         "symfony/ux-chartjs": "2.x-dev",
         "symfony/ux-cropperjs": "2.x-dev",
@@ -51,12 +51,12 @@
         "symfony/ux-twig-component": "2.x-dev",
         "symfony/ux-typed": "2.x-dev",
         "symfony/ux-vue": "2.x-dev",
-        "symfony/validator": "7.2.*",
-        "symfony/yaml": "7.2.*",
+        "symfony/validator": "7.1.*",
+        "symfony/yaml": "7.1.*",
         "symfonycasts/dynamic-forms": "^0.1.2",
-        "symfonycasts/sass-bundle": "0.8.*",
-        "tempest/highlight": "^2.10.6",
-        "twbs/bootstrap": "^5.3.3",
+        "symfonycasts/sass-bundle": "^0.6.0",
+        "tempest/highlight": "^2.10.3",
+        "twbs/bootstrap": "^5.3",
         "twig/extra-bundle": "^3.13",
         "twig/html-extra": "^3.13",
         "twig/intl-extra": "^3.13",
@@ -65,17 +65,17 @@
         "twig/twig": "^3.14"
     },
     "require-dev": {
-        "phpunit/phpunit": "^9.6.21",
-        "symfony/browser-kit": "7.2.*",
-        "symfony/css-selector": "7.2.*",
-        "symfony/debug-bundle": "7.2.*",
-        "symfony/maker-bundle": "^1.61",
-        "symfony/phpunit-bridge": "7.2.*",
-        "symfony/stopwatch": "7.2.*",
-        "symfony/web-profiler-bundle": "7.2.*",
+        "phpunit/phpunit": "^9.6.9",
+        "symfony/browser-kit": "7.1.*",
+        "symfony/css-selector": "7.1.*",
+        "symfony/debug-bundle": "7.1.*",
+        "symfony/maker-bundle": "^1.60",
+        "symfony/phpunit-bridge": "7.1.*",
+        "symfony/stopwatch": "7.1.*",
+        "symfony/web-profiler-bundle": "7.1.*",
         "vincentlanglet/twig-cs-fixer": "3.1.*",
         "zenstruck/browser": "^1.9",
-        "zenstruck/foundry": "2.2.*"
+        "zenstruck/foundry": "2.0.*"
     },
     "replace": {
         "symfony/polyfill-ctype": "*",
@@ -119,7 +119,7 @@
         "symfony": {
             "allow-contrib": false,
             "docker": true,
-            "require": "7.2.*"
+            "require": "7.1.*"
         }
     },
     "scripts": {
diff --git a/ux.symfony.com/composer.lock b/ux.symfony.com/composer.lock
index 64824239..43e4ea9d 100644
--- a/ux.symfony.com/composer.lock
+++ b/ux.symfony.com/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "f9bf689e0e76abae07cd63aa31447eea",
+    "content-hash": "a1a1ef4f3aba41044cc0f8c7a74f73f7",
     "packages": [
         {
             "name": "composer/semver",
@@ -1341,16 +1341,16 @@
         },
         {
             "name": "doctrine/persistence",
-            "version": "3.4.0",
+            "version": "3.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/doctrine/persistence.git",
-                "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff"
+                "reference": "b337726451f5d530df338fc7f68dee8781b49779"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff",
-                "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff",
+                "url": "https://api.github.com/repos/doctrine/persistence/zipball/b337726451f5d530df338fc7f68dee8781b49779",
+                "reference": "b337726451f5d530df338fc7f68dee8781b49779",
                 "shasum": ""
             },
             "require": {
@@ -1364,11 +1364,12 @@
             "require-dev": {
                 "doctrine/coding-standard": "^12",
                 "doctrine/common": "^3.0",
-                "phpstan/phpstan": "1.12.7",
+                "phpstan/phpstan": "1.11.1",
                 "phpstan/phpstan-phpunit": "^1",
                 "phpstan/phpstan-strict-rules": "^1.1",
-                "phpunit/phpunit": "^8.5.38 || ^9.5",
-                "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0"
+                "phpunit/phpunit": "^8.5 || ^9.5",
+                "symfony/cache": "^4.4 || ^5.4 || ^6.0",
+                "vimeo/psalm": "4.30.0 || 5.24.0"
             },
             "type": "library",
             "autoload": {
@@ -1417,7 +1418,7 @@
             ],
             "support": {
                 "issues": "https://github.com/doctrine/persistence/issues",
-                "source": "https://github.com/doctrine/persistence/tree/3.4.0"
+                "source": "https://github.com/doctrine/persistence/tree/3.3.3"
             },
             "funding": [
                 {
@@ -1433,7 +1434,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-30T19:48:12+00:00"
+            "time": "2024-06-20T10:14:30+00:00"
         },
         {
             "name": "doctrine/sql-formatter",
@@ -2709,16 +2710,16 @@
         },
         {
             "name": "symfony/asset",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/asset.git",
-                "reference": "cb926cd59fefa1f9b4900b3695f0f846797ba5c0"
+                "reference": "8970de4a0cedd34e097c0f5c502a614780b9ca43"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/asset/zipball/cb926cd59fefa1f9b4900b3695f0f846797ba5c0",
-                "reference": "cb926cd59fefa1f9b4900b3695f0f846797ba5c0",
+                "url": "https://api.github.com/repos/symfony/asset/zipball/8970de4a0cedd34e097c0f5c502a614780b9ca43",
+                "reference": "8970de4a0cedd34e097c0f5c502a614780b9ca43",
                 "shasum": ""
             },
             "require": {
@@ -2758,7 +2759,7 @@
             "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/asset/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/asset/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -2774,20 +2775,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/asset-mapper",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/asset-mapper.git",
-                "reference": "984b58a711b8e8ad5c494b4fa827929b59b3916f"
+                "reference": "e3ae56f965f1fe503db1f604756a44d40e6dea16"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/984b58a711b8e8ad5c494b4fa827929b59b3916f",
-                "reference": "984b58a711b8e8ad5c494b4fa827929b59b3916f",
+                "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/e3ae56f965f1fe503db1f604756a44d40e6dea16",
+                "reference": "e3ae56f965f1fe503db1f604756a44d40e6dea16",
                 "shasum": ""
             },
             "require": {
@@ -2837,7 +2838,7 @@
             "description": "Maps directories of assets & makes them available in a public directory with versioned filenames.",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/asset-mapper/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/asset-mapper/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -2853,20 +2854,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-27T08:35:32+00:00"
+            "time": "2024-09-19T08:57:32+00:00"
         },
         {
             "name": "symfony/cache",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/cache.git",
-                "reference": "1354995a9e758e7141a90ed99248a0e21bee701d"
+                "reference": "86e5296b10e4dec8c8441056ca606aedb8a3be0a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/cache/zipball/1354995a9e758e7141a90ed99248a0e21bee701d",
-                "reference": "1354995a9e758e7141a90ed99248a0e21bee701d",
+                "url": "https://api.github.com/repos/symfony/cache/zipball/86e5296b10e4dec8c8441056ca606aedb8a3be0a",
+                "reference": "86e5296b10e4dec8c8441056ca606aedb8a3be0a",
                 "shasum": ""
             },
             "require": {
@@ -2894,7 +2895,6 @@
                 "doctrine/dbal": "^3.6|^4",
                 "predis/predis": "^1.1|^2.0",
                 "psr/simple-cache": "^1.0|^2.0|^3.0",
-                "symfony/clock": "^6.4|^7.0",
                 "symfony/config": "^6.4|^7.0",
                 "symfony/dependency-injection": "^6.4|^7.0",
                 "symfony/filesystem": "^6.4|^7.0",
@@ -2935,7 +2935,7 @@
                 "psr6"
             ],
             "support": {
-                "source": "https://github.com/symfony/cache/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/cache/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -2951,7 +2951,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:40:01+00:00"
+            "time": "2024-09-17T09:16:35+00:00"
         },
         {
             "name": "symfony/cache-contracts",
@@ -3031,16 +3031,16 @@
         },
         {
             "name": "symfony/config",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "75cfe49f73d6d43110690e55fb212d697ee598d9"
+                "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/75cfe49f73d6d43110690e55fb212d697ee598d9",
-                "reference": "75cfe49f73d6d43110690e55fb212d697ee598d9",
+                "url": "https://api.github.com/repos/symfony/config/zipball/2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2",
+                "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2",
                 "shasum": ""
             },
             "require": {
@@ -3086,7 +3086,7 @@
             "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/config/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/config/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -3102,20 +3102,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "de74db6d7c9f4ecabf7b4a1a20655e021b034001"
+                "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/de74db6d7c9f4ecabf7b4a1a20655e021b034001",
-                "reference": "de74db6d7c9f4ecabf7b4a1a20655e021b034001",
+                "url": "https://api.github.com/repos/symfony/console/zipball/0fa539d12b3ccf068a722bbbffa07ca7079af9ee",
+                "reference": "0fa539d12b3ccf068a722bbbffa07ca7079af9ee",
                 "shasum": ""
             },
             "require": {
@@ -3179,7 +3179,7 @@
                 "terminal"
             ],
             "support": {
-                "source": "https://github.com/symfony/console/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/console/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -3195,20 +3195,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "6d5c6520d1984bc67af228dd6519e03e58661d7f"
+                "reference": "38465f925ec4e0707b090e9147c65869837d639d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6d5c6520d1984bc67af228dd6519e03e58661d7f",
-                "reference": "6d5c6520d1984bc67af228dd6519e03e58661d7f",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/38465f925ec4e0707b090e9147c65869837d639d",
+                "reference": "38465f925ec4e0707b090e9147c65869837d639d",
                 "shasum": ""
             },
             "require": {
@@ -3259,7 +3259,7 @@
             "description": "Allows you to standardize and centralize the way objects are constructed in your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/dependency-injection/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/dependency-injection/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -3275,7 +3275,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -3346,16 +3346,16 @@
         },
         {
             "name": "symfony/doctrine-bridge",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/doctrine-bridge.git",
-                "reference": "653ab90f3b2c7fcd3a37b29c23552ab7680f54d2"
+                "reference": "2568d0adaa5b0018b07beaa90363b880a43cc957"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/653ab90f3b2c7fcd3a37b29c23552ab7680f54d2",
-                "reference": "653ab90f3b2c7fcd3a37b29c23552ab7680f54d2",
+                "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/2568d0adaa5b0018b07beaa90363b880a43cc957",
+                "reference": "2568d0adaa5b0018b07beaa90363b880a43cc957",
                 "shasum": ""
             },
             "require": {
@@ -3368,7 +3368,6 @@
                 "symfony/service-contracts": "^2.5|^3"
             },
             "conflict": {
-                "doctrine/collections": "<1.8",
                 "doctrine/dbal": "<3.6",
                 "doctrine/lexer": "<1.1",
                 "doctrine/orm": "<2.15",
@@ -3385,7 +3384,7 @@
                 "symfony/validator": "<6.4"
             },
             "require-dev": {
-                "doctrine/collections": "^1.8|^2.0",
+                "doctrine/collections": "^1.0|^2.0",
                 "doctrine/data-fixtures": "^1.1",
                 "doctrine/dbal": "^3.6|^4",
                 "doctrine/orm": "^2.15|^3",
@@ -3435,7 +3434,7 @@
             "description": "Provides integration for Doctrine with various Symfony components",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/doctrine-bridge/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/doctrine-bridge/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -3451,20 +3450,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-08T12:32:26+00:00"
         },
         {
             "name": "symfony/dotenv",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dotenv.git",
-                "reference": "07b2c58767aadc8ed96b26fadc513a0d00ccd084"
+                "reference": "6d966200b399fa59759286f3fc7c919f0677c449"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dotenv/zipball/07b2c58767aadc8ed96b26fadc513a0d00ccd084",
-                "reference": "07b2c58767aadc8ed96b26fadc513a0d00ccd084",
+                "url": "https://api.github.com/repos/symfony/dotenv/zipball/6d966200b399fa59759286f3fc7c919f0677c449",
+                "reference": "6d966200b399fa59759286f3fc7c919f0677c449",
                 "shasum": ""
             },
             "require": {
@@ -3509,7 +3508,7 @@
                 "environment"
             ],
             "support": {
-                "source": "https://github.com/symfony/dotenv/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/dotenv/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -3525,20 +3524,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-28T12:51:41+00:00"
+            "time": "2024-09-17T09:16:35+00:00"
         },
         {
             "name": "symfony/error-handler",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/error-handler.git",
-                "reference": "ad57ca04868ca877e7919c56d20bdfa8024b54d6"
+                "reference": "432bb369952795c61ca1def65e078c4a80dad13c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/error-handler/zipball/ad57ca04868ca877e7919c56d20bdfa8024b54d6",
-                "reference": "ad57ca04868ca877e7919c56d20bdfa8024b54d6",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c",
+                "reference": "432bb369952795c61ca1def65e078c4a80dad13c",
                 "shasum": ""
             },
             "require": {
@@ -3584,7 +3583,7 @@
             "description": "Provides tools to manage errors and ease debugging PHP code",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/error-handler/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/error-handler/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -3600,20 +3599,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-14T08:54:27+00:00"
+            "time": "2024-07-26T13:02:51+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1"
+                "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1",
-                "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
+                "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
                 "shasum": ""
             },
             "require": {
@@ -3664,7 +3663,7 @@
             "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -3680,7 +3679,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/event-dispatcher-contracts",
@@ -3760,16 +3759,16 @@
         },
         {
             "name": "symfony/expression-language",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/expression-language.git",
-                "reference": "26f4884a455e755e630a5fc372df124a3578da2e"
+                "reference": "b9e4bc6685d513c10235145ed1042a6081635806"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/expression-language/zipball/26f4884a455e755e630a5fc372df124a3578da2e",
-                "reference": "26f4884a455e755e630a5fc372df124a3578da2e",
+                "url": "https://api.github.com/repos/symfony/expression-language/zipball/b9e4bc6685d513c10235145ed1042a6081635806",
+                "reference": "b9e4bc6685d513c10235145ed1042a6081635806",
                 "shasum": ""
             },
             "require": {
@@ -3804,7 +3803,7 @@
             "description": "Provides an engine that can compile and evaluate expressions",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/expression-language/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/expression-language/tree/v7.1.4"
             },
             "funding": [
                 {
@@ -3820,20 +3819,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-15T11:52:45+00:00"
+            "time": "2024-08-12T09:59:40+00:00"
         },
         {
             "name": "symfony/filesystem",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb"
+                "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
-                "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/61fe0566189bf32e8cfee78335d8776f64a66f5a",
+                "reference": "61fe0566189bf32e8cfee78335d8776f64a66f5a",
                 "shasum": ""
             },
             "require": {
@@ -3870,7 +3869,7 @@
             "description": "Provides basic utilities for the filesystem",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/filesystem/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/filesystem/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -3886,20 +3885,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-09-17T09:16:35+00:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49"
+                "reference": "d95bbf319f7d052082fb7af147e0f835a695e823"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49",
-                "reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823",
+                "reference": "d95bbf319f7d052082fb7af147e0f835a695e823",
                 "shasum": ""
             },
             "require": {
@@ -3934,7 +3933,7 @@
             "description": "Finds files and directories via an intuitive fluent interface",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/finder/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/finder/tree/v7.1.4"
             },
             "funding": [
                 {
@@ -3950,7 +3949,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-08-13T14:28:19+00:00"
         },
         {
             "name": "symfony/flex",
@@ -4022,16 +4021,16 @@
         },
         {
             "name": "symfony/form",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/form.git",
-                "reference": "73c00ef4ced12b43647a37c184f05650c636a539"
+                "reference": "6b8b53ad6d42f14b158c896163b96ff260d78222"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/form/zipball/73c00ef4ced12b43647a37c184f05650c636a539",
-                "reference": "73c00ef4ced12b43647a37c184f05650c636a539",
+                "url": "https://api.github.com/repos/symfony/form/zipball/6b8b53ad6d42f14b158c896163b96ff260d78222",
+                "reference": "6b8b53ad6d42f14b158c896163b96ff260d78222",
                 "shasum": ""
             },
             "require": {
@@ -4099,7 +4098,7 @@
             "description": "Allows to easily create, process and reuse HTML forms",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/form/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/form/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -4115,20 +4114,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/framework-bundle",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/framework-bundle.git",
-                "reference": "8a7df876a98d15c8b9f01b10397a76d5de548324"
+                "reference": "8a792de86230c13a9de7750c0c8b23cc083183d4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/8a7df876a98d15c8b9f01b10397a76d5de548324",
-                "reference": "8a7df876a98d15c8b9f01b10397a76d5de548324",
+                "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/8a792de86230c13a9de7750c0c8b23cc083183d4",
+                "reference": "8a792de86230c13a9de7750c0c8b23cc083183d4",
                 "shasum": ""
             },
             "require": {
@@ -4137,14 +4136,14 @@
                 "php": ">=8.2",
                 "symfony/cache": "^6.4|^7.0",
                 "symfony/config": "^6.4|^7.0",
-                "symfony/dependency-injection": "^7.2",
+                "symfony/dependency-injection": "^7.1.5",
                 "symfony/deprecation-contracts": "^2.5|^3",
                 "symfony/error-handler": "^6.4|^7.0",
                 "symfony/event-dispatcher": "^6.4|^7.0",
                 "symfony/filesystem": "^7.1",
                 "symfony/finder": "^6.4|^7.0",
                 "symfony/http-foundation": "^6.4|^7.0",
-                "symfony/http-kernel": "^7.2",
+                "symfony/http-kernel": "^6.4|^7.0",
                 "symfony/polyfill-mbstring": "~1.0",
                 "symfony/routing": "^6.4|^7.0"
             },
@@ -4166,18 +4165,16 @@
                 "symfony/mime": "<6.4",
                 "symfony/property-access": "<6.4",
                 "symfony/property-info": "<6.4",
-                "symfony/runtime": "<6.4.13|>=7.0,<7.1.6",
                 "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4",
                 "symfony/security-core": "<6.4",
-                "symfony/security-csrf": "<7.2",
-                "symfony/serializer": "<7.1",
+                "symfony/security-csrf": "<6.4",
+                "symfony/serializer": "<6.4",
                 "symfony/stopwatch": "<6.4",
                 "symfony/translation": "<6.4",
                 "symfony/twig-bridge": "<6.4",
                 "symfony/twig-bundle": "<6.4",
                 "symfony/validator": "<6.4",
                 "symfony/web-profiler-bundle": "<6.4",
-                "symfony/webhook": "<7.2",
                 "symfony/workflow": "<6.4"
             },
             "require-dev": {
@@ -4209,7 +4206,7 @@
                 "symfony/scheduler": "^6.4.4|^7.0.4",
                 "symfony/security-bundle": "^6.4|^7.0",
                 "symfony/semaphore": "^6.4|^7.0",
-                "symfony/serializer": "^7.1",
+                "symfony/serializer": "^6.4|^7.0",
                 "symfony/stopwatch": "^6.4|^7.0",
                 "symfony/string": "^6.4|^7.0",
                 "symfony/translation": "^6.4|^7.0",
@@ -4218,10 +4215,9 @@
                 "symfony/uid": "^6.4|^7.0",
                 "symfony/validator": "^6.4|^7.0",
                 "symfony/web-link": "^6.4|^7.0",
-                "symfony/webhook": "^7.2",
                 "symfony/workflow": "^6.4|^7.0",
                 "symfony/yaml": "^6.4|^7.0",
-                "twig/twig": "^3.12"
+                "twig/twig": "^3.0.4"
             },
             "type": "symfony-bundle",
             "autoload": {
@@ -4249,7 +4245,7 @@
             "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/framework-bundle/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/framework-bundle/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -4265,20 +4261,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-09-20T13:35:23+00:00"
         },
         {
             "name": "symfony/http-client",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-client.git",
-                "reference": "dee07290e432b1dde37dbb4ea1d67663f3cce0bc"
+                "reference": "abca35865118edf35a23f2f24978a1784c831cb4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-client/zipball/dee07290e432b1dde37dbb4ea1d67663f3cce0bc",
-                "reference": "dee07290e432b1dde37dbb4ea1d67663f3cce0bc",
+                "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4",
+                "reference": "abca35865118edf35a23f2f24978a1784c831cb4",
                 "shasum": ""
             },
             "require": {
@@ -4289,7 +4285,6 @@
                 "symfony/service-contracts": "^2.5|^3"
             },
             "conflict": {
-                "amphp/amp": "<2.5",
                 "php-http/discovery": "<1.15",
                 "symfony/http-foundation": "<6.4"
             },
@@ -4300,14 +4295,14 @@
                 "symfony/http-client-implementation": "3.0"
             },
             "require-dev": {
-                "amphp/http-client": "^4.2.1|^5.0",
-                "amphp/http-tunnel": "^1.0|^2.0",
+                "amphp/amp": "^2.5",
+                "amphp/http-client": "^4.2.1",
+                "amphp/http-tunnel": "^1.0",
                 "amphp/socket": "^1.1",
                 "guzzlehttp/promises": "^1.4|^2.0",
                 "nyholm/psr7": "^1.0",
                 "php-http/httplug": "^1.0|^2.0",
                 "psr/http-client": "^1.0",
-                "symfony/amphp-http-client-meta": "^1.0|^2.0",
                 "symfony/dependency-injection": "^6.4|^7.0",
                 "symfony/http-kernel": "^6.4|^7.0",
                 "symfony/messenger": "^6.4|^7.0",
@@ -4344,7 +4339,7 @@
                 "http"
             ],
             "support": {
-                "source": "https://github.com/symfony/http-client/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/http-client/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -4360,7 +4355,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-22T19:26:41+00:00"
+            "time": "2024-09-20T13:35:23+00:00"
         },
         {
             "name": "symfony/http-client-contracts",
@@ -4442,21 +4437,20 @@
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "735b8519a8bcbf603d3af0430fb1be5c8822af13"
+                "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/735b8519a8bcbf603d3af0430fb1be5c8822af13",
-                "reference": "735b8519a8bcbf603d3af0430fb1be5c8822af13",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e30ef73b1e44eea7eb37ba69600a354e553f694b",
+                "reference": "e30ef73b1e44eea7eb37ba69600a354e553f694b",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.2",
-                "symfony/deprecation-contracts": "^2.5|^3.0",
                 "symfony/polyfill-mbstring": "~1.1",
                 "symfony/polyfill-php83": "^1.27"
             },
@@ -4500,7 +4494,7 @@
             "description": "Defines an object-oriented layer for the HTTP specification",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-foundation/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/http-foundation/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -4516,20 +4510,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "1d5619199df507f9f03584ae9141924cc148050e"
+                "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1d5619199df507f9f03584ae9141924cc148050e",
-                "reference": "1d5619199df507f9f03584ae9141924cc148050e",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/44204d96150a9df1fc57601ec933d23fefc2d65b",
+                "reference": "44204d96150a9df1fc57601ec933d23fefc2d65b",
                 "shasum": ""
             },
             "require": {
@@ -4558,7 +4552,7 @@
                 "symfony/twig-bridge": "<6.4",
                 "symfony/validator": "<6.4",
                 "symfony/var-dumper": "<6.4",
-                "twig/twig": "<3.12"
+                "twig/twig": "<3.0.4"
             },
             "provide": {
                 "psr/log-implementation": "1.0|2.0|3.0"
@@ -4586,7 +4580,7 @@
                 "symfony/validator": "^6.4|^7.0",
                 "symfony/var-dumper": "^6.4|^7.0",
                 "symfony/var-exporter": "^6.4|^7.0",
-                "twig/twig": "^3.12"
+                "twig/twig": "^3.0.4"
             },
             "type": "library",
             "autoload": {
@@ -4614,7 +4608,7 @@
             "description": "Provides a structured process for converting a Request into a Response",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/http-kernel/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/http-kernel/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -4630,20 +4624,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-27T15:21:58+00:00"
+            "time": "2024-09-21T06:09:21+00:00"
         },
         {
             "name": "symfony/intl",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/intl.git",
-                "reference": "e0c8d9c19b3a52f2d379319fd16298568ce9573d"
+                "reference": "a0ba7a400e4c915500762c998355bea219a32d6b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/intl/zipball/e0c8d9c19b3a52f2d379319fd16298568ce9573d",
-                "reference": "e0c8d9c19b3a52f2d379319fd16298568ce9573d",
+                "url": "https://api.github.com/repos/symfony/intl/zipball/a0ba7a400e4c915500762c998355bea219a32d6b",
+                "reference": "a0ba7a400e4c915500762c998355bea219a32d6b",
                 "shasum": ""
             },
             "require": {
@@ -4700,7 +4694,7 @@
                 "localization"
             ],
             "support": {
-                "source": "https://github.com/symfony/intl/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/intl/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -4716,7 +4710,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-08T07:22:49+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/mercure",
@@ -4887,22 +4881,22 @@
         },
         {
             "name": "symfony/mercure-notifier",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mercure-notifier.git",
-                "reference": "790a1d45ec6efe644aa7a136ccedadc2023f6985"
+                "reference": "8580a527487ac171445cc46a7dc4ef878333c2c4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mercure-notifier/zipball/790a1d45ec6efe644aa7a136ccedadc2023f6985",
-                "reference": "790a1d45ec6efe644aa7a136ccedadc2023f6985",
+                "url": "https://api.github.com/repos/symfony/mercure-notifier/zipball/8580a527487ac171445cc46a7dc4ef878333c2c4",
+                "reference": "8580a527487ac171445cc46a7dc4ef878333c2c4",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.2",
                 "symfony/mercure": "^0.5.2|^0.6",
-                "symfony/notifier": "^7.2",
+                "symfony/notifier": "^6.4|^7.0",
                 "symfony/service-contracts": "^2.5|^3"
             },
             "type": "symfony-notifier-bridge",
@@ -4935,7 +4929,7 @@
                 "notifier"
             ],
             "support": {
-                "source": "https://github.com/symfony/mercure-notifier/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/mercure-notifier/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -4951,20 +4945,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-27T08:38:14+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/mime",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/mime.git",
-                "reference": "e57faea55d255c31b0899f0130c7d9da65fa2ec7"
+                "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/mime/zipball/e57faea55d255c31b0899f0130c7d9da65fa2ec7",
-                "reference": "e57faea55d255c31b0899f0130c7d9da65fa2ec7",
+                "url": "https://api.github.com/repos/symfony/mime/zipball/711d2e167e8ce65b05aea6b258c449671cdd38ff",
+                "reference": "711d2e167e8ce65b05aea6b258c449671cdd38ff",
                 "shasum": ""
             },
             "require": {
@@ -5019,7 +5013,7 @@
                 "mime-type"
             ],
             "support": {
-                "source": "https://github.com/symfony/mime/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/mime/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -5035,20 +5029,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/monolog-bridge",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/monolog-bridge.git",
-                "reference": "bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d"
+                "reference": "727be11ae17bb1c5a7f600753b9a1bf0cc0ec3b8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d",
-                "reference": "bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d",
+                "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/727be11ae17bb1c5a7f600753b9a1bf0cc0ec3b8",
+                "reference": "727be11ae17bb1c5a7f600753b9a1bf0cc0ec3b8",
                 "shasum": ""
             },
             "require": {
@@ -5097,7 +5091,7 @@
             "description": "Provides integration for Monolog with various Symfony components",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/monolog-bridge/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/monolog-bridge/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -5113,20 +5107,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-14T18:16:08+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/monolog-bundle",
-            "version": "v3.10.0",
+            "version": "dev-master",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/monolog-bundle.git",
-                "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181"
+                "reference": "ed0e4a287282971d110fd8c99d9ac391559a43ce"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181",
-                "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181",
+                "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/ed0e4a287282971d110fd8c99d9ac391559a43ce",
+                "reference": "ed0e4a287282971d110fd8c99d9ac391559a43ce",
                 "shasum": ""
             },
             "require": {
@@ -5139,9 +5133,10 @@
             },
             "require-dev": {
                 "symfony/console": "^5.4 || ^6.0 || ^7.0",
-                "symfony/phpunit-bridge": "^6.3 || ^7.0",
+                "symfony/phpunit-bridge": "^7.1",
                 "symfony/yaml": "^5.4 || ^6.0 || ^7.0"
             },
+            "default-branch": true,
             "type": "symfony-bundle",
             "extra": {
                 "branch-alias": {
@@ -5178,7 +5173,7 @@
             ],
             "support": {
                 "issues": "https://github.com/symfony/monolog-bundle/issues",
-                "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0"
+                "source": "https://github.com/symfony/monolog-bundle/tree/master"
             },
             "funding": [
                 {
@@ -5194,20 +5189,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-11-06T17:08:13+00:00"
+            "time": "2024-08-06T10:03:39+00:00"
         },
         {
             "name": "symfony/notifier",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/notifier.git",
-                "reference": "1a2a1639d102add41aa6896ff683cc05e3d52197"
+                "reference": "843946b0b1018ddc714b467f223607c71f9f6c8f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/notifier/zipball/1a2a1639d102add41aa6896ff683cc05e3d52197",
-                "reference": "1a2a1639d102add41aa6896ff683cc05e3d52197",
+                "url": "https://api.github.com/repos/symfony/notifier/zipball/843946b0b1018ddc714b467f223607c71f9f6c8f",
+                "reference": "843946b0b1018ddc714b467f223607c71f9f6c8f",
                 "shasum": ""
             },
             "require": {
@@ -5256,7 +5251,7 @@
                 "notifier"
             ],
             "support": {
-                "source": "https://github.com/symfony/notifier/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/notifier/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -5272,20 +5267,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-17T20:56:22+00:00"
+            "time": "2024-09-08T12:32:26+00:00"
         },
         {
             "name": "symfony/options-resolver",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/options-resolver.git",
-                "reference": "4f69e6b9745493ea38e5ffdc937e41e7145aa04c"
+                "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4f69e6b9745493ea38e5ffdc937e41e7145aa04c",
-                "reference": "4f69e6b9745493ea38e5ffdc937e41e7145aa04c",
+                "url": "https://api.github.com/repos/symfony/options-resolver/zipball/47aa818121ed3950acd2b58d1d37d08a94f9bf55",
+                "reference": "47aa818121ed3950acd2b58d1d37d08a94f9bf55",
                 "shasum": ""
             },
             "require": {
@@ -5323,7 +5318,7 @@
                 "options"
             ],
             "support": {
-                "source": "https://github.com/symfony/options-resolver/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/options-resolver/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -5339,7 +5334,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/polyfill-intl-grapheme",
@@ -5828,16 +5823,16 @@
         },
         {
             "name": "symfony/process",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "2ad775b9f17c8c9c1fe457750ce191e0f7c1fbff"
+                "reference": "5c03ee6369281177f07f7c68252a280beccba847"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/2ad775b9f17c8c9c1fe457750ce191e0f7c1fbff",
-                "reference": "2ad775b9f17c8c9c1fe457750ce191e0f7c1fbff",
+                "url": "https://api.github.com/repos/symfony/process/zipball/5c03ee6369281177f07f7c68252a280beccba847",
+                "reference": "5c03ee6369281177f07f7c68252a280beccba847",
                 "shasum": ""
             },
             "require": {
@@ -5869,7 +5864,7 @@
             "description": "Executes commands in sub-processes",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/process/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/process/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -5885,20 +5880,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-26T08:57:56+00:00"
+            "time": "2024-09-19T21:48:23+00:00"
         },
         {
             "name": "symfony/property-access",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/property-access.git",
-                "reference": "3ae42efba01e45aaedecf5c93c8d6a3ab3a82276"
+                "reference": "6c709f97103355016e5782d0622437ae381012ad"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/property-access/zipball/3ae42efba01e45aaedecf5c93c8d6a3ab3a82276",
-                "reference": "3ae42efba01e45aaedecf5c93c8d6a3ab3a82276",
+                "url": "https://api.github.com/repos/symfony/property-access/zipball/6c709f97103355016e5782d0622437ae381012ad",
+                "reference": "6c709f97103355016e5782d0622437ae381012ad",
                 "shasum": ""
             },
             "require": {
@@ -5945,7 +5940,7 @@
                 "reflection"
             ],
             "support": {
-                "source": "https://github.com/symfony/property-access/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/property-access/tree/v7.1.4"
             },
             "funding": [
                 {
@@ -5961,20 +5956,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-26T12:28:35+00:00"
+            "time": "2024-08-30T16:12:47+00:00"
         },
         {
             "name": "symfony/property-info",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/property-info.git",
-                "reference": "f8c1e96378984c4ae72caa2e304728999d2fd580"
+                "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/property-info/zipball/f8c1e96378984c4ae72caa2e304728999d2fd580",
-                "reference": "f8c1e96378984c4ae72caa2e304728999d2fd580",
+                "url": "https://api.github.com/repos/symfony/property-info/zipball/88a279df2db5b7919cac6f35d6a5d1d7147e6a9b",
+                "reference": "88a279df2db5b7919cac6f35d6a5d1d7147e6a9b",
                 "shasum": ""
             },
             "require": {
@@ -6029,7 +6024,7 @@
                 "validator"
             ],
             "support": {
-                "source": "https://github.com/symfony/property-info/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/property-info/tree/v7.1.3"
             },
             "funding": [
                 {
@@ -6045,20 +6040,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-03T09:19:10+00:00"
+            "time": "2024-07-26T07:36:36+00:00"
         },
         {
             "name": "symfony/routing",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "b9f47730638e96d6ff26f84bd4a7e89073d15634"
+                "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/b9f47730638e96d6ff26f84bd4a7e89073d15634",
-                "reference": "b9f47730638e96d6ff26f84bd4a7e89073d15634",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/1500aee0094a3ce1c92626ed8cf3c2037e86f5a7",
+                "reference": "1500aee0094a3ce1c92626ed8cf3c2037e86f5a7",
                 "shasum": ""
             },
             "require": {
@@ -6110,7 +6105,7 @@
                 "url"
             ],
             "support": {
-                "source": "https://github.com/symfony/routing/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/routing/tree/v7.1.4"
             },
             "funding": [
                 {
@@ -6126,20 +6121,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-03T12:20:01+00:00"
+            "time": "2024-08-29T08:16:25+00:00"
         },
         {
             "name": "symfony/runtime",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/runtime.git",
-                "reference": "049a9f3bebe7d4d9572e3d4a86f0fb7fe24fb077"
+                "reference": "ea34522c447dd91a2b31cb330ee4540a56ba53f6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/runtime/zipball/049a9f3bebe7d4d9572e3d4a86f0fb7fe24fb077",
-                "reference": "049a9f3bebe7d4d9572e3d4a86f0fb7fe24fb077",
+                "url": "https://api.github.com/repos/symfony/runtime/zipball/ea34522c447dd91a2b31cb330ee4540a56ba53f6",
+                "reference": "ea34522c447dd91a2b31cb330ee4540a56ba53f6",
                 "shasum": ""
             },
             "require": {
@@ -6189,7 +6184,7 @@
                 "runtime"
             ],
             "support": {
-                "source": "https://github.com/symfony/runtime/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/runtime/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -6205,20 +6200,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:55:39+00:00"
         },
         {
             "name": "symfony/serializer",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/serializer.git",
-                "reference": "56bcd41f8e8792b15ca363b730e26c7c536a7873"
+                "reference": "71d6e1f70f00752d1469d0f5e83b0a51716f288b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/serializer/zipball/56bcd41f8e8792b15ca363b730e26c7c536a7873",
-                "reference": "56bcd41f8e8792b15ca363b730e26c7c536a7873",
+                "url": "https://api.github.com/repos/symfony/serializer/zipball/71d6e1f70f00752d1469d0f5e83b0a51716f288b",
+                "reference": "71d6e1f70f00752d1469d0f5e83b0a51716f288b",
                 "shasum": ""
             },
             "require": {
@@ -6244,7 +6239,7 @@
                 "symfony/cache": "^6.4|^7.0",
                 "symfony/config": "^6.4|^7.0",
                 "symfony/console": "^6.4|^7.0",
-                "symfony/dependency-injection": "^7.2",
+                "symfony/dependency-injection": "^6.4|^7.0",
                 "symfony/error-handler": "^6.4|^7.0",
                 "symfony/filesystem": "^6.4|^7.0",
                 "symfony/form": "^6.4|^7.0",
@@ -6288,7 +6283,7 @@
             "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/serializer/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/serializer/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -6304,7 +6299,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-22T19:37:21+00:00"
+            "time": "2024-09-20T12:13:15+00:00"
         },
         {
             "name": "symfony/service-contracts",
@@ -6395,12 +6390,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/stimulus-bundle.git",
-                "reference": "2dc5431fd4fd84662615b435af7a0a6affd94f2d"
+                "reference": "e5f7747b514865719e0990389ce35a9b71bebb48"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/2dc5431fd4fd84662615b435af7a0a6affd94f2d",
-                "reference": "2dc5431fd4fd84662615b435af7a0a6affd94f2d",
+                "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/e5f7747b514865719e0990389ce35a9b71bebb48",
+                "reference": "e5f7747b514865719e0990389ce35a9b71bebb48",
                 "shasum": ""
             },
             "require": {
@@ -6441,7 +6436,7 @@
                 "symfony-ux"
             ],
             "support": {
-                "source": "https://github.com/symfony/stimulus-bundle/tree/2.x"
+                "source": "https://github.com/symfony/stimulus-bundle/tree/v2.21.0"
             },
             "funding": [
                 {
@@ -6457,20 +6452,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-28T11:18:16+00:00"
+            "time": "2024-10-05T22:11:16+00:00"
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/stopwatch.git",
-                "reference": "696f418b0d722a4225e1c3d95489d262971ca924"
+                "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/696f418b0d722a4225e1c3d95489d262971ca924",
-                "reference": "696f418b0d722a4225e1c3d95489d262971ca924",
+                "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d",
+                "reference": "5b75bb1ac2ba1b9d05c47fc4b3046a625377d23d",
                 "shasum": ""
             },
             "require": {
@@ -6503,7 +6498,7 @@
             "description": "Provides a way to profile code",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/stopwatch/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/stopwatch/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -6519,20 +6514,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/string",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/string.git",
-                "reference": "205580699b4d3e11f7b679faf2c0f57ffca6981c"
+                "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/string/zipball/205580699b4d3e11f7b679faf2c0f57ffca6981c",
-                "reference": "205580699b4d3e11f7b679faf2c0f57ffca6981c",
+                "url": "https://api.github.com/repos/symfony/string/zipball/d66f9c343fa894ec2037cc928381df90a7ad4306",
+                "reference": "d66f9c343fa894ec2037cc928381df90a7ad4306",
                 "shasum": ""
             },
             "require": {
@@ -6590,7 +6585,7 @@
                 "utf8"
             ],
             "support": {
-                "source": "https://github.com/symfony/string/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/string/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -6606,25 +6601,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "f1faf9a381d39d0bf8ca1c10cab7dcf41fba50dc"
+                "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/f1faf9a381d39d0bf8ca1c10cab7dcf41fba50dc",
-                "reference": "f1faf9a381d39d0bf8ca1c10cab7dcf41fba50dc",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/235535e3f84f3dfbdbde0208ede6ca75c3a489ea",
+                "reference": "235535e3f84f3dfbdbde0208ede6ca75c3a489ea",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.2",
-                "symfony/deprecation-contracts": "^2.5|^3",
                 "symfony/polyfill-mbstring": "~1.0",
                 "symfony/translation-contracts": "^2.5|^3.0"
             },
@@ -6685,7 +6679,7 @@
             "description": "Provides tools to internationalize your application",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/translation/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/translation/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -6701,7 +6695,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-16T06:30:38+00:00"
         },
         {
             "name": "symfony/translation-contracts",
@@ -6783,23 +6777,22 @@
         },
         {
             "name": "symfony/twig-bridge",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/twig-bridge.git",
-                "reference": "a5d88e50935a998eb84495098f2d1e3aa75de627"
+                "reference": "e997e5025b53c0f7b17632802daefdd6a04540ae"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/a5d88e50935a998eb84495098f2d1e3aa75de627",
-                "reference": "a5d88e50935a998eb84495098f2d1e3aa75de627",
+                "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/e997e5025b53c0f7b17632802daefdd6a04540ae",
+                "reference": "e997e5025b53c0f7b17632802daefdd6a04540ae",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.2",
-                "symfony/deprecation-contracts": "^2.5|^3",
                 "symfony/translation-contracts": "^2.5|^3",
-                "twig/twig": "^3.12"
+                "twig/twig": "^3.9"
             },
             "conflict": {
                 "phpdocumentor/reflection-docblock": "<3.2.2",
@@ -6873,7 +6866,7 @@
             "description": "Provides integration for Twig with various Symfony components",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/twig-bridge/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/twig-bridge/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -6889,20 +6882,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T16:06:58+00:00"
+            "time": "2024-09-15T06:48:17+00:00"
         },
         {
             "name": "symfony/twig-bundle",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/twig-bundle.git",
-                "reference": "cd2be4563afaef5285bb6e0a06c5445e644a5c01"
+                "reference": "4e6afd0dc8396f16861b682f3b854ff6e24bfb7e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/cd2be4563afaef5285bb6e0a06c5445e644a5c01",
-                "reference": "cd2be4563afaef5285bb6e0a06c5445e644a5c01",
+                "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/4e6afd0dc8396f16861b682f3b854ff6e24bfb7e",
+                "reference": "4e6afd0dc8396f16861b682f3b854ff6e24bfb7e",
                 "shasum": ""
             },
             "require": {
@@ -6913,7 +6906,7 @@
                 "symfony/http-foundation": "^6.4|^7.0",
                 "symfony/http-kernel": "^6.4|^7.0",
                 "symfony/twig-bridge": "^6.4|^7.0",
-                "twig/twig": "^3.12"
+                "twig/twig": "^3.0.4"
             },
             "conflict": {
                 "symfony/framework-bundle": "<6.4",
@@ -6957,7 +6950,7 @@
             "description": "Provides a tight integration of Twig into the Symfony full-stack framework",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/twig-bundle/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/twig-bundle/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -6973,20 +6966,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T08:11:15+00:00"
+            "time": "2024-09-08T12:32:26+00:00"
         },
         {
             "name": "symfony/type-info",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/type-info.git",
-                "reference": "fdac72a37de68564ff83ea2c2a3e9b0b2245d3bd"
+                "reference": "9f6094aa900d2c06bd61576a6f279d4ac441515f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/type-info/zipball/fdac72a37de68564ff83ea2c2a3e9b0b2245d3bd",
-                "reference": "fdac72a37de68564ff83ea2c2a3e9b0b2245d3bd",
+                "url": "https://api.github.com/repos/symfony/type-info/zipball/9f6094aa900d2c06bd61576a6f279d4ac441515f",
+                "reference": "9f6094aa900d2c06bd61576a6f279d4ac441515f",
                 "shasum": ""
             },
             "require": {
@@ -7039,7 +7032,7 @@
                 "type"
             ],
             "support": {
-                "source": "https://github.com/symfony/type-info/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/type-info/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -7055,20 +7048,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-09-19T21:48:23+00:00"
         },
         {
             "name": "symfony/uid",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/uid.git",
-                "reference": "2d294d0c48df244c71c105a169d0190bfb080426"
+                "reference": "8c7bb8acb933964055215d89f9a9871df0239317"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426",
-                "reference": "2d294d0c48df244c71c105a169d0190bfb080426",
+                "url": "https://api.github.com/repos/symfony/uid/zipball/8c7bb8acb933964055215d89f9a9871df0239317",
+                "reference": "8c7bb8acb933964055215d89f9a9871df0239317",
                 "shasum": ""
             },
             "require": {
@@ -7113,7 +7106,7 @@
                 "uuid"
             ],
             "support": {
-                "source": "https://github.com/symfony/uid/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/uid/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -7129,7 +7122,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-09-17T09:16:35+00:00"
         },
         {
             "name": "symfony/ux-autocomplete",
@@ -7137,12 +7130,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/ux-autocomplete.git",
-                "reference": "c1681c9b8fc3aa09657e02b8842be69102918a89"
+                "reference": "357a4b8eef612b279568292a878e60b8b0992413"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/c1681c9b8fc3aa09657e02b8842be69102918a89",
-                "reference": "c1681c9b8fc3aa09657e02b8842be69102918a89",
+                "url": "https://api.github.com/repos/symfony/ux-autocomplete/zipball/357a4b8eef612b279568292a878e60b8b0992413",
+                "reference": "357a4b8eef612b279568292a878e60b8b0992413",
                 "shasum": ""
             },
             "require": {
@@ -7204,7 +7197,7 @@
                 "symfony-ux"
             ],
             "support": {
-                "source": "https://github.com/symfony/ux-autocomplete/tree/2.x"
+                "source": "https://github.com/symfony/ux-autocomplete/tree/v2.21.0"
             },
             "funding": [
                 {
@@ -7220,7 +7213,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-24T09:16:33+00:00"
+            "time": "2024-10-21T19:02:15+00:00"
         },
         {
             "name": "symfony/ux-chartjs",
@@ -7475,12 +7468,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/ux-icons.git",
-                "reference": "b409bc7427957ba931589d16f42c145eeb4fb148"
+                "reference": "c3b3fd29b3f90e977b267251ef15ea06f3cec553"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/ux-icons/zipball/b409bc7427957ba931589d16f42c145eeb4fb148",
-                "reference": "b409bc7427957ba931589d16f42c145eeb4fb148",
+                "url": "https://api.github.com/repos/symfony/ux-icons/zipball/c3b3fd29b3f90e977b267251ef15ea06f3cec553",
+                "reference": "c3b3fd29b3f90e977b267251ef15ea06f3cec553",
                 "shasum": ""
             },
             "require": {
@@ -7541,7 +7534,7 @@
                 "twig"
             ],
             "support": {
-                "source": "https://github.com/symfony/ux-icons/tree/2.x"
+                "source": "https://github.com/symfony/ux-icons/tree/v2.21.0"
             },
             "funding": [
                 {
@@ -7557,7 +7550,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-31T16:56:54+00:00"
+            "time": "2024-10-21T19:01:22+00:00"
         },
         {
             "name": "symfony/ux-lazy-image",
@@ -7715,17 +7708,16 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/ux-live-component.git",
-                "reference": "b1727573b4bff5821958306c6360668aac82f6d3"
+                "reference": "1cc963a50a31a8ca92fbd145b29b27231b199b1b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/ux-live-component/zipball/b1727573b4bff5821958306c6360668aac82f6d3",
-                "reference": "b1727573b4bff5821958306c6360668aac82f6d3",
+                "url": "https://api.github.com/repos/symfony/ux-live-component/zipball/1cc963a50a31a8ca92fbd145b29b27231b199b1b",
+                "reference": "1cc963a50a31a8ca92fbd145b29b27231b199b1b",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.1",
-                "symfony/deprecation-contracts": "^2.5|^3.0",
                 "symfony/property-access": "^5.4.5|^6.0|^7.0",
                 "symfony/stimulus-bundle": "^2.9",
                 "symfony/ux-twig-component": "^2.8",
@@ -7786,7 +7778,7 @@
                 "twig"
             ],
             "support": {
-                "source": "https://github.com/symfony/ux-live-component/tree/2.x"
+                "source": "https://github.com/symfony/ux-live-component/tree/v2.21.0"
             },
             "funding": [
                 {
@@ -7802,7 +7794,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-31T16:39:49+00:00"
+            "time": "2024-10-15T10:36:54+00:00"
         },
         {
             "name": "symfony/ux-map",
@@ -8360,12 +8352,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/ux-turbo.git",
-                "reference": "add0a143c032a482c07c8d5e8776270973491abd"
+                "reference": "075c609e54fc421c6b1c1974e46e9a8b2d44277c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/ux-turbo/zipball/add0a143c032a482c07c8d5e8776270973491abd",
-                "reference": "add0a143c032a482c07c8d5e8776270973491abd",
+                "url": "https://api.github.com/repos/symfony/ux-turbo/zipball/075c609e54fc421c6b1c1974e46e9a8b2d44277c",
+                "reference": "075c609e54fc421c6b1c1974e46e9a8b2d44277c",
                 "shasum": ""
             },
             "require": {
@@ -8435,7 +8427,7 @@
                 "turbo-stream"
             ],
             "support": {
-                "source": "https://github.com/symfony/ux-turbo/tree/2.x"
+                "source": "https://github.com/symfony/ux-turbo/tree/v2.21.0"
             },
             "funding": [
                 {
@@ -8451,7 +8443,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-30T20:05:58+00:00"
+            "time": "2024-10-21T19:07:02+00:00"
         },
         {
             "name": "symfony/ux-twig-component",
@@ -8459,12 +8451,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/ux-twig-component.git",
-                "reference": "da12467494cbf4adc91384f7ace7063e315b7445"
+                "reference": "5b60b239fffcb04fc8bdb2a5a4001d19442d575d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/da12467494cbf4adc91384f7ace7063e315b7445",
-                "reference": "da12467494cbf4adc91384f7ace7063e315b7445",
+                "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/5b60b239fffcb04fc8bdb2a5a4001d19442d575d",
+                "reference": "5b60b239fffcb04fc8bdb2a5a4001d19442d575d",
                 "shasum": ""
             },
             "require": {
@@ -8519,7 +8511,7 @@
                 "twig"
             ],
             "support": {
-                "source": "https://github.com/symfony/ux-twig-component/tree/2.x"
+                "source": "https://github.com/symfony/ux-twig-component/tree/v2.21.0"
             },
             "funding": [
                 {
@@ -8535,7 +8527,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-11-01T06:57:32+00:00"
+            "time": "2024-10-05T22:11:16+00:00"
         },
         {
             "name": "symfony/ux-typed",
@@ -8688,16 +8680,16 @@
         },
         {
             "name": "symfony/validator",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/validator.git",
-                "reference": "8392b9bafbfed3c166a979ac0bd8a3186abb8e75"
+                "reference": "e57592782dc2a86997477f28164c51af53512ad8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/validator/zipball/8392b9bafbfed3c166a979ac0bd8a3186abb8e75",
-                "reference": "8392b9bafbfed3c166a979ac0bd8a3186abb8e75",
+                "url": "https://api.github.com/repos/symfony/validator/zipball/e57592782dc2a86997477f28164c51af53512ad8",
+                "reference": "e57592782dc2a86997477f28164c51af53512ad8",
                 "shasum": ""
             },
             "require": {
@@ -8765,7 +8757,7 @@
             "description": "Provides tools to validate values",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/validator/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/validator/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -8781,20 +8773,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-09-20T08:28:38+00:00"
         },
         {
             "name": "symfony/var-dumper",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-dumper.git",
-                "reference": "b86ce1b5bb196cfb3796856979167271d3989c7c"
+                "reference": "e20e03889539fd4e4211e14d2179226c513c010d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b86ce1b5bb196cfb3796856979167271d3989c7c",
-                "reference": "b86ce1b5bb196cfb3796856979167271d3989c7c",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e20e03889539fd4e4211e14d2179226c513c010d",
+                "reference": "e20e03889539fd4e4211e14d2179226c513c010d",
                 "shasum": ""
             },
             "require": {
@@ -8810,7 +8802,7 @@
                 "symfony/http-kernel": "^6.4|^7.0",
                 "symfony/process": "^6.4|^7.0",
                 "symfony/uid": "^6.4|^7.0",
-                "twig/twig": "^3.12"
+                "twig/twig": "^3.0.4"
             },
             "bin": [
                 "Resources/bin/var-dump-server"
@@ -8848,7 +8840,7 @@
                 "dump"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-dumper/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/var-dumper/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -8864,20 +8856,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T08:11:15+00:00"
+            "time": "2024-09-16T10:07:02+00:00"
         },
         {
             "name": "symfony/var-exporter",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/var-exporter.git",
-                "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d"
+                "reference": "b80a669a2264609f07f1667f891dbfca25eba44c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d",
-                "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d",
+                "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b80a669a2264609f07f1667f891dbfca25eba44c",
+                "reference": "b80a669a2264609f07f1667f891dbfca25eba44c",
                 "shasum": ""
             },
             "require": {
@@ -8924,7 +8916,7 @@
                 "serialize"
             ],
             "support": {
-                "source": "https://github.com/symfony/var-exporter/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/var-exporter/tree/v7.1.2"
             },
             "funding": [
                 {
@@ -8940,20 +8932,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-18T07:58:17+00:00"
+            "time": "2024-06-28T08:00:31+00:00"
         },
         {
             "name": "symfony/web-link",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/web-link.git",
-                "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532"
+                "reference": "63f90aa0054bfd9a091d2f5cf465958f1030638f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/web-link/zipball/f537556a885e14a1d28f6c759d41e57e93d0a532",
-                "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532",
+                "url": "https://api.github.com/repos/symfony/web-link/zipball/63f90aa0054bfd9a091d2f5cf465958f1030638f",
+                "reference": "63f90aa0054bfd9a091d2f5cf465958f1030638f",
                 "shasum": ""
             },
             "require": {
@@ -9007,7 +8999,7 @@
                 "push"
             ],
             "support": {
-                "source": "https://github.com/symfony/web-link/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/web-link/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -9023,25 +9015,24 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "099581e99f557e9f16b43c5916c26380b54abb22"
+                "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22",
-                "reference": "099581e99f557e9f16b43c5916c26380b54abb22",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/4e561c316e135e053bd758bf3b3eb291d9919de4",
+                "reference": "4e561c316e135e053bd758bf3b3eb291d9919de4",
                 "shasum": ""
             },
             "require": {
                 "php": ">=8.2",
-                "symfony/deprecation-contracts": "^2.5|^3.0",
                 "symfony/polyfill-ctype": "^1.8"
             },
             "conflict": {
@@ -9079,7 +9070,7 @@
             "description": "Loads and dumps YAML files",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/yaml/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/yaml/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -9095,7 +9086,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:56:12+00:00"
+            "time": "2024-09-17T12:49:58+00:00"
         },
         {
             "name": "symfonycasts/dynamic-forms",
@@ -9153,16 +9144,16 @@
         },
         {
             "name": "symfonycasts/sass-bundle",
-            "version": "v0.8.1",
+            "version": "v0.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/SymfonyCasts/sass-bundle.git",
-                "reference": "4637a176b5adfb03f83c409c3f9f566e30426318"
+                "reference": "aa47da8ae43136a21a764eedb1471f2a168359cb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/SymfonyCasts/sass-bundle/zipball/4637a176b5adfb03f83c409c3f9f566e30426318",
-                "reference": "4637a176b5adfb03f83c409c3f9f566e30426318",
+                "url": "https://api.github.com/repos/SymfonyCasts/sass-bundle/zipball/aa47da8ae43136a21a764eedb1471f2a168359cb",
+                "reference": "aa47da8ae43136a21a764eedb1471f2a168359cb",
                 "shasum": ""
             },
             "require": {
@@ -9175,9 +9166,9 @@
             },
             "require-dev": {
                 "matthiasnoback/symfony-config-test": "^5.0",
-                "phpunit/phpunit": "^9.6",
+                "phpstan/phpstan-symfony": "^1.4",
                 "symfony/framework-bundle": "^6.3|^7.0",
-                "symfony/phpunit-bridge": "^6.3.9|^7.0"
+                "symfony/phpunit-bridge": "^6.3|^7.0"
             },
             "type": "library",
             "autoload": {
@@ -9202,22 +9193,22 @@
             ],
             "support": {
                 "issues": "https://github.com/SymfonyCasts/sass-bundle/issues",
-                "source": "https://github.com/SymfonyCasts/sass-bundle/tree/v0.8.1"
+                "source": "https://github.com/SymfonyCasts/sass-bundle/tree/v0.6.0"
             },
-            "time": "2024-10-17T10:46:06+00:00"
+            "time": "2024-02-26T10:09:48+00:00"
         },
         {
             "name": "tempest/highlight",
-            "version": "2.10.6",
+            "version": "2.10.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/tempestphp/highlight.git",
-                "reference": "00ef935cc68b1b1ba68ffb09e91a810e42ca4e9d"
+                "reference": "2d119afdac7aa98927dbbcf239e5cff86b74faf0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/tempestphp/highlight/zipball/00ef935cc68b1b1ba68ffb09e91a810e42ca4e9d",
-                "reference": "00ef935cc68b1b1ba68ffb09e91a810e42ca4e9d",
+                "url": "https://api.github.com/repos/tempestphp/highlight/zipball/2d119afdac7aa98927dbbcf239e5cff86b74faf0",
+                "reference": "2d119afdac7aa98927dbbcf239e5cff86b74faf0",
                 "shasum": ""
             },
             "require": {
@@ -9254,7 +9245,7 @@
             "description": "Fast, extensible, server-side code highlighting",
             "support": {
                 "issues": "https://github.com/tempestphp/highlight/issues",
-                "source": "https://github.com/tempestphp/highlight/tree/2.10.6"
+                "source": "https://github.com/tempestphp/highlight/tree/2.10.5"
             },
             "funding": [
                 {
@@ -9262,7 +9253,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-10-24T06:44:39+00:00"
+            "time": "2024-10-20T04:44:15+00:00"
         },
         {
             "name": "twbs/bootstrap",
@@ -9742,16 +9733,16 @@
     "packages-dev": [
         {
             "name": "behat/mink",
-            "version": "v1.12.0",
+            "version": "v1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/minkphp/Mink.git",
-                "reference": "7e4edec6c335937029cb3569ce7ef81182804d0a"
+                "reference": "d8527fdf8785aad38455fb426af457ab9937aece"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/minkphp/Mink/zipball/7e4edec6c335937029cb3569ce7ef81182804d0a",
-                "reference": "7e4edec6c335937029cb3569ce7ef81182804d0a",
+                "url": "https://api.github.com/repos/minkphp/Mink/zipball/d8527fdf8785aad38455fb426af457ab9937aece",
+                "reference": "d8527fdf8785aad38455fb426af457ab9937aece",
                 "shasum": ""
             },
             "require": {
@@ -9802,9 +9793,9 @@
             ],
             "support": {
                 "issues": "https://github.com/minkphp/Mink/issues",
-                "source": "https://github.com/minkphp/Mink/tree/v1.12.0"
+                "source": "https://github.com/minkphp/Mink/tree/v1.11.0"
             },
-            "time": "2024-10-30T18:48:14+00:00"
+            "time": "2023-12-09T11:23:23+00:00"
         },
         {
             "name": "fakerphp/faker",
@@ -11559,16 +11550,16 @@
         },
         {
             "name": "symfony/browser-kit",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/browser-kit.git",
-                "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94"
+                "reference": "9c13742e3175b5815e272b981876ae329bec2040"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/8d64d17e198082f8f198d023a6b634e7b5fdda94",
-                "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94",
+                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9c13742e3175b5815e272b981876ae329bec2040",
+                "reference": "9c13742e3175b5815e272b981876ae329bec2040",
                 "shasum": ""
             },
             "require": {
@@ -11607,7 +11598,7 @@
             "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/browser-kit/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/browser-kit/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -11623,20 +11614,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/css-selector",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2"
+                "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2",
-                "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
+                "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
                 "shasum": ""
             },
             "require": {
@@ -11672,7 +11663,7 @@
             "description": "Converts CSS selectors to XPath expressions",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/css-selector/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/css-selector/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -11688,20 +11679,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:57:53+00:00"
         },
         {
             "name": "symfony/debug-bundle",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug-bundle.git",
-                "reference": "2dade0d1415c08b627379b5ec214ec8424cb2e32"
+                "reference": "aa024d28ce7ce0c6a16ee57c066838bece92893f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/2dade0d1415c08b627379b5ec214ec8424cb2e32",
-                "reference": "2dade0d1415c08b627379b5ec214ec8424cb2e32",
+                "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/aa024d28ce7ce0c6a16ee57c066838bece92893f",
+                "reference": "aa024d28ce7ce0c6a16ee57c066838bece92893f",
                 "shasum": ""
             },
             "require": {
@@ -11746,7 +11737,7 @@
             "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/debug-bundle/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/debug-bundle/tree/v7.1.1"
             },
             "funding": [
                 {
@@ -11762,20 +11753,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-09-25T14:21:43+00:00"
+            "time": "2024-05-31T14:55:39+00:00"
         },
         {
             "name": "symfony/dom-crawler",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dom-crawler.git",
-                "reference": "3e838f9095f53f2b98287a361c1cdb68bbd3aa7b"
+                "reference": "b92af238457a7cdd2738f941cd525d76313e8283"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/3e838f9095f53f2b98287a361c1cdb68bbd3aa7b",
-                "reference": "3e838f9095f53f2b98287a361c1cdb68bbd3aa7b",
+                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b92af238457a7cdd2738f941cd525d76313e8283",
+                "reference": "b92af238457a7cdd2738f941cd525d76313e8283",
                 "shasum": ""
             },
             "require": {
@@ -11813,7 +11804,7 @@
             "description": "Eases DOM navigation for HTML and XML documents",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/dom-crawler/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/dom-crawler/tree/v7.1.5"
             },
             "funding": [
                 {
@@ -11829,7 +11820,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-25T15:15:23+00:00"
+            "time": "2024-09-15T06:48:17+00:00"
         },
         {
             "name": "symfony/maker-bundle",
@@ -11925,16 +11916,16 @@
         },
         {
             "name": "symfony/phpunit-bridge",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/phpunit-bridge.git",
-                "reference": "078398ebac9b707438286e8d689b30b5ef1e6602"
+                "reference": "e876eb90e32a8fc4c4911d458e09f88d65877d1c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/078398ebac9b707438286e8d689b30b5ef1e6602",
-                "reference": "078398ebac9b707438286e8d689b30b5ef1e6602",
+                "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e876eb90e32a8fc4c4911d458e09f88d65877d1c",
+                "reference": "e876eb90e32a8fc4c4911d458e09f88d65877d1c",
                 "shasum": ""
             },
             "require": {
@@ -11987,7 +11978,7 @@
             "description": "Provides utilities for PHPUnit, especially user deprecation notices management",
             "homepage": "https://symfony.com",
             "support": {
-                "source": "https://github.com/symfony/phpunit-bridge/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.4"
             },
             "funding": [
                 {
@@ -12003,20 +11994,20 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T06:50:56+00:00"
+            "time": "2024-08-13T14:28:19+00:00"
         },
         {
             "name": "symfony/web-profiler-bundle",
-            "version": "v7.2.0-BETA1",
+            "version": "v7.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/web-profiler-bundle.git",
-                "reference": "1827c2cf600a760334b4fbbc610a9fe308a3f73a"
+                "reference": "3cfc775277a8f2dacdd0f72d196bc87b272a763f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/1827c2cf600a760334b4fbbc610a9fe308a3f73a",
-                "reference": "1827c2cf600a760334b4fbbc610a9fe308a3f73a",
+                "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/3cfc775277a8f2dacdd0f72d196bc87b272a763f",
+                "reference": "3cfc775277a8f2dacdd0f72d196bc87b272a763f",
                 "shasum": ""
             },
             "require": {
@@ -12026,13 +12017,12 @@
                 "symfony/http-kernel": "^6.4|^7.0",
                 "symfony/routing": "^6.4|^7.0",
                 "symfony/twig-bundle": "^6.4|^7.0",
-                "twig/twig": "^3.12"
+                "twig/twig": "^3.10"
             },
             "conflict": {
                 "symfony/form": "<6.4",
                 "symfony/mailer": "<6.4",
-                "symfony/messenger": "<6.4",
-                "symfony/serializer": "<7.2"
+                "symfony/messenger": "<6.4"
             },
             "require-dev": {
                 "symfony/browser-kit": "^6.4|^7.0",
@@ -12069,7 +12059,7 @@
                 "dev"
             ],
             "support": {
-                "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.2.0-BETA1"
+                "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.1.4"
             },
             "funding": [
                 {
@@ -12085,7 +12075,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-10-23T08:11:15+00:00"
+            "time": "2024-08-12T09:59:40+00:00"
         },
         {
             "name": "theseer/tokenizer",
@@ -12277,16 +12267,16 @@
         },
         {
             "name": "zenstruck/assert",
-            "version": "v1.5.1",
+            "version": "v1.5.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/zenstruck/assert.git",
-                "reference": "39554ce3a275fbf8c870b251e620101f644e9277"
+                "reference": "60956bb6584a51c6c2ab9fa8707b7c013d770163"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/zenstruck/assert/zipball/39554ce3a275fbf8c870b251e620101f644e9277",
-                "reference": "39554ce3a275fbf8c870b251e620101f644e9277",
+                "url": "https://api.github.com/repos/zenstruck/assert/zipball/60956bb6584a51c6c2ab9fa8707b7c013d770163",
+                "reference": "60956bb6584a51c6c2ab9fa8707b7c013d770163",
                 "shasum": ""
             },
             "require": {
@@ -12296,8 +12286,8 @@
             },
             "require-dev": {
                 "phpstan/phpstan": "^1.4",
-                "phpunit/phpunit": "^9.5.21",
-                "symfony/phpunit-bridge": "^6.3|^7.0"
+                "phpunit/phpunit": "^9.5",
+                "symfony/phpunit-bridge": "^6.3"
             },
             "type": "library",
             "autoload": {
@@ -12324,7 +12314,7 @@
             ],
             "support": {
                 "issues": "https://github.com/zenstruck/assert/issues",
-                "source": "https://github.com/zenstruck/assert/tree/v1.5.1"
+                "source": "https://github.com/zenstruck/assert/tree/v1.5.0"
             },
             "funding": [
                 {
@@ -12332,7 +12322,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-10-28T18:08:12+00:00"
+            "time": "2023-12-02T09:08:04+00:00"
         },
         {
             "name": "zenstruck/browser",
@@ -12466,16 +12456,16 @@
         },
         {
             "name": "zenstruck/foundry",
-            "version": "v2.2.1",
+            "version": "v2.0.9",
             "source": {
                 "type": "git",
                 "url": "https://github.com/zenstruck/foundry.git",
-                "reference": "4743a9da142b42d484ac7a99c1a7068aa66c7bec"
+                "reference": "b0a5d3d8b43acd4b0f356c6dcfdec6c8ebff1c08"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/zenstruck/foundry/zipball/4743a9da142b42d484ac7a99c1a7068aa66c7bec",
-                "reference": "4743a9da142b42d484ac7a99c1a7068aa66c7bec",
+                "url": "https://api.github.com/repos/zenstruck/foundry/zipball/b0a5d3d8b43acd4b0f356c6dcfdec6c8ebff1c08",
+                "reference": "b0a5d3d8b43acd4b0f356c6dcfdec6c8ebff1c08",
                 "shasum": ""
             },
             "require": {
@@ -12512,9 +12502,6 @@
                     "target-directory": "bin/tools",
                     "bin-links": true,
                     "forward-command": false
-                },
-                "psalm": {
-                    "pluginClass": "Zenstruck\\Foundry\\Psalm\\FoundryPlugin"
                 }
             },
             "autoload": {
@@ -12524,8 +12511,7 @@
                     "src/phpunit_helper.php"
                 ],
                 "psr-4": {
-                    "Zenstruck\\Foundry\\": "src/",
-                    "Zenstruck\\Foundry\\Psalm\\": "utils/psalm"
+                    "Zenstruck\\Foundry\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -12555,7 +12541,7 @@
             ],
             "support": {
                 "issues": "https://github.com/zenstruck/foundry/issues",
-                "source": "https://github.com/zenstruck/foundry/tree/v2.2.1"
+                "source": "https://github.com/zenstruck/foundry/tree/v2.0.9"
             },
             "funding": [
                 {
@@ -12563,7 +12549,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2024-10-31T12:10:58+00:00"
+            "time": "2024-09-02T18:20:52+00:00"
         }
     ],
     "aliases": [],
diff --git a/ux.symfony.com/config/packages/symfonycasts_sass.yaml b/ux.symfony.com/config/packages/symfonycasts_sass.yaml
deleted file mode 100644
index 041d1e28..00000000
--- a/ux.symfony.com/config/packages/symfonycasts_sass.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-symfonycasts_sass:
-    sass_options:
-        style: compressed       
-        source_map: false       
-        quiet: true             # silence deprecation warnings
diff --git a/ux.symfony.com/config/packages/twig_component.yaml b/ux.symfony.com/config/packages/twig_component.yaml
index 388d533e..9322e147 100644
--- a/ux.symfony.com/config/packages/twig_component.yaml
+++ b/ux.symfony.com/config/packages/twig_component.yaml
@@ -1,10 +1,10 @@
 twig_component:
     defaults:
-        App\Twig\Components\: 'components/'
-        
-        # Custom namespace for MemoryDemo
+        App\Twig\: 'components/'
         App\LiveMemory\Component\:
             template_directory: 'demos/live_memory/components/LiveMemory/'
             name_prefix: 'LiveMemory:'
 
+
+    #anonymous_template_directory: 'demos/live_memory/components/'
     anonymous_template_directory: 'components/'
diff --git a/ux.symfony.com/src/Twig/Components/Alert.php b/ux.symfony.com/src/Twig/Alert.php
similarity index 94%
rename from ux.symfony.com/src/Twig/Components/Alert.php
rename to ux.symfony.com/src/Twig/Alert.php
index 00f8d8fc..f24dfcd4 100644
--- a/ux.symfony.com/src/Twig/Components/Alert.php
+++ b/ux.symfony.com/src/Twig/Alert.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
 
diff --git a/ux.symfony.com/src/Twig/Components/BootstrapModal.php b/ux.symfony.com/src/Twig/BootstrapModal.php
similarity index 92%
rename from ux.symfony.com/src/Twig/Components/BootstrapModal.php
rename to ux.symfony.com/src/Twig/BootstrapModal.php
index 51063999..96cf003c 100644
--- a/ux.symfony.com/src/Twig/Components/BootstrapModal.php
+++ b/ux.symfony.com/src/Twig/BootstrapModal.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
 
diff --git a/ux.symfony.com/src/Twig/Components/DinoChart.php b/ux.symfony.com/src/Twig/DinoChart.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/DinoChart.php
rename to ux.symfony.com/src/Twig/DinoChart.php
index ed4fc14b..1c49e80c 100644
--- a/ux.symfony.com/src/Twig/Components/DinoChart.php
+++ b/ux.symfony.com/src/Twig/DinoChart.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Service\DinoStatsService;
 use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
diff --git a/ux.symfony.com/src/Twig/Components/DocsLink.php b/ux.symfony.com/src/Twig/DocsLink.php
similarity index 95%
rename from ux.symfony.com/src/Twig/Components/DocsLink.php
rename to ux.symfony.com/src/Twig/DocsLink.php
index e057fa87..7dd6e75e 100644
--- a/ux.symfony.com/src/Twig/Components/DocsLink.php
+++ b/ux.symfony.com/src/Twig/DocsLink.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
 use Symfony\UX\TwigComponent\Attribute\ExposeInTemplate;
diff --git a/ux.symfony.com/src/Twig/Components/FoodVote.php b/ux.symfony.com/src/Twig/FoodVote.php
similarity index 97%
rename from ux.symfony.com/src/Twig/Components/FoodVote.php
rename to ux.symfony.com/src/Twig/FoodVote.php
index 40395daf..3822ba96 100644
--- a/ux.symfony.com/src/Twig/Components/FoodVote.php
+++ b/ux.symfony.com/src/Twig/FoodVote.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\Food;
 use App\Repository\FoodRepository;
diff --git a/ux.symfony.com/src/Twig/Components/HomepageTerminalSwapper.php b/ux.symfony.com/src/Twig/HomepageTerminalSwapper.php
similarity index 97%
rename from ux.symfony.com/src/Twig/Components/HomepageTerminalSwapper.php
rename to ux.symfony.com/src/Twig/HomepageTerminalSwapper.php
index b126bc5d..dca67b40 100644
--- a/ux.symfony.com/src/Twig/Components/HomepageTerminalSwapper.php
+++ b/ux.symfony.com/src/Twig/HomepageTerminalSwapper.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Model\UxPackage;
 use App\Service\UxPackageRepository;
diff --git a/ux.symfony.com/src/Twig/Components/InlineEditFood.php b/ux.symfony.com/src/Twig/InlineEditFood.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/InlineEditFood.php
rename to ux.symfony.com/src/Twig/InlineEditFood.php
index 2753be3b..5923ac94 100644
--- a/ux.symfony.com/src/Twig/Components/InlineEditFood.php
+++ b/ux.symfony.com/src/Twig/InlineEditFood.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\Food;
 use Doctrine\ORM\EntityManagerInterface;
diff --git a/ux.symfony.com/src/Twig/Components/InvoiceCreator.php b/ux.symfony.com/src/Twig/InvoiceCreator.php
similarity index 99%
rename from ux.symfony.com/src/Twig/Components/InvoiceCreator.php
rename to ux.symfony.com/src/Twig/InvoiceCreator.php
index 14c22561..eff32b28 100644
--- a/ux.symfony.com/src/Twig/Components/InvoiceCreator.php
+++ b/ux.symfony.com/src/Twig/InvoiceCreator.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\Invoice;
 use App\Entity\InvoiceItem;
diff --git a/ux.symfony.com/src/Twig/Components/InvoiceCreatorLineItem.php b/ux.symfony.com/src/Twig/InvoiceCreatorLineItem.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/InvoiceCreatorLineItem.php
rename to ux.symfony.com/src/Twig/InvoiceCreatorLineItem.php
index 660ce9de..105e6f3c 100644
--- a/ux.symfony.com/src/Twig/Components/InvoiceCreatorLineItem.php
+++ b/ux.symfony.com/src/Twig/InvoiceCreatorLineItem.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\Product;
 use App\Repository\ProductRepository;
diff --git a/ux.symfony.com/src/Twig/Components/MealPlanner.php b/ux.symfony.com/src/Twig/MealPlanner.php
similarity index 96%
rename from ux.symfony.com/src/Twig/Components/MealPlanner.php
rename to ux.symfony.com/src/Twig/MealPlanner.php
index 93db6133..30e5f6c7 100644
--- a/ux.symfony.com/src/Twig/Components/MealPlanner.php
+++ b/ux.symfony.com/src/Twig/MealPlanner.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Form\MealPlannerForm;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
diff --git a/ux.symfony.com/src/Twig/Components/NewCategoryForm.php b/ux.symfony.com/src/Twig/NewCategoryForm.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/NewCategoryForm.php
rename to ux.symfony.com/src/Twig/NewCategoryForm.php
index 7636e2b1..8f70d26c 100644
--- a/ux.symfony.com/src/Twig/Components/NewCategoryForm.php
+++ b/ux.symfony.com/src/Twig/NewCategoryForm.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\Category;
 use Doctrine\ORM\EntityManagerInterface;
diff --git a/ux.symfony.com/src/Twig/Components/NewProductForm.php b/ux.symfony.com/src/Twig/NewProductForm.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/NewProductForm.php
rename to ux.symfony.com/src/Twig/NewProductForm.php
index bb33fa4f..41e66df7 100644
--- a/ux.symfony.com/src/Twig/Components/NewProductForm.php
+++ b/ux.symfony.com/src/Twig/NewProductForm.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\Category;
 use App\Entity\Product;
diff --git a/ux.symfony.com/src/Twig/Components/ProductGrid.php b/ux.symfony.com/src/Twig/ProductGrid.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/ProductGrid.php
rename to ux.symfony.com/src/Twig/ProductGrid.php
index fa2a6eba..11793d2b 100644
--- a/ux.symfony.com/src/Twig/Components/ProductGrid.php
+++ b/ux.symfony.com/src/Twig/ProductGrid.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Service\EmojiCollection;
 use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
diff --git a/ux.symfony.com/src/Twig/Components/ProductGrid2.php b/ux.symfony.com/src/Twig/ProductGrid2.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/ProductGrid2.php
rename to ux.symfony.com/src/Twig/ProductGrid2.php
index a837bcdb..1a71ff36 100644
--- a/ux.symfony.com/src/Twig/Components/ProductGrid2.php
+++ b/ux.symfony.com/src/Twig/ProductGrid2.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Service\EmojiCollection;
 use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
diff --git a/ux.symfony.com/src/Twig/Components/RegistrationForm.php b/ux.symfony.com/src/Twig/RegistrationForm.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/RegistrationForm.php
rename to ux.symfony.com/src/Twig/RegistrationForm.php
index f7918900..8ce8733c 100644
--- a/ux.symfony.com/src/Twig/Components/RegistrationForm.php
+++ b/ux.symfony.com/src/Twig/RegistrationForm.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Form\RegistrationFormType;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
diff --git a/ux.symfony.com/src/Twig/Components/Terminal.php b/ux.symfony.com/src/Twig/Terminal.php
similarity index 95%
rename from ux.symfony.com/src/Twig/Components/Terminal.php
rename to ux.symfony.com/src/Twig/Terminal.php
index 6399b571..7e943b6f 100644
--- a/ux.symfony.com/src/Twig/Components/Terminal.php
+++ b/ux.symfony.com/src/Twig/Terminal.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Util\SourceCleaner;
 use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
diff --git a/ux.symfony.com/src/Twig/Components/TodoListForm.php b/ux.symfony.com/src/Twig/TodoListForm.php
similarity index 96%
rename from ux.symfony.com/src/Twig/Components/TodoListForm.php
rename to ux.symfony.com/src/Twig/TodoListForm.php
index 019bbd8f..165936f6 100644
--- a/ux.symfony.com/src/Twig/Components/TodoListForm.php
+++ b/ux.symfony.com/src/Twig/TodoListForm.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use App\Entity\TodoList;
 use App\Form\TodoListFormType;
diff --git a/ux.symfony.com/src/Twig/Components/UploadFiles.php b/ux.symfony.com/src/Twig/UploadFiles.php
similarity index 98%
rename from ux.symfony.com/src/Twig/Components/UploadFiles.php
rename to ux.symfony.com/src/Twig/UploadFiles.php
index 824ca5b7..ce59a21f 100644
--- a/ux.symfony.com/src/Twig/Components/UploadFiles.php
+++ b/ux.symfony.com/src/Twig/UploadFiles.php
@@ -9,7 +9,7 @@
  * file that was distributed with this source code.
  */
 
-namespace App\Twig\Components;
+namespace App\Twig;
 
 use Symfony\Component\HttpFoundation\File\UploadedFile;
 use Symfony\Component\HttpFoundation\Request;
diff --git a/ux.symfony.com/templates/components/FileTree.html.twig b/ux.symfony.com/templates/components/FileTree.html.twig
index 1f8bb94b..70519766 100644
--- a/ux.symfony.com/templates/components/FileTree.html.twig
+++ b/ux.symfony.com/templates/components/FileTree.html.twig
@@ -1,6 +1,6 @@
-<ul class="FileTree FileTree-main list-unstyled px-3">
+<div class="FileTree FileTree-main list-unstyled px-3">
     {{ _self.fileTree(files) }}
-</ul>
+</div>
 
 {% macro fileTree(files) %}
     {% for file_info in files %}
diff --git a/ux.symfony.com/templates/demos/live_component/auto_validating_form.html.twig b/ux.symfony.com/templates/demos/live_component/auto_validating_form.html.twig
index df3f0aff..4a1d8d2b 100644
--- a/ux.symfony.com/templates/demos/live_component/auto_validating_form.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/auto_validating_form.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/RegistrationForm.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/RegistrationForm.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/demos/live_component/bootstrap.html.twig b/ux.symfony.com/templates/demos/live_component/bootstrap.html.twig
index 0175c334..4c3f3715 100644
--- a/ux.symfony.com/templates/demos/live_component/bootstrap.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/bootstrap.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/TodoListForm.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/TodoListForm.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/demos/live_component/chartjs.html.twig b/ux.symfony.com/templates/demos/live_component/chartjs.html.twig
index f9b04b0d..58a8881e 100644
--- a/ux.symfony.com/templates/demos/live_component/chartjs.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/chartjs.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/DinoChart.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/DinoChart.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/demos/live_component/dependent_form_fields.html.twig b/ux.symfony.com/templates/demos/live_component/dependent_form_fields.html.twig
index 4ee03984..bbb69b83 100644
--- a/ux.symfony.com/templates/demos/live_component/dependent_form_fields.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/dependent_form_fields.html.twig
@@ -2,7 +2,7 @@
 
 {% block code_block_full %}
     <twig:Code:TabbedCodeBlocks :files="[
-        'src/Twig/Components/MealPlanner.php',
+        'src/Twig/MealPlanner.php',
         'templates/components/MealPlanner.html.twig',
         'src/Form/MealPlannerForm.php',
     ]" />
diff --git a/ux.symfony.com/templates/demos/live_component/form_collection_type.html.twig b/ux.symfony.com/templates/demos/live_component/form_collection_type.html.twig
index 0175c334..4c3f3715 100644
--- a/ux.symfony.com/templates/demos/live_component/form_collection_type.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/form_collection_type.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/TodoListForm.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/TodoListForm.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/demos/live_component/infinite_scroll.html.twig b/ux.symfony.com/templates/demos/live_component/infinite_scroll.html.twig
index fa9a634e..6bdf0dba 100644
--- a/ux.symfony.com/templates/demos/live_component/infinite_scroll.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/infinite_scroll.html.twig
@@ -26,7 +26,7 @@
 
     <section class="py-5" style="padding-top: 6rem;">
         <div class="container container-xxl">
-            <twig:Code:CodeWithExplanationRow filename="src/Twig/Components/ProductGrid.php" reversed sticky style="--bs-gutter-x: 4rem;">
+            <twig:Code:CodeWithExplanationRow filename="src/Twig/ProductGrid.php" reversed sticky style="--bs-gutter-x: 4rem;">
 This component is quite standard: the page number as a `LiveProp`, a `LiveAction`
 to load the next page, and a `getItems` method to retrieve the page results.
 
diff --git a/ux.symfony.com/templates/demos/live_component/inline_edit.html.twig b/ux.symfony.com/templates/demos/live_component/inline_edit.html.twig
index 233b68f6..2a7628d2 100644
--- a/ux.symfony.com/templates/demos/live_component/inline_edit.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/inline_edit.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/InlineEditFood.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/InlineEditFood.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/demos/live_component/invoice.html.twig b/ux.symfony.com/templates/demos/live_component/invoice.html.twig
index 9d9340b3..b4c54257 100644
--- a/ux.symfony.com/templates/demos/live_component/invoice.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/invoice.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_full %}
-    <twig:Code:CodeWithExplanationRow filename="src/Twig/Components/InvoiceCreator.php" sticky class="pt-5">
+    <twig:Code:CodeWithExplanationRow filename="src/Twig/InvoiceCreator.php" sticky class="pt-5">
 ## Main Component
 
 This main component keeps track of the `Invoice` (which may be new) and
@@ -30,7 +30,7 @@ data: `productId`, `quantity`, and `isEditing`. It also passes a `key`,
 which is needed so LiveComponents can track which row is which.
     </twig:Code:CodeWithExplanationRow>
 
-    <twig:Code:CodeWithExplanationRow filename="src/Twig/Components/InvoiceCreatorLineItem.php" sticky class="pt-5">
+    <twig:Code:CodeWithExplanationRow filename="src/Twig/InvoiceCreatorLineItem.php" sticky class="pt-5">
 ## Child Component
 
 The child component for each "line item". This handles validating, saving,
diff --git a/ux.symfony.com/templates/demos/live_component/product_form.html.twig b/ux.symfony.com/templates/demos/live_component/product_form.html.twig
index 6aad5da5..bb2a7ada 100644
--- a/ux.symfony.com/templates/demos/live_component/product_form.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/product_form.html.twig
@@ -5,7 +5,7 @@
 {% endblock %}
 
 {% block code_block_full %}
-    <twig:Code:CodeWithExplanationRow filename="src/Twig/Components/NewProductForm.php" sticky>
+    <twig:Code:CodeWithExplanationRow filename="src/Twig/NewProductForm.php" sticky>
 ## New Product Form
 
 Live component with a form, `ValidatableComponentTrait` and a
@@ -31,7 +31,7 @@ and `data-bs-target="#new-category-modal"`.
     </twig:Code:CodeWithExplanationRow>
 
     <twig:Code:CodeWithExplanationRow
-        filename="src/Twig/Components/NewCategoryForm.php" sticky
+        filename="src/Twig/NewCategoryForm.php" sticky
     >
 ## New Category Form
 
@@ -45,7 +45,7 @@ the new `Category` to the database and then does two important things:
     </twig:Code:CodeWithExplanationRow>
 
     <twig:Code:TabbedCodeBlocks :files="[
-        'src/Twig/Components/BootstrapModal.php',
+        'src/Twig/BootstrapModal.php',
         'templates/components/BootstrapModal.html.twig',
         'assets/controllers/bootstrap-modal-controller.js',
     ]" />
diff --git a/ux.symfony.com/templates/demos/live_component/upload.html.twig b/ux.symfony.com/templates/demos/live_component/upload.html.twig
index 246d47b8..671f4fbd 100644
--- a/ux.symfony.com/templates/demos/live_component/upload.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/upload.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/UploadFiles.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/UploadFiles.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/demos/live_component/voting.html.twig b/ux.symfony.com/templates/demos/live_component/voting.html.twig
index 34da62e0..776ba909 100644
--- a/ux.symfony.com/templates/demos/live_component/voting.html.twig
+++ b/ux.symfony.com/templates/demos/live_component/voting.html.twig
@@ -1,7 +1,7 @@
 {% extends 'demos/live_demo.html.twig' %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/FoodVote.php" height="400px" />
+    <twig:CodeBlock filename="src/Twig/FoodVote.php" height="400px" />
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/ux.symfony.com/templates/ux_packages/twig_component.html.twig b/ux.symfony.com/templates/ux_packages/twig_component.html.twig
index 91da8abb..843a33dd 100644
--- a/ux.symfony.com/templates/ux_packages/twig_component.html.twig
+++ b/ux.symfony.com/templates/ux_packages/twig_component.html.twig
@@ -16,7 +16,7 @@
 {% endblock %}
 
 {% block code_block_left %}
-    <twig:CodeBlock filename="src/Twig/Components/Alert.php" height="330px"/>
+    <twig:CodeBlock filename="src/Twig/Alert.php" height="330px"/>
 {% endblock %}
 
 {% block code_block_right %}
diff --git a/yarn.lock b/yarn.lock
index 27e8d369..a40a02fc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3879,7 +3879,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"anymatch@npm:^3.0.3":
+"anymatch@npm:^3.0.3, anymatch@npm:~3.1.2":
   version: 3.1.3
   resolution: "anymatch@npm:3.1.3"
   dependencies:
@@ -4135,6 +4135,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"binary-extensions@npm:^2.0.0":
+  version: 2.2.0
+  resolution: "binary-extensions@npm:2.2.0"
+  checksum: 10c0/d73d8b897238a2d3ffa5f59c0241870043aa7471335e89ea5e1ff48edb7c2d0bb471517a3e4c5c3f4c043615caa2717b5f80a5e61e07503d51dc85cb848e665d
+  languageName: node
+  linkType: hard
+
 "brace-expansion@npm:^1.1.7":
   version: 1.1.11
   resolution: "brace-expansion@npm:1.1.11"
@@ -4172,7 +4179,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"braces@npm:^3.0.2":
+"braces@npm:^3.0.2, braces@npm:~3.0.2":
   version: 3.0.2
   resolution: "braces@npm:3.0.2"
   dependencies:
@@ -4383,6 +4390,25 @@ __metadata:
   languageName: node
   linkType: hard
 
+"chokidar@npm:^3.5.2":
+  version: 3.5.3
+  resolution: "chokidar@npm:3.5.3"
+  dependencies:
+    anymatch: "npm:~3.1.2"
+    braces: "npm:~3.0.2"
+    fsevents: "npm:~2.3.2"
+    glob-parent: "npm:~5.1.2"
+    is-binary-path: "npm:~2.1.0"
+    is-glob: "npm:~4.0.1"
+    normalize-path: "npm:~3.0.0"
+    readdirp: "npm:~3.6.0"
+  dependenciesMeta:
+    fsevents:
+      optional: true
+  checksum: 10c0/1076953093e0707c882a92c66c0f56ba6187831aa51bb4de878c1fec59ae611a3bf02898f190efec8e77a086b8df61c2b2a3ea324642a0558bdf8ee6c5dc9ca1
+  languageName: node
+  linkType: hard
+
 "chownr@npm:^2.0.0":
   version: 2.0.0
   resolution: "chownr@npm:2.0.0"
@@ -4423,12 +4449,26 @@ __metadata:
   languageName: node
   linkType: hard
 
-"clean-css@npm:^5.3.3":
-  version: 5.3.3
-  resolution: "clean-css@npm:5.3.3"
+"clean-css-cli@npm:^5.6.2":
+  version: 5.6.2
+  resolution: "clean-css-cli@npm:5.6.2"
+  dependencies:
+    chokidar: "npm:^3.5.2"
+    clean-css: "npm:^5.3.2"
+    commander: "npm:7.x"
+    glob: "npm:^7.1.6"
+  bin:
+    cleancss: bin/cleancss
+  checksum: 10c0/125d6aa8d34bce0598bcca2a14ca0c5f33dfcb237de28770c7982888d978070efd5bb5007d4d7a89c7cca385b5ed7d2717fa64e6f4a91a47cacf85b7522babd7
+  languageName: node
+  linkType: hard
+
+"clean-css@npm:^5.3.2":
+  version: 5.3.2
+  resolution: "clean-css@npm:5.3.2"
   dependencies:
     source-map: "npm:~0.6.0"
-  checksum: 10c0/381de7523e23f3762eb180e327dcc0cedafaf8cb1cd8c26b7cc1fc56e0829a92e734729c4f955394d65ed72fb62f82d8baf78af34b33b8a7d41ebad2accdd6fb
+  checksum: 10c0/315e0e81306524bd2c1905fa6823bf7658be40799b78f446e5e6922808718d2b80266fb3e96842a06176fa683bc2c1a0d2827b08d154e2f9cf136d7bda909d33
   languageName: node
   linkType: hard
 
@@ -4553,6 +4593,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"commander@npm:7.x":
+  version: 7.2.0
+  resolution: "commander@npm:7.2.0"
+  checksum: 10c0/8d690ff13b0356df7e0ebbe6c59b4712f754f4b724d4f473d3cc5b3fdcf978e3a5dc3078717858a2ceb50b0f84d0660a7f22a96cdc50fb877d0c9bb31593d23a
+  languageName: node
+  linkType: hard
+
 "commondir@npm:^1.0.1":
   version: 1.0.1
   resolution: "commondir@npm:1.0.1"
@@ -5590,6 +5637,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"glob-parent@npm:~5.1.2":
+  version: 5.1.2
+  resolution: "glob-parent@npm:5.1.2"
+  dependencies:
+    is-glob: "npm:^4.0.1"
+  checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee
+  languageName: node
+  linkType: hard
+
 "glob@npm:^10.2.2, glob@npm:^10.3.10":
   version: 10.4.5
   resolution: "glob@npm:10.4.5"
@@ -5606,7 +5662,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4":
+"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6":
   version: 7.2.3
   resolution: "glob@npm:7.2.3"
   dependencies:
@@ -5992,6 +6048,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-binary-path@npm:~2.1.0":
+  version: 2.1.0
+  resolution: "is-binary-path@npm:2.1.0"
+  dependencies:
+    binary-extensions: "npm:^2.0.0"
+  checksum: 10c0/a16eaee59ae2b315ba36fad5c5dcaf8e49c3e27318f8ab8fa3cdb8772bf559c8d1ba750a589c2ccb096113bb64497084361a25960899cb6172a6925ab6123d38
+  languageName: node
+  linkType: hard
+
 "is-boolean-object@npm:^1.1.0":
   version: 1.1.2
   resolution: "is-boolean-object@npm:1.1.2"
@@ -6110,6 +6175,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-extglob@npm:^2.1.1":
+  version: 2.1.1
+  resolution: "is-extglob@npm:2.1.1"
+  checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912
+  languageName: node
+  linkType: hard
+
 "is-fullwidth-code-point@npm:^3.0.0":
   version: 3.0.0
   resolution: "is-fullwidth-code-point@npm:3.0.0"
@@ -6124,6 +6196,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1":
+  version: 4.0.3
+  resolution: "is-glob@npm:4.0.3"
+  dependencies:
+    is-extglob: "npm:^2.1.1"
+  checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a
+  languageName: node
+  linkType: hard
+
 "is-lambda@npm:^1.0.1":
   version: 1.0.1
   resolution: "is-lambda@npm:1.0.1"
@@ -7762,7 +7843,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"normalize-path@npm:^3.0.0":
+"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
   version: 3.0.0
   resolution: "normalize-path@npm:3.0.0"
   checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046
@@ -8079,7 +8160,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1":
+"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1":
   version: 2.3.1
   resolution: "picomatch@npm:2.3.1"
   checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be
@@ -8325,6 +8406,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"readdirp@npm:~3.6.0":
+  version: 3.6.0
+  resolution: "readdirp@npm:3.6.0"
+  dependencies:
+    picomatch: "npm:^2.2.1"
+  checksum: 10c0/6fa848cf63d1b82ab4e985f4cf72bd55b7dcfd8e0a376905804e48c3634b7e749170940ba77b32804d5fe93b3cc521aa95a8d7e7d725f830da6d93f3669ce66b
+  languageName: node
+  linkType: hard
+
 "redent@npm:^3.0.0":
   version: 3.0.0
   resolution: "redent@npm:3.0.0"
@@ -8683,7 +8773,7 @@ __metadata:
     "@rollup/plugin-typescript": "npm:^11.1.6"
     "@symfony/stimulus-testing": "npm:^2.0.1"
     "@vitest/browser": "npm:^2.1.1"
-    clean-css: "npm:^5.3.3"
+    clean-css-cli: "npm:^5.6.2"
     playwright: "npm:^1.47.0"
     rollup: "npm:^4.22.5"
     tslib: "npm:^2.6.3"


Test patch:
diff --git a/bin/test_package.sh b/bin/run-vitest-all.sh
similarity index 66%
rename from bin/test_package.sh
rename to bin/run-vitest-all.sh
index 669e293c..74db629b 100755
--- a/bin/test_package.sh
+++ b/bin/run-vitest-all.sh
@@ -1,20 +1,8 @@
 #!/bin/bash
 
-# This script is used to test an UX package.
-# It also handle the case where a package has multiple versions of a peerDependency defined.
-
-SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
-PROJECT_DIR=$(dirname "$SCRIPT_DIR")
-
 # Flag to track if any test fails
 all_tests_passed=true
 
-# Check if we have at least one argument
-if [ $# -eq 0 ]
-  then
-    echo "No arguments supplied, please provide the package's path."
-fi
-
 # Check if jq is installed
 if ! command -v jq &> /dev/null; then
     echo "jq is required but not installed. Aborting."
@@ -23,31 +11,16 @@ fi
 
 runTestSuite() {
     echo -e "Running tests for $workspace...\n"
-    yarn run -T vitest --run || { all_tests_passed=false; }
+    yarn workspace $workspace run -T vitest --run || { all_tests_passed=false; }
 }
 
 processWorkspace() {
-    local location="$1"
+    local workspace="$1"
+    local location="$2"
 
-    if [ ! -d "$location" ]; then
-        echo "No directory found at $location"
-        return
-    fi
-
-    package_json_path="$location/package.json"
-    if [ ! -f "$package_json_path" ]; then
-        echo "No package.json found at $package_json_path"
-        return
-    fi
-    
-    workspace=$(jq -r '.name' "$package_json_path")
-    if [ -z "$workspace" ]; then
-        echo "No name found in package.json at $package_json_path"
-        return
-    fi
-    
     echo -e "Processing workspace $workspace at location $location...\n"
 
+    package_json_path="$location/package.json"
     echo "Checking '$package_json_path' for peerDependencies with multiple versions defined"
     deps_with_multiple_versions=$(jq -r '.peerDependencies | to_entries[] | select(.value | contains("||")) | .key' "$package_json_path")
 
@@ -75,7 +48,21 @@ processWorkspace() {
     fi
 }
 
-processWorkspace "$(realpath "$PWD/$1")"
+# Iterate over each workspace using process substitution
+while IFS= read -r workspace_info; do
+    # Split the workspace_info into workspace and location
+    workspace=$(echo "$workspace_info" | jq -r '.name')
+    location=$(echo "$workspace_info" | jq -r '.location')
+    
+    # Skip the root workspace
+    if [ $workspace == "null" ]; then
+        continue
+    fi
+
+    # Call the function to process the workspace
+    processWorkspace "$workspace" "$location"
+
+done < <(yarn workspaces list --json)
 
 # Check the flag at the end and exit with code 1 if any test failed
 if [ "$all_tests_passed" = false ]; then
diff --git a/test/setup.js b/test/setup.js
index f60ad9b0..ddd4655c 100644
--- a/test/setup.js
+++ b/test/setup.js
@@ -7,4 +7,6 @@
  * file that was distributed with this source code.
  */
 
+'use strict';
+
 import '@symfony/stimulus-testing/setup';