From f6c46d17f5fbb293c48868b61c251518e211a7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Wr=C3=B3blewski?= Date: Fri, 20 Sep 2024 22:24:30 +0200 Subject: [PATCH 1/2] Improve integration with Profiler --- docs/.vitepress/config.mts | 1 + docs/package-lock.json | 1605 +++++++++++------ docs/src/docs/features/profiler.md | 40 + docs/src/public/profiler_tab.png | Bin 0 -> 77929 bytes docs/src/public/profiler_toolbar.png | Bin 0 -> 3092 bytes phpstan.dist.neon | 3 +- src/Column/Type/ActionsColumnType.php | 5 +- src/Column/Type/CollectionColumnType.php | 5 +- src/DataCollector/DataTableDataCollector.php | 181 +- .../DataTableDataCollectorInterface.php | 25 +- src/DataCollector/DataTableDataExtractor.php | 120 +- .../DataTableDataExtractorInterface.php | 18 +- .../EventListener/DataCollectorListener.php | 20 +- .../ResolvedActionTypeDataCollectorProxy.php | 80 + ...vedActionTypeFactoryDataCollectorProxy.php | 27 + .../ResolvedColumnTypeDataCollectorProxy.php | 107 ++ ...vedColumnTypeFactoryDataCollectorProxy.php | 27 + ...esolvedDataTableTypeDataCollectorProxy.php | 85 + ...DataTableTypeFactoryDataCollectorProxy.php | 27 + ...ResolvedExporterTypeDataCollectorProxy.php | 58 + ...dExporterTypeFactoryDataCollectorProxy.php | 24 + .../ResolvedFilterTypeDataCollectorProxy.php | 74 + ...vedFilterTypeFactoryDataCollectorProxy.php | 27 + src/DataTable.php | 4 + src/DataTableConfigBuilder.php | 38 + src/DataTableConfigBuilderInterface.php | 4 + src/DataTableConfigInterface.php | 6 + src/Debug/TraceableDataTableFactory.php | 47 - src/DependencyInjection/Configuration.php | 8 + .../KreyuDataTableExtension.php | 6 + src/Event/DataTableEvents.php | 10 + src/Exporter/ExporterConfigBuilder.php | 39 + .../ExporterConfigBuilderInterface.php | 4 + src/Exporter/ExporterConfigInterface.php | 6 + src/Filter/FilterConfigBuilder.php | 38 + src/Filter/FilterConfigBuilderInterface.php | 4 + src/Filter/FilterConfigInterface.php | 6 + src/Resources/config/debug.php | 47 +- .../views/data_collector/template.html.twig | 1175 +++++++++++- 39 files changed, 3250 insertions(+), 751 deletions(-) create mode 100644 docs/src/docs/features/profiler.md create mode 100644 docs/src/public/profiler_tab.png create mode 100644 docs/src/public/profiler_toolbar.png create mode 100644 src/DataCollector/Proxy/ResolvedActionTypeDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedActionTypeFactoryDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedColumnTypeDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedColumnTypeFactoryDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedDataTableTypeDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedDataTableTypeFactoryDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedExporterTypeDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedExporterTypeFactoryDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedFilterTypeDataCollectorProxy.php create mode 100644 src/DataCollector/Proxy/ResolvedFilterTypeFactoryDataCollectorProxy.php delete mode 100644 src/Debug/TraceableDataTableFactory.php diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 10aae368..65e3f1e4 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -53,6 +53,7 @@ export default defineConfig({ { text: 'Persistence', link: '/docs/features/persistence' }, { text: 'Theming', link: '/docs/features/theming' }, { text: 'Asynchronicity', link: '/docs/features/asynchronicity' }, + { text: 'Profiler', link: '/docs/features/profiler' }, { text: 'Extensibility', link: '/docs/features/extensibility' }, ] }, diff --git a/docs/package-lock.json b/docs/package-lock.json index ff985216..8f4b10a8 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -56,139 +56,179 @@ } }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.22.1.tgz", - "integrity": "sha512-Sw6IAmOCvvP6QNgY9j+Hv09mvkvEIDKjYW8ow0UDDAxSXy664RBNQk3i/0nt7gvceOJ6jGmOTimaZoY1THmU7g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", "dev": true, "dependencies": { - "@algolia/cache-common": "4.22.1" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/cache-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.22.1.tgz", - "integrity": "sha512-TJMBKqZNKYB9TptRRjSUtevJeQVXRmg6rk9qgFKWvOy8jhCPdyNZV1nB3SKGufzvTVbomAukFR8guu/8NRKBTA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==", "dev": true }, "node_modules/@algolia/cache-in-memory": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.22.1.tgz", - "integrity": "sha512-ve+6Ac2LhwpufuWavM/aHjLoNz/Z/sYSgNIXsinGofWOysPilQZPUetqLj8vbvi+DHZZaYSEP9H5SRVXnpsNNw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", "dev": true, "dependencies": { - "@algolia/cache-common": "4.22.1" + "@algolia/cache-common": "4.24.0" } }, "node_modules/@algolia/client-account": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.22.1.tgz", - "integrity": "sha512-k8m+oegM2zlns/TwZyi4YgCtyToackkOpE+xCaKCYfBfDtdGOaVZCM5YvGPtK+HGaJMIN/DoTL8asbM3NzHonw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", "dev": true, "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-analytics": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.22.1.tgz", - "integrity": "sha512-1ssi9pyxyQNN4a7Ji9R50nSdISIumMFDwKNuwZipB6TkauJ8J7ha/uO60sPJFqQyqvvI+px7RSNRQT3Zrvzieg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", "dev": true, "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.22.1.tgz", - "integrity": "sha512-IvaL5v9mZtm4k4QHbBGDmU3wa/mKokmqNBqPj0K7lcR8ZDKzUorhcGp/u8PkPC/e0zoHSTvRh7TRkGX3Lm7iOQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", "dev": true, "dependencies": { - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.22.1.tgz", - "integrity": "sha512-sl+/klQJ93+4yaqZ7ezOttMQ/nczly/3GmgZXJ1xmoewP5jmdP/X/nV5U7EHHH3hCUEHeN7X1nsIhGPVt9E1cQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", "dev": true, "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/client-search": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.1.tgz", - "integrity": "sha512-yb05NA4tNaOgx3+rOxAmFztgMTtGBi97X7PC3jyNeGiwkAjOZc2QrdZBYyIdcDLoI09N0gjtpClcackoTN0gPA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", "dev": true, "dependencies": { - "@algolia/client-common": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/transporter": "4.22.1" + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/logger-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.22.1.tgz", - "integrity": "sha512-OnTFymd2odHSO39r4DSWRFETkBufnY2iGUZNrMXpIhF5cmFE8pGoINNPzwg02QLBlGSaLqdKy0bM8S0GyqPLBg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==", "dev": true }, "node_modules/@algolia/logger-console": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.22.1.tgz", - "integrity": "sha512-O99rcqpVPKN1RlpgD6H3khUWylU24OXlzkavUAMy6QZd1776QAcauE3oP8CmD43nbaTjBexZj2nGsBH9Tc0FVA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", "dev": true, "dependencies": { - "@algolia/logger-common": "4.22.1" + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dev": true, + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.22.1.tgz", - "integrity": "sha512-dtQGYIg6MteqT1Uay3J/0NDqD+UciHy3QgRbk7bNddOJu+p3hzjTRYESqEnoX/DpEkaNYdRHUKNylsqMpgwaEw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", "dev": true, "dependencies": { - "@algolia/requester-common": "4.22.1" + "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/requester-common": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.22.1.tgz", - "integrity": "sha512-dgvhSAtg2MJnR+BxrIFqlLtkLlVVhas9HgYKMk2Uxiy5m6/8HZBL40JVAMb2LovoPFs9I/EWIoFVjOrFwzn5Qg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==", "dev": true }, "node_modules/@algolia/requester-node-http": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.22.1.tgz", - "integrity": "sha512-JfmZ3MVFQkAU+zug8H3s8rZ6h0ahHZL/SpMaSasTCGYR5EEJsCc8SI5UZ6raPN2tjxa5bxS13BRpGSBUens7EA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", "dev": true, "dependencies": { - "@algolia/requester-common": "4.22.1" + "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/transporter": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.22.1.tgz", - "integrity": "sha512-kzWgc2c9IdxMa3YqA6TN0NW5VrKYYW/BELIn7vnLyn+U/RFdZ4lxxt9/8yq3DKV5snvoDzzO4ClyejZRdV3lMQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", "dev": true, "dependencies": { - "@algolia/cache-common": "4.22.1", - "@algolia/logger-common": "4.22.1", - "@algolia/requester-common": "4.22.1" + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -196,31 +236,45 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@docsearch/css": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", - "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", + "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==", "dev": true }, "node_modules/@docsearch/js": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.5.2.tgz", - "integrity": "sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.1.tgz", + "integrity": "sha512-erI3RRZurDr1xES5hvYJ3Imp7jtrXj6f1xYIzDzxiS7nNBufYWPbJwrmMqWC5g9y165PmxEmN9pklGCdLi0Iqg==", "dev": true, "dependencies": { - "@docsearch/react": "3.5.2", + "@docsearch/react": "3.6.1", "preact": "^10.0.0" } }, "node_modules/@docsearch/react": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", - "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz", + "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==", "dev": true, "dependencies": { "@algolia/autocomplete-core": "1.9.3", "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.5.2", + "@docsearch/css": "3.6.1", "algoliasearch": "^4.19.1" }, "peerDependencies": { @@ -245,9 +299,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -261,9 +315,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -277,9 +331,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -293,9 +347,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -309,9 +363,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -325,9 +379,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -341,9 +395,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -357,9 +411,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -373,9 +427,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -389,9 +443,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -405,9 +459,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -421,9 +475,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -437,9 +491,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -453,9 +507,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -469,9 +523,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -485,9 +539,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -501,9 +555,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -517,9 +571,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -533,9 +587,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -549,9 +603,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -565,9 +619,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -581,9 +635,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -597,9 +651,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -613,15 +667,15 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz", - "integrity": "sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.2.tgz", + "integrity": "sha512-8Ao+EDmTPjZ1ZBABc1ohN7Ylx7UIYcjReZinigedTOnGFhIctyGPxY2II+hJ6gD2/vkDKZTyQ0e7++kwv6wDrw==", "cpu": [ "arm" ], @@ -632,9 +686,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz", - "integrity": "sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.2.tgz", + "integrity": "sha512-I+B1v0a4iqdS9DvYt1RJZ3W+Oh9EVWjbY6gp79aAYipIbxSLEoQtFQlZEnUuwhDXCqMxJ3hluxKAdPD+GiluFQ==", "cpu": [ "arm64" ], @@ -645,9 +699,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz", - "integrity": "sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.2.tgz", + "integrity": "sha512-BTHO7rR+LC67OP7I8N8GvdvnQqzFujJYWo7qCQ8fGdQcb8Gn6EQY+K1P+daQLnDCuWKbZ+gHAQZuKiQkXkqIYg==", "cpu": [ "arm64" ], @@ -658,9 +712,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz", - "integrity": "sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.2.tgz", + "integrity": "sha512-1esGwDNFe2lov4I6GsEeYaAMHwkqk0IbuGH7gXGdBmd/EP9QddJJvTtTF/jv+7R8ZTYPqwcdLpMTxK8ytP6k6Q==", "cpu": [ "x64" ], @@ -671,9 +725,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz", - "integrity": "sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.2.tgz", + "integrity": "sha512-GBHuY07x96OTEM3OQLNaUSUwrOhdMea/LDmlFHi/HMonrgF6jcFrrFFwJhhe84XtA1oK/Qh4yFS+VMREf6dobg==", "cpu": [ "arm" ], @@ -684,9 +738,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz", - "integrity": "sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.2.tgz", + "integrity": "sha512-Dbfa9Sc1G1lWxop0gNguXOfGhaXQWAGhZUcqA0Vs6CnJq8JW/YOw/KvyGtQFmz4yDr0H4v9X248SM7bizYj4yQ==", "cpu": [ "arm" ], @@ -697,9 +751,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz", - "integrity": "sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.2.tgz", + "integrity": "sha512-Z1YpgBvFYhZIyBW5BoopwSg+t7yqEhs5HCei4JbsaXnhz/eZehT18DaXl957aaE9QK7TRGFryCAtStZywcQe1A==", "cpu": [ "arm64" ], @@ -710,9 +764,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz", - "integrity": "sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.2.tgz", + "integrity": "sha512-66Zszr7i/JaQ0u/lefcfaAw16wh3oT72vSqubIMQqWzOg85bGCPhoeykG/cC5uvMzH80DQa2L539IqKht6twVA==", "cpu": [ "arm64" ], @@ -723,9 +777,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz", - "integrity": "sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.2.tgz", + "integrity": "sha512-HpJCMnlMTfEhwo19bajvdraQMcAq3FX08QDx3OfQgb+414xZhKNf3jNvLFYKbbDSGBBrQh5yNwWZrdK0g0pokg==", "cpu": [ "ppc64" ], @@ -736,9 +790,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz", - "integrity": "sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.2.tgz", + "integrity": "sha512-/egzQzbOSRef2vYCINKITGrlwkzP7uXRnL+xU2j75kDVp3iPdcF0TIlfwTRF8woBZllhk3QaxNOEj2Ogh3t9hg==", "cpu": [ "riscv64" ], @@ -749,9 +803,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz", - "integrity": "sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.2.tgz", + "integrity": "sha512-qgYbOEbrPfEkH/OnUJd1/q4s89FvNJQIUldx8X2F/UM5sEbtkqZpf2s0yly2jSCKr1zUUOY1hnTP2J1WOzMAdA==", "cpu": [ "s390x" ], @@ -762,9 +816,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz", - "integrity": "sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.2.tgz", + "integrity": "sha512-a0lkvNhFLhf+w7A95XeBqGQaG0KfS3hPFJnz1uraSdUe/XImkp/Psq0Ca0/UdD5IEAGoENVmnYrzSC9Y2a2uKQ==", "cpu": [ "x64" ], @@ -775,9 +829,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz", - "integrity": "sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.2.tgz", + "integrity": "sha512-sSWBVZgzwtsuG9Dxi9kjYOUu/wKW+jrbzj4Cclabqnfkot8Z3VEHcIgyenA3lLn/Fu11uDviWjhctulkhEO60g==", "cpu": [ "x64" ], @@ -788,9 +842,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz", - "integrity": "sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.2.tgz", + "integrity": "sha512-t/YgCbZ638R/r7IKb9yCM6nAek1RUvyNdfU0SHMDLOf6GFe/VG1wdiUAsxTWHKqjyzkRGg897ZfCpdo1bsCSsA==", "cpu": [ "arm64" ], @@ -801,9 +855,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz", - "integrity": "sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.2.tgz", + "integrity": "sha512-kTmX5uGs3WYOA+gYDgI6ITkZng9SP71FEMoHNkn+cnmb9Zuyyay8pf0oO5twtTwSjNGy1jlaWooTIr+Dw4tIbw==", "cpu": [ "ia32" ], @@ -814,9 +868,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz", - "integrity": "sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.2.tgz", + "integrity": "sha512-Yy8So+SoRz8I3NS4Bjh91BICPOSVgdompTIPYTByUqU66AXSIOgmW3Lv1ke3NORPqxdF+RdrZET+8vYai6f4aA==", "cpu": [ "x64" ], @@ -827,46 +881,115 @@ ] }, "node_modules/@shikijs/core": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.1.5.tgz", - "integrity": "sha512-cKc5vGQ4p/4sjx48BHIO7CvLaN32vqpz5Wh7v2n+U1EezGdfX4Wms7khBctKz3iCg9yYq4sfGUc2t+JWj6EUsw==", - "dev": true + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.18.0.tgz", + "integrity": "sha512-VK4BNVCd2leY62Nm2JjyxtRLkyrZT/tv104O81eyaCjHq4Adceq2uJVFJJAIof6lT1mBwZrEo2qT/T+grv3MQQ==", + "dev": true, + "dependencies": { + "@shikijs/engine-javascript": "1.18.0", + "@shikijs/engine-oniguruma": "1.18.0", + "@shikijs/types": "1.18.0", + "@shikijs/vscode-textmate": "^9.2.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.3" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.18.0.tgz", + "integrity": "sha512-qoP/aO/ATNwYAUw1YMdaip/YVEstMZEgrwhePm83Ll9OeQPuxDZd48szZR8oSQNQBT8m8UlWxZv8EA3lFuyI5A==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.18.0", + "@shikijs/vscode-textmate": "^9.2.2", + "oniguruma-to-js": "0.4.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.18.0.tgz", + "integrity": "sha512-B9u0ZKI/cud+TcmF8Chyh+R4V5qQVvyDOqXC2l2a4x73PBSBc6sZ0JRAX3eqyJswqir6ktwApUUGBYePdKnMJg==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.18.0", + "@shikijs/vscode-textmate": "^9.2.2" + } }, "node_modules/@shikijs/transformers": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.1.5.tgz", - "integrity": "sha512-ot6KWPmLuSN9nA9FAhttOXZIjKIy7cnwpNtI9aWmYN72RUaDz8eojRfMGUXsXXUxW/buvcvdZQAQldk7/pFpdw==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.18.0.tgz", + "integrity": "sha512-EdX/UIVaaS8qp9NWRyHIXp2dmuLpdVvx+UVpbIn9eafFlLemAuljPb2+K40ie6jrlg0uUIqkg25CM/8I34yBNw==", + "dev": true, + "dependencies": { + "shiki": "1.18.0" + } + }, + "node_modules/@shikijs/types": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.18.0.tgz", + "integrity": "sha512-O9N36UEaGGrxv1yUrN2nye7gDLG5Uq0/c1LyfmxsvzNPqlHzWo9DI0A4+fhW2y3bGKuQu/fwS7EPdKJJCowcVA==", "dev": true, "dependencies": { - "shiki": "1.1.5" + "@shikijs/vscode-textmate": "^9.2.2", + "@types/hast": "^3.0.4" } }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.2.2.tgz", + "integrity": "sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==", + "dev": true + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", "dev": true }, "node_modules/@types/markdown-it": { - "version": "13.0.7", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.7.tgz", - "integrity": "sha512-U/CBi2YUUcTHBt5tjO2r5QV/x0Po6nsYwQU4Y04fBS6vfoImaiZ6f8bi3CjTCxBPQSO1LMyUqkByzi8AidyxfA==", + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "dev": true, + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "dev": true, "dependencies": { - "@types/linkify-it": "*", - "@types/mdurl": "*" + "@types/unist": "*" } }, "node_modules/@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "dev": true }, "node_modules/@types/web-bluetooth": { @@ -875,10 +998,16 @@ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", "dev": true }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vitejs/plugin-vue": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", - "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz", + "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" @@ -889,205 +1018,179 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", - "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.7.tgz", + "integrity": "sha512-A0gay3lK71MddsSnGlBxRPOugIVdACze9L/rCo5X5srCyjQfZOfYtSFMJc3aOZCM+xN55EQpb4R97rYn/iEbSw==", "dev": true, "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.19", + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.7", "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", - "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.7.tgz", + "integrity": "sha512-GYWl3+gO8/g0ZdYaJ18fYHdI/WVic2VuuUd1NsPp60DWXKy+XjdhFsDW7FbUto8siYYZcosBGn9yVBkjhq1M8Q==", "dev": true, "dependencies": { - "@vue/compiler-core": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-core": "3.5.7", + "@vue/shared": "3.5.7" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", - "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.7.tgz", + "integrity": "sha512-EjOJtCWJrC7HqoCEzOwpIYHm+JH7YmkxC1hG6VkqIukYRqj8KFUlTLK6hcT4nGgtVov2+ZfrdrRlcaqS78HnBA==", "dev": true, "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.19", - "@vue/compiler-dom": "3.4.19", - "@vue/compiler-ssr": "3.4.19", - "@vue/shared": "3.4.19", + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.7", + "@vue/compiler-dom": "3.5.7", + "@vue/compiler-ssr": "3.5.7", + "@vue/shared": "3.5.7", "estree-walker": "^2.0.2", - "magic-string": "^0.30.6", - "postcss": "^8.4.33", - "source-map-js": "^1.0.2" + "magic-string": "^0.30.11", + "postcss": "^8.4.47", + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", - "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.7.tgz", + "integrity": "sha512-oZx+jXP2k5arV/8Ly3TpQbfFyimMw2ANrRqvHJoKjPqtEzazxQGZjCLOfq8TnZ3wy2TOXdqfmVp4q7FyYeHV4g==", "dev": true, "dependencies": { - "@vue/compiler-dom": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-dom": "3.5.7", + "@vue/shared": "3.5.7" } }, "node_modules/@vue/devtools-api": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.0.15.tgz", - "integrity": "sha512-kgEYWosDyWpS1vFSuJNNWUnHkP+VkL3Y+9mw+rf7ex41SwbYL/WdC3KXqAtjiSrEs7r/FrHmUTh0BkINJPFkbA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.4.5.tgz", + "integrity": "sha512-PX9uXirHOY2P99kb1cP3DxWZojFW3acNMqd+l4i5nKcqY59trXTOfwDZXt2Qifu0OU1izAQb76Ur6NPVldF2KQ==", "dev": true, "dependencies": { - "@vue/devtools-kit": "^7.0.15" + "@vue/devtools-kit": "^7.4.5" } }, "node_modules/@vue/devtools-kit": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.0.15.tgz", - "integrity": "sha512-dT7OeCe1LUCIhHIb/yRR6Hn+XHh73r1o78onqCrxEKHdoZwBItiIeVnmJZPEUDFstIxfs+tJL231mySk3laTow==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.4.5.tgz", + "integrity": "sha512-Uuki4Z6Bc/ExvtlPkeDNGSAe4580R+HPcVABfTE9TF7BTz3Nntk7vxIRUyWblZkUEcB/x+wn2uofyt5i2LaUew==", "dev": true, "dependencies": { - "@vue/devtools-shared": "^7.0.15", + "@vue/devtools-shared": "^7.4.5", + "birpc": "^0.2.17", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", - "speakingurl": "^14.0.1" - }, - "peerDependencies": { - "vue": "^3.0.0" + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" } }, "node_modules/@vue/devtools-shared": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.0.15.tgz", - "integrity": "sha512-fpfvMVvS7aDgO7x2JPFiTQ1MHcCc63/bE7yTgs278gMBybuO9b3hdiZ/k0Pw1rN+RefaU9yQiFA+5CCFc1D+6w==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.4.5.tgz", + "integrity": "sha512-2XgUOkL/7QDmyYI9J7cm+rz/qBhcGv+W5+i1fhwdQ0HQ1RowhdK66F0QBuJSz/5k12opJY8eN6m03/XZMs7imQ==", "dev": true, "dependencies": { - "rfdc": "^1.3.1" + "rfdc": "^1.4.1" } }, "node_modules/@vue/reactivity": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz", - "integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.7.tgz", + "integrity": "sha512-yF0EpokpOHRNXyn/h6abXc9JFIzfdAf0MJHIi92xxCWS0mqrXH6+2aZ+A6EbSrspGzX5MHTd5N8iBA28HnXu9g==", "dev": true, "dependencies": { - "@vue/shared": "3.4.19" + "@vue/shared": "3.5.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz", - "integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.7.tgz", + "integrity": "sha512-OzLpBpKbZEaZVSNfd+hQbfBrDKux+b7Yl5hYhhWWWhHD7fEpF+CdI3Brm5k5GsufHEfvMcjruPxwQZuBN6nFYQ==", "dev": true, "dependencies": { - "@vue/reactivity": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/reactivity": "3.5.7", + "@vue/shared": "3.5.7" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz", - "integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.7.tgz", + "integrity": "sha512-fL7cETfE27U2jyTgqzE382IGFY6a6uyznErn27KbbEzNctzxxUWYDbaN3B55l9nXh0xW2LRWPuWKOvjtO2UewQ==", "dev": true, "dependencies": { - "@vue/runtime-core": "3.4.19", - "@vue/shared": "3.4.19", + "@vue/reactivity": "3.5.7", + "@vue/runtime-core": "3.5.7", + "@vue/shared": "3.5.7", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz", - "integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.7.tgz", + "integrity": "sha512-peRypij815eIDjpPpPXvYQGYqPH6QXwLJGWraJYPPn8JqWGl29A8QXnS7/Mh3TkMiOcdsJNhbFCoW2Agc2NgAQ==", "dev": true, "dependencies": { - "@vue/compiler-ssr": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-ssr": "3.5.7", + "@vue/shared": "3.5.7" }, "peerDependencies": { - "vue": "3.4.19" + "vue": "3.5.7" } }, "node_modules/@vue/shared": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", - "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.7.tgz", + "integrity": "sha512-NBE1PBIvzIedxIc2RZiKXvGbJkrZ2/hLf3h8GlS4/sP9xcXEZMFWOazFkNd6aGeUCMaproe5MHVYB3/4AW9q9g==", "dev": true }, "node_modules/@vueuse/core": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.7.2.tgz", - "integrity": "sha512-AOyAL2rK0By62Hm+iqQn6Rbu8bfmbgaIMXcE3TSr7BdQ42wnSFlwIdPjInO62onYsEMK/yDMU8C6oGfDAtZ2qQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz", + "integrity": "sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==", "dev": true, "dependencies": { "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.7.2", - "@vueuse/shared": "10.7.2", - "vue-demi": ">=0.14.6" + "@vueuse/metadata": "11.1.0", + "@vueuse/shared": "11.1.0", + "vue-demi": ">=0.14.10" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, "node_modules/@vueuse/integrations": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.7.2.tgz", - "integrity": "sha512-+u3RLPFedjASs5EKPc69Ge49WNgqeMfSxFn+qrQTzblPXZg6+EFzhjarS5edj2qAf6xQ93f95TUxRwKStXj/sQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.1.0.tgz", + "integrity": "sha512-O2ZgrAGPy0qAjpoI2YR3egNgyEqwG85fxfwmA9BshRIGjV4G6yu6CfOPpMHAOoCD+UfsIl7Vb1bXJ6ifrHYDDA==", "dev": true, "dependencies": { - "@vueuse/core": "10.7.2", - "@vueuse/shared": "10.7.2", - "vue-demi": ">=0.14.6" + "@vueuse/core": "11.1.0", + "@vueuse/shared": "11.1.0", + "vue-demi": ">=0.14.10" }, "funding": { "url": "https://github.com/sponsors/antfu" }, "peerDependencies": { - "async-validator": "*", - "axios": "*", - "change-case": "*", - "drauu": "*", - "focus-trap": "*", - "fuse.js": "*", - "idb-keyval": "*", - "jwt-decode": "*", - "nprogress": "*", - "qrcode": "*", - "sortablejs": "*", - "universal-cookie": "*" + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7" }, "peerDependenciesMeta": { "async-validator": { @@ -1128,99 +1231,48 @@ } } }, - "node_modules/@vueuse/integrations/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, "node_modules/@vueuse/metadata": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz", - "integrity": "sha512-kCWPb4J2KGrwLtn1eJwaJD742u1k5h6v/St5wFe8Quih90+k2a0JP8BS4Zp34XUuJqS2AxFYMb1wjUL8HfhWsQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz", + "integrity": "sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==", "dev": true, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.7.2.tgz", - "integrity": "sha512-qFbXoxS44pi2FkgFjPvF4h7c9oMDutpyBdcJdMYIMg9XyXli2meFMuaKn+UMgsClo//Th6+beeCgqweT/79BVA==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.1.0.tgz", + "integrity": "sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==", "dev": true, "dependencies": { - "vue-demi": ">=0.14.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", - "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" + "vue-demi": ">=0.14.10" }, "funding": { "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } } }, "node_modules/algoliasearch": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz", - "integrity": "sha512-jwydKFQJKIx9kIZ8Jm44SdpigFwRGPESaxZBaHSV0XWN2yBJAOT4mT7ppvlrpA4UGzz92pqFnVKr/kaZXrcreg==", - "dev": true, - "dependencies": { - "@algolia/cache-browser-local-storage": "4.22.1", - "@algolia/cache-common": "4.22.1", - "@algolia/cache-in-memory": "4.22.1", - "@algolia/client-account": "4.22.1", - "@algolia/client-analytics": "4.22.1", - "@algolia/client-common": "4.22.1", - "@algolia/client-personalization": "4.22.1", - "@algolia/client-search": "4.22.1", - "@algolia/logger-common": "4.22.1", - "@algolia/logger-console": "4.22.1", - "@algolia/requester-browser-xhr": "4.22.1", - "@algolia/requester-common": "4.22.1", - "@algolia/requester-node-http": "4.22.1", - "@algolia/transporter": "4.22.1" + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "dev": true, + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" } }, "node_modules/argparse": { @@ -1229,12 +1281,98 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/birpc": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.17.tgz", + "integrity": "sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -1248,9 +1386,9 @@ } }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -1260,29 +1398,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/estree-walker": { @@ -1292,9 +1430,9 @@ "dev": true }, "node_modules/focus-trap": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", - "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz", + "integrity": "sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==", "dev": true, "dependencies": { "tabbable": "^6.2.0" @@ -1314,12 +1452,70 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/hast-util-to-html": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", + "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hookable": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", "dev": true }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -1330,15 +1526,12 @@ } }, "node_modules/magic-string": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", - "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/mark.js": { @@ -1348,9 +1541,9 @@ "dev": true }, "node_modules/markdown-it": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", - "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, "dependencies": { "argparse": "^2.0.1", @@ -1358,22 +1551,132 @@ "linkify-it": "^5.0.0", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", - "uc.micro": "^2.0.0" + "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", "dev": true }, + "node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/minisearch": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.3.0.tgz", - "integrity": "sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz", + "integrity": "sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==", "dev": true }, "node_modules/mitt": { @@ -1400,6 +1703,18 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/oniguruma-to-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", + "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "dev": true, + "dependencies": { + "regex": "^4.3.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/perfect-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", @@ -1407,15 +1722,15 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -1433,23 +1748,33 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/preact": { - "version": "10.19.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", - "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==", + "version": "10.24.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.0.tgz", + "integrity": "sha512-aK8Cf+jkfyuZ0ZZRG9FbYqwmEiGQ4y/PUO4SuTWoyWL244nZZh7bd5h2APd4rSNDYTBNghg1L+5iJN3Skxtbsw==", "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" } }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/punycode.js": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", @@ -1459,16 +1784,22 @@ "node": ">=6" } }, + "node_modules/regex": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.2.tgz", + "integrity": "sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw==", + "dev": true + }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "node_modules/rollup": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.16.4.tgz", - "integrity": "sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.2.tgz", + "integrity": "sha512-JWWpTrZmqQGQWt16xvNn6KVIUz16VtZwl984TKw0dfqqRpFwtLJYYk1/4BTgplndMQKWUk/yB4uOShYmMzA2Vg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -1481,50 +1812,58 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.16.4", - "@rollup/rollup-android-arm64": "4.16.4", - "@rollup/rollup-darwin-arm64": "4.16.4", - "@rollup/rollup-darwin-x64": "4.16.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.16.4", - "@rollup/rollup-linux-arm-musleabihf": "4.16.4", - "@rollup/rollup-linux-arm64-gnu": "4.16.4", - "@rollup/rollup-linux-arm64-musl": "4.16.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.16.4", - "@rollup/rollup-linux-riscv64-gnu": "4.16.4", - "@rollup/rollup-linux-s390x-gnu": "4.16.4", - "@rollup/rollup-linux-x64-gnu": "4.16.4", - "@rollup/rollup-linux-x64-musl": "4.16.4", - "@rollup/rollup-win32-arm64-msvc": "4.16.4", - "@rollup/rollup-win32-ia32-msvc": "4.16.4", - "@rollup/rollup-win32-x64-msvc": "4.16.4", + "@rollup/rollup-android-arm-eabi": "4.22.2", + "@rollup/rollup-android-arm64": "4.22.2", + "@rollup/rollup-darwin-arm64": "4.22.2", + "@rollup/rollup-darwin-x64": "4.22.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.2", + "@rollup/rollup-linux-arm-musleabihf": "4.22.2", + "@rollup/rollup-linux-arm64-gnu": "4.22.2", + "@rollup/rollup-linux-arm64-musl": "4.22.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.2", + "@rollup/rollup-linux-riscv64-gnu": "4.22.2", + "@rollup/rollup-linux-s390x-gnu": "4.22.2", + "@rollup/rollup-linux-x64-gnu": "4.22.2", + "@rollup/rollup-linux-x64-musl": "4.22.2", + "@rollup/rollup-win32-arm64-msvc": "4.22.2", + "@rollup/rollup-win32-ia32-msvc": "4.22.2", + "@rollup/rollup-win32-x64-msvc": "4.22.2", "fsevents": "~2.3.2" } }, - "node_modules/search-insights": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz", - "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==", - "dev": true, - "peer": true - }, "node_modules/shiki": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.1.5.tgz", - "integrity": "sha512-754GuKIwkUdT810Xm8btuyNQPL+q3PqOkwGW/VlmAWyMYp+HbvvDt69sWXO1sm5aeczBJQjmQTTMR4GkKQNQPw==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.18.0.tgz", + "integrity": "sha512-8jo7tOXr96h9PBQmOHVrltnETn1honZZY76YA79MHheGQg55jBvbm9dtU+MI5pjC5NJCFuA6rvVTLVeSW5cE4A==", "dev": true, "dependencies": { - "@shikijs/core": "1.1.5" + "@shikijs/core": "1.18.0", + "@shikijs/engine-javascript": "1.18.0", + "@shikijs/engine-oniguruma": "1.18.0", + "@shikijs/types": "1.18.0", + "@shikijs/vscode-textmate": "^9.2.2", + "@types/hast": "^3.0.4" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/speakingurl": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", @@ -1534,27 +1873,168 @@ "node": ">=0.10.0" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/superjson": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", + "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "dev": true, + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", "dev": true }, - "node_modules/uc.micro": { + "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.0.0.tgz", - "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", "dev": true }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", - "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", + "version": "5.4.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz", + "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -1573,6 +2053,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -1590,6 +2071,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -1602,33 +2086,34 @@ } }, "node_modules/vitepress": { - "version": "1.0.0-rc.43", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-rc.43.tgz", - "integrity": "sha512-XZ9xaN76/LxCBqvk6U+3ne3T60JOavdOlk+FMQBlXYK/9pyyKGfjnEra4yKYvOdZdStoTg8VXTAj4wcsCTlJaQ==", - "dev": true, - "dependencies": { - "@docsearch/css": "^3.5.2", - "@docsearch/js": "^3.5.2", - "@shikijs/core": "^1.1.3", - "@shikijs/transformers": "^1.1.3", - "@types/markdown-it": "^13.0.7", - "@vitejs/plugin-vue": "^5.0.4", - "@vue/devtools-api": "^7.0.14", - "@vueuse/core": "^10.7.2", - "@vueuse/integrations": "^10.7.2", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.3.4.tgz", + "integrity": "sha512-I1/F6OW1xl3kW4PaIMC6snxjWgf3qfziq2aqsDoFc/Gt41WbcRv++z8zjw8qGRIJ+I4bUW7ZcKFDHHN/jkH9DQ==", + "dev": true, + "dependencies": { + "@docsearch/css": "^3.6.1", + "@docsearch/js": "^3.6.1", + "@shikijs/core": "^1.13.0", + "@shikijs/transformers": "^1.13.0", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^5.1.2", + "@vue/devtools-api": "^7.3.8", + "@vue/shared": "^3.4.38", + "@vueuse/core": "^11.0.0", + "@vueuse/integrations": "^11.0.0", "focus-trap": "^7.5.4", "mark.js": "8.11.1", - "minisearch": "^6.3.0", - "shiki": "^1.1.3", - "vite": "^5.1.3", - "vue": "^3.4.19" + "minisearch": "^7.1.0", + "shiki": "^1.13.0", + "vite": "^5.4.1", + "vue": "^3.4.38" }, "bin": { "vitepress": "bin/vitepress.js" }, "peerDependencies": { - "markdown-it-mathjax3": "^4.3.2", - "postcss": "^8.4.35" + "markdown-it-mathjax3": "^4", + "postcss": "^8" }, "peerDependenciesMeta": { "markdown-it-mathjax3": { @@ -1650,16 +2135,16 @@ } }, "node_modules/vue": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz", - "integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.7.tgz", + "integrity": "sha512-JcFm0f5j8DQO9E07pZRxqZ/ZsNopMVzHYXpKvnfqXFcA4JTi+4YcrikRn9wkzWsdj0YsLzlLIsR0zzGxA2P6Wg==", "dev": true, "dependencies": { - "@vue/compiler-dom": "3.4.19", - "@vue/compiler-sfc": "3.4.19", - "@vue/runtime-dom": "3.4.19", - "@vue/server-renderer": "3.4.19", - "@vue/shared": "3.4.19" + "@vue/compiler-dom": "3.5.7", + "@vue/compiler-sfc": "3.5.7", + "@vue/runtime-dom": "3.5.7", + "@vue/server-renderer": "3.5.7", + "@vue/shared": "3.5.7" }, "peerDependencies": { "typescript": "*" @@ -1669,6 +2154,42 @@ "optional": true } } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/docs/src/docs/features/profiler.md b/docs/src/docs/features/profiler.md new file mode 100644 index 00000000..ab021668 --- /dev/null +++ b/docs/src/docs/features/profiler.md @@ -0,0 +1,40 @@ +# Profiler + +The bundle has a built-in integration with the [Symfony Profiler](https://symfony.com/doc/current/profiler.html). + +## Usage + +If at least one data table was created, the toolbar will include a new tab: + +![profiler_toolbar.png](/profiler_toolbar.png) + +Clicking it will redirect you to the _Data Tables_ profiler tab: + +![profiler_tab.png](/profiler_tab.png) + +Here you can inspect every single part of each data table: + +- quick overview - is this column sortable? is this filter applied? +- type class of each component; +- which options were passed; +- how those options got resolved; +- variables available in views, passed to the templates; +- data of each value row of the current page; + +## Configuration + +Because the amount of data collected for this integration can be massive, +the maximum depth of serialization can be adjusted in the bundle configuration: + +```yaml +kreyu_data_table: + profiler: + max_depth: 3 +``` + +Increasing the `max_depth` value will result in collecting and displaying deeper objects. +If you wish to disable this limitation completely, set this value to `-1`. + +::: warning +Increasing the depth **will** result in the browser freezes after opening the profiler tab. +::: diff --git a/docs/src/public/profiler_tab.png b/docs/src/public/profiler_tab.png new file mode 100644 index 0000000000000000000000000000000000000000..9577b95ee6680fcf46023d6b195ec6948ba6ff05 GIT binary patch literal 77929 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 literal 0 HcmV?d00001 diff --git a/docs/src/public/profiler_toolbar.png b/docs/src/public/profiler_toolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..dbfd80640a724c31135d3aff5680bfe9eace7666 GIT binary patch literal 3092 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 XOXdk?YiiT7zkP@s)&oO39GLMhX&M5= literal 0 HcmV?d00001 diff --git a/phpstan.dist.neon b/phpstan.dist.neon index ab2834f1..24c32c70 100755 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -1,9 +1,8 @@ parameters: level: 5 - checkGenericClassInNonGenericObjectType: false paths: - src - tests excludePaths: - src/Resources/skeleton/* - - src/DependencyInjection/Configuration.php \ No newline at end of file + - src/DependencyInjection/Configuration.php diff --git a/src/Column/Type/ActionsColumnType.php b/src/Column/Type/ActionsColumnType.php index 9db45d46..33effa43 100755 --- a/src/Column/Type/ActionsColumnType.php +++ b/src/Column/Type/ActionsColumnType.php @@ -25,7 +25,10 @@ public function buildValueView(ColumnValueView $view, ColumnInterface $column, a $actions = []; foreach ($options['actions'] as $name => $action) { - $actions[$name] = $this->resolveAction($name, $action, $view)?->createView($view); + $action = $this->resolveAction($name, $action, $view); + $action?->setDataTable($column->getDataTable()); + + $actions[$name] = $action?->createView($view); } $view->vars['actions'] = array_filter($actions); diff --git a/src/Column/Type/CollectionColumnType.php b/src/Column/Type/CollectionColumnType.php index 8b0effed..92833cb9 100755 --- a/src/Column/Type/CollectionColumnType.php +++ b/src/Column/Type/CollectionColumnType.php @@ -62,8 +62,6 @@ private function createChildrenColumnValueViews(ColumnValueView $view, ColumnInt /** @var ColumnFactoryInterface $prototypeFactory */ $prototypeFactory = $column->getConfig()->getAttribute('prototype_factory'); - $prototype = $prototypeFactory->createNamed('__name__', $options['entry_type'], $options['entry_options']); - $children = []; foreach ($view->vars['value'] ?? [] as $index => $data) { @@ -73,6 +71,9 @@ private function createChildrenColumnValueViews(ColumnValueView $view, ColumnInt $valueRowView->index = $index; $valueRowView->data = $data; + $prototype = $prototypeFactory->createNamed((string) $index, $options['entry_type'], $options['entry_options']); + $prototype->setDataTable($column->getDataTable()); + $children[] = $prototype->createValueView($valueRowView); } diff --git a/src/DataCollector/DataTableDataCollector.php b/src/DataCollector/DataTableDataCollector.php index c3759d25..5c4287a1 100644 --- a/src/DataCollector/DataTableDataCollector.php +++ b/src/DataCollector/DataTableDataCollector.php @@ -4,10 +4,19 @@ namespace Kreyu\Bundle\DataTableBundle\DataCollector; +use Kreyu\Bundle\DataTableBundle\Action\ActionContext; use Kreyu\Bundle\DataTableBundle\Action\ActionInterface; +use Kreyu\Bundle\DataTableBundle\Action\ActionView; +use Kreyu\Bundle\DataTableBundle\Column\ColumnHeaderView; use Kreyu\Bundle\DataTableBundle\Column\ColumnInterface; +use Kreyu\Bundle\DataTableBundle\Column\ColumnValueView; use Kreyu\Bundle\DataTableBundle\DataTableInterface; +use Kreyu\Bundle\DataTableBundle\DataTableView; +use Kreyu\Bundle\DataTableBundle\Exporter\ExporterInterface; +use Kreyu\Bundle\DataTableBundle\Filter\FilterInterface; +use Kreyu\Bundle\DataTableBundle\Filter\FilterView; use Kreyu\Bundle\DataTableBundle\Filter\FiltrationData; +use Kreyu\Bundle\DataTableBundle\Sorting\SortingData; use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -17,104 +26,166 @@ class DataTableDataCollector extends AbstractDataCollector implements DataTableDataCollectorInterface { public function __construct( - readonly private DataTableDataExtractorInterface $dataExtractor, + private DataTableDataExtractorInterface $dataExtractor, + private int $maxDepth = 3, ) { if (!class_exists(ClassStub::class)) { throw new \LogicException(sprintf('The VarDumper component is needed for using the "%s" class. Install symfony/var-dumper version 3.4 or above.', __CLASS__)); } } + public function __sleep(): array + { + $this->data = $this->cloneVar($this->data)->withMaxDepth($this->maxDepth); + + return parent::__sleep(); + } + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { - // Everything is collected on dataTable creation } public function collectDataTable(DataTableInterface $dataTable): void { - $this->data[$dataTable->getConfig()->getName()] = [ - 'filters' => [], - 'columns' => array_map(function (ColumnInterface $column) { - return [ - 'name' => $column->getName(), - 'type' => $column->getConfig()->getType()->getInnerType()::class, - 'options' => $this->cloneVar($column->getConfig()->getOptions()), - ]; - }, array_filter($dataTable->getColumns(), function (ColumnInterface $column) { - return !str_contains($column->getName(), '__'); - }), + $data = [ + 'columns' => $this->mapWithKeys( + fn (ColumnInterface $column) => [$column->getName() => $this->dataExtractor->extractColumnConfiguration($column)], + $dataTable->getColumns(), + ), + 'filters' => $this->mapWithKeys( + fn (FilterInterface $filter) => [$filter->getName() => $this->dataExtractor->extractFilterConfiguration($filter)], + $dataTable->getFilters(), + ), + 'actions' => $this->mapWithKeys( + fn (ActionInterface $action) => [$action->getName() => $this->dataExtractor->extractActionConfiguration($action)], + $dataTable->getActions(), + ), + 'row_actions' => $this->mapWithKeys( + fn (ActionInterface $action) => [$action->getName() => $this->dataExtractor->extractActionConfiguration($action)], + $dataTable->getRowActions(), + ), + 'batch_actions' => $this->mapWithKeys( + fn (ActionInterface $action) => [$action->getName() => $this->dataExtractor->extractActionConfiguration($action)], + $dataTable->getBatchActions(), + ), + 'exporters' => $this->mapWithKeys( + fn (ExporterInterface $exporter) => [$exporter->getName() => $this->dataExtractor->extractExporterConfiguration($exporter)], + $dataTable->getExporters(), ), - 'actions' => array_map(function (ActionInterface $action) { - return [ - 'name' => $action->getName(), - 'type' => $action->getConfig()->getType()->getInnerType()::class, - 'options' => $this->cloneVar($action->getConfig()->getOptions()), - ]; - }, $dataTable->getActions()), - 'batch_actions' => array_map(function (ActionInterface $action) { - return [ - 'name' => $action->getName(), - 'type' => $action->getConfig()->getType()->getInnerType()::class, - 'options' => $this->cloneVar($action->getConfig()->getOptions()), - ]; - }, $dataTable->getBatchActions()), - 'row_actions' => array_map(function (ActionInterface $action) { - return [ - 'name' => $action->getName(), - 'type' => $action->getConfig()->getType()->getInnerType()::class, - 'options' => $this->cloneVar($action->getConfig()->getOptions()), - ]; - }, $dataTable->getRowActions()), ]; + + $data = array_merge($data, $this->dataExtractor->extractDataTableConfiguration($dataTable)); + + $this->data[$dataTable->getName()] = $data; } - public static function getTemplate(): ?string + public function collectDataTableView(DataTableInterface $dataTable, DataTableView $view): void { - return '@KreyuDataTable/data_collector/template.html.twig'; + $this->data[$dataTable->getName()] += [ + 'view_vars' => $this->ksort($view->vars), + 'value_rows' => $this->dataExtractor->extractValueRows($view), + ]; } - public function getDataTables(): array + public function collectColumnHeaderView(ColumnInterface $column, ColumnHeaderView $view): void { - return array_keys($this->data); + $this->data[$column->getDataTable()->getName()]['columns'][$column->getName()]['header_view_vars'] = $this->ksort($view->vars); } - public function getColumns(string $dataTableName): array + public function collectColumnValueView(ColumnInterface $column, ColumnValueView $view): void { - return $this->data[$dataTableName]['columns']; + // TODO: Support nested columns from CollectionColumnType + if (null !== $view->parent->origin) { + return; + } + + $this->data[$column->getDataTable()->getName()]['columns'][$column->getName()]['value_view_vars'] = $this->ksort($view->vars); } - public function getFilters(string $dataTableName): array + public function collectSortingData(DataTableInterface $dataTable, SortingData $data): void { - return $this->data[$dataTableName]['filters']; + foreach ($data->getColumns() as $columnName => $columnSortingData) { + if (!$dataTable->hasColumn($columnName)) { + continue; + } + + $column = $dataTable->getColumn($columnName); + + $this->data[$column->getDataTable()->getName()]['columns'][$column->getName()] ??= []; + $this->data[$column->getDataTable()->getName()]['columns'][$column->getName()] += [ + 'sort_direction' => $columnSortingData->getDirection(), + ]; + } } - public function getActions(string $dataTableName): array + public function collectFilterView(FilterInterface $filter, FilterView $view): void { - return $this->data[$dataTableName]['actions']; + $this->data[$filter->getDataTable()->getName()]['filters'][$filter->getName()]['view_vars'] = $this->ksort($view->vars); } - public function getBatchActions(string $dataTableName): array + public function collectFiltrationData(DataTableInterface $dataTable, FiltrationData $data): void { - return $this->data[$dataTableName]['batch_actions']; + foreach ($data->getFilters() as $filterName => $filterData) { + if (!$dataTable->hasFilter($filterName)) { + continue; + } + + $filter = $dataTable->getFilter($filterName); + + $this->data[$filter->getDataTable()->getName()]['filters'][$filter->getName()] ??= []; + $this->data[$filter->getDataTable()->getName()]['filters'][$filter->getName()] += [ + 'data' => $filterData, + 'operator_label' => $filterData->getOperator()->getLabel(), + ]; + } } - public function getRowActions(string $dataTableName): array + public function collectActionView(ActionInterface $action, ActionView $view): void { - return $this->data[$dataTableName]['row_actions']; + $actionsKey = match ($action->getConfig()->getContext()) { + ActionContext::Global => 'actions', + ActionContext::Row => 'row_actions', + ActionContext::Batch => 'batch_actions', + }; + + $this->data[$action->getDataTable()->getName()][$actionsKey][$action->getName()]['view_vars'] = $this->ksort($view->vars); } - public function collectFilter(DataTableInterface $dataTable, FiltrationData $filtrationData): void + public static function getTemplate(): ?string { - $dataToRedirect = []; + return '@KreyuDataTable/data_collector/template.html.twig'; + } - foreach ($filtrationData->getFilters() as $field => $data) { - $dataToRedirect[] = $this->dataExtractor->extractFilter($dataTable, $field, $data); + public function getData(): array|Data + { + return $this->data; + } + + /** + * @internal + */ + private function mapWithKeys(callable $callback, array $array): array + { + $data = []; + + foreach ($array as $value) { + foreach ($callback($value) as $mapKey => $mapValue) { + $data[$mapKey] = $mapValue; + } } - $this->data[$dataTable->getConfig()->getName()]['filters'] = $dataToRedirect; + return $data; } - public function getData(): array|Data + /** + * @internal + */ + private function ksort(array $array): array { - return $this->data; + $copy = $array; + + ksort($copy); + + return $copy; } } diff --git a/src/DataCollector/DataTableDataCollectorInterface.php b/src/DataCollector/DataTableDataCollectorInterface.php index 665f6e4d..f3fa6d35 100644 --- a/src/DataCollector/DataTableDataCollectorInterface.php +++ b/src/DataCollector/DataTableDataCollectorInterface.php @@ -4,14 +4,37 @@ namespace Kreyu\Bundle\DataTableBundle\DataCollector; +use Kreyu\Bundle\DataTableBundle\Action\ActionInterface; +use Kreyu\Bundle\DataTableBundle\Action\ActionView; +use Kreyu\Bundle\DataTableBundle\Column\ColumnHeaderView; +use Kreyu\Bundle\DataTableBundle\Column\ColumnInterface; +use Kreyu\Bundle\DataTableBundle\Column\ColumnValueView; use Kreyu\Bundle\DataTableBundle\DataTableInterface; +use Kreyu\Bundle\DataTableBundle\DataTableView; +use Kreyu\Bundle\DataTableBundle\Filter\FilterInterface; +use Kreyu\Bundle\DataTableBundle\Filter\FilterView; use Kreyu\Bundle\DataTableBundle\Filter\FiltrationData; +use Kreyu\Bundle\DataTableBundle\Sorting\SortingData; use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface; use Symfony\Component\VarDumper\Cloner\Data; interface DataTableDataCollectorInterface extends DataCollectorInterface { - public function collectFilter(DataTableInterface $dataTable, FiltrationData $filtrationData): void; + public function collectDataTable(DataTableInterface $dataTable): void; + + public function collectDataTableView(DataTableInterface $dataTable, DataTableView $view): void; + + public function collectColumnHeaderView(ColumnInterface $column, ColumnHeaderView $view): void; + + public function collectColumnValueView(ColumnInterface $column, ColumnValueView $view): void; + + public function collectSortingData(DataTableInterface $dataTable, SortingData $data): void; + + public function collectFilterView(FilterInterface $filter, FilterView $view): void; + + public function collectFiltrationData(DataTableInterface $dataTable, FiltrationData $data): void; + + public function collectActionView(ActionInterface $action, ActionView $view): void; public function getData(): array|Data; } diff --git a/src/DataCollector/DataTableDataExtractor.php b/src/DataCollector/DataTableDataExtractor.php index fc0e95ec..fbfc716f 100644 --- a/src/DataCollector/DataTableDataExtractor.php +++ b/src/DataCollector/DataTableDataExtractor.php @@ -4,18 +4,124 @@ namespace Kreyu\Bundle\DataTableBundle\DataCollector; +use Kreyu\Bundle\DataTableBundle\Action\ActionInterface; +use Kreyu\Bundle\DataTableBundle\Column\ColumnInterface; use Kreyu\Bundle\DataTableBundle\DataTableInterface; -use Kreyu\Bundle\DataTableBundle\Filter\FilterData; +use Kreyu\Bundle\DataTableBundle\DataTableView; +use Kreyu\Bundle\DataTableBundle\Exporter\ExporterInterface; +use Kreyu\Bundle\DataTableBundle\Filter\FilterInterface; +use Kreyu\Bundle\DataTableBundle\ValueRowView; +use Symfony\Component\VarDumper\Caster\ClassStub; class DataTableDataExtractor implements DataTableDataExtractorInterface { - public function extractFilter(DataTableInterface $dataTable, string $field, FilterData $data): array + public function extractDataTableConfiguration(DataTableInterface $dataTable): array { - return [ - 'name' => $field, - 'operator' => $data->getOperator()->getLabel(), - 'value' => $data->getValue(), - 'type' => $dataTable->getFilter($field)->getConfig()->getType()->getInnerType()::class, + $data = [ + 'name' => $dataTable->getName(), + 'type_class' => new ClassStub($dataTable->getConfig()->getType()->getInnerType()::class), + 'passed_options' => $dataTable->getConfig()->getAttribute('data_collector/passed_options', []), + 'resolved_options' => $dataTable->getConfig()->getOptions(), + 'features' => [ + 'pagination' => [ + 'enabled' => $dataTable->getConfig()->isPaginationEnabled(), + 'persistence_enabled' => $dataTable->getConfig()->isPaginationPersistenceEnabled(), + ], + 'sorting' => [ + 'enabled' => $dataTable->getConfig()->isSortingEnabled(), + 'persistence_enabled' => $dataTable->getConfig()->isSortingPersistenceEnabled(), + ], + 'filtration' => [ + 'enabled' => $dataTable->getConfig()->isFiltrationEnabled(), + 'persistence_enabled' => $dataTable->getConfig()->isFiltrationPersistenceEnabled(), + ], + 'exporting' => [ + 'enabled' => $dataTable->getConfig()->isExportingEnabled(), + ], + 'personalization' => [ + 'enabled' => $dataTable->getConfig()->isPersonalizationEnabled(), + 'persistence_enabled' => $dataTable->getConfig()->isPersonalizationPersistenceEnabled(), + ], + ], + 'page' => $dataTable->getPagination()->getCurrentPageNumber(), + 'per_page' => $dataTable->getPagination()->getItemNumberPerPage(), + 'total_count' => $dataTable->getPagination()->getTotalItemCount(), ]; + + ksort($data['passed_options']); + ksort($data['resolved_options']); + + return $data; + } + + public function extractColumnConfiguration(ColumnInterface $column): array + { + $data = [ + 'name' => $column->getName(), + 'type_class' => new ClassStub($column->getConfig()->getType()->getInnerType()::class), + 'passed_options' => $column->getConfig()->getAttribute('data_collector/passed_options', []), + 'resolved_options' => $column->getConfig()->getOptions(), + ]; + + ksort($data['passed_options']); + ksort($data['resolved_options']); + + return $data; + } + + public function extractFilterConfiguration(FilterInterface $filter): array + { + $data = [ + 'name' => $filter->getName(), + 'type_class' => new ClassStub($filter->getConfig()->getType()->getInnerType()::class), + 'passed_options' => $filter->getConfig()->getAttribute('data_collector/passed_options', []), + 'resolved_options' => $filter->getConfig()->getOptions(), + ]; + + ksort($data['passed_options']); + ksort($data['resolved_options']); + + return $data; + } + + public function extractActionConfiguration(ActionInterface $action): array + { + $data = [ + 'name' => $action->getName(), + 'type_class' => new ClassStub($action->getConfig()->getType()->getInnerType()::class), + 'passed_options' => $action->getConfig()->getAttribute('data_collector/passed_options', []), + 'resolved_options' => $action->getConfig()->getOptions(), + ]; + + ksort($data['passed_options']); + ksort($data['resolved_options']); + + return $data; + } + + public function extractExporterConfiguration(ExporterInterface $exporter): array + { + $data = [ + 'name' => $exporter->getName(), + 'type_class' => new ClassStub($exporter->getConfig()->getType()->getInnerType()::class), + 'passed_options' => $exporter->getConfig()->getAttribute('data_collector/passed_options', []), + 'resolved_options' => $exporter->getConfig()->getOptions(), + ]; + + ksort($data['passed_options']); + ksort($data['resolved_options']); + + return $data; + } + + public function extractValueRows(DataTableView $view): array + { + $data = []; + + foreach ($view->valueRows as $valueRow) { + $data[] = $valueRow->data; + } + + return $data; } } diff --git a/src/DataCollector/DataTableDataExtractorInterface.php b/src/DataCollector/DataTableDataExtractorInterface.php index 6d772921..7a333aab 100644 --- a/src/DataCollector/DataTableDataExtractorInterface.php +++ b/src/DataCollector/DataTableDataExtractorInterface.php @@ -4,10 +4,24 @@ namespace Kreyu\Bundle\DataTableBundle\DataCollector; +use Kreyu\Bundle\DataTableBundle\Action\ActionInterface; +use Kreyu\Bundle\DataTableBundle\Column\ColumnInterface; use Kreyu\Bundle\DataTableBundle\DataTableInterface; -use Kreyu\Bundle\DataTableBundle\Filter\FilterData; +use Kreyu\Bundle\DataTableBundle\DataTableView; +use Kreyu\Bundle\DataTableBundle\Exporter\ExporterInterface; +use Kreyu\Bundle\DataTableBundle\Filter\FilterInterface; interface DataTableDataExtractorInterface { - public function extractFilter(DataTableInterface $dataTable, string $field, FilterData $data): array; + public function extractDataTableConfiguration(DataTableInterface $dataTable): array; + + public function extractColumnConfiguration(ColumnInterface $column): array; + + public function extractFilterConfiguration(FilterInterface $filter): array; + + public function extractActionConfiguration(ActionInterface $action): array; + + public function extractExporterConfiguration(ExporterInterface $exporter): array; + + public function extractValueRows(DataTableView $view): array; } diff --git a/src/DataCollector/EventListener/DataCollectorListener.php b/src/DataCollector/EventListener/DataCollectorListener.php index d629784a..998f67b3 100644 --- a/src/DataCollector/EventListener/DataCollectorListener.php +++ b/src/DataCollector/EventListener/DataCollectorListener.php @@ -5,8 +5,10 @@ namespace Kreyu\Bundle\DataTableBundle\DataCollector\EventListener; use Kreyu\Bundle\DataTableBundle\DataCollector\DataTableDataCollectorInterface; +use Kreyu\Bundle\DataTableBundle\Event\DataTableEvent; use Kreyu\Bundle\DataTableBundle\Event\DataTableEvents; use Kreyu\Bundle\DataTableBundle\Event\DataTableFiltrationEvent; +use Kreyu\Bundle\DataTableBundle\Event\DataTableSortingEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class DataCollectorListener implements EventSubscriberInterface @@ -19,12 +21,24 @@ public function __construct( public static function getSubscribedEvents(): array { return [ - DataTableEvents::POST_FILTER => ['onPostFilter', 255], + DataTableEvents::POST_INITIALIZE => ['collectDataTable', 255], + DataTableEvents::POST_FILTER => ['collectFiltrationData', 255], + DataTableEvents::POST_SORT => ['collectSortingData', 255], ]; } - public function onPostFilter(DataTableFiltrationEvent $event): void + public function collectDataTable(DataTableEvent $event): void { - $this->dataCollector->collectFilter($event->getDataTable(), $event->getFiltrationData()); + $this->dataCollector->collectDataTable($event->getDataTable()); + } + + public function collectFiltrationData(DataTableFiltrationEvent $event): void + { + $this->dataCollector->collectFiltrationData($event->getDataTable(), $event->getFiltrationData()); + } + + public function collectSortingData(DataTableSortingEvent $event): void + { + $this->dataCollector->collectSortingData($event->getDataTable(), $event->getSortingData()); } } diff --git a/src/DataCollector/Proxy/ResolvedActionTypeDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedActionTypeDataCollectorProxy.php new file mode 100644 index 00000000..8d581850 --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedActionTypeDataCollectorProxy.php @@ -0,0 +1,80 @@ +proxiedType->getBlockPrefix(); + } + + public function getBlockPrefixHierarchy(): array + { + return $this->proxiedType->getBlockPrefixHierarchy(); + } + + public function getParent(): ?ResolvedActionTypeInterface + { + return $this->proxiedType->getParent(); + } + + public function getInnerType(): ActionTypeInterface + { + return $this->proxiedType->getInnerType(); + } + + public function getTypeExtensions(): array + { + return $this->proxiedType->getTypeExtensions(); + } + + public function createBuilder(ActionFactoryInterface $factory, string $name, array $options): ActionBuilderInterface + { + $builder = $this->proxiedType->createBuilder($factory, $name, $options); + $builder->setAttribute('data_collector/passed_options', $options); + $builder->setType($this); + + return $builder; + } + + public function createView(ActionInterface $action, ColumnValueView|DataTableView $parent): ActionView + { + return $this->proxiedType->createView($action, $parent); + } + + public function buildAction(ActionBuilderInterface $builder, array $options): void + { + $this->proxiedType->buildAction($builder, $options); + } + + public function buildView(ActionView $view, ActionInterface $action, array $options): void + { + $this->proxiedType->buildView($view, $action, $options); + $this->dataCollector->collectActionView($action, $view); + } + + public function getOptionsResolver(): OptionsResolver + { + return $this->proxiedType->getOptionsResolver(); + } +} diff --git a/src/DataCollector/Proxy/ResolvedActionTypeFactoryDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedActionTypeFactoryDataCollectorProxy.php new file mode 100644 index 00000000..a18997bd --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedActionTypeFactoryDataCollectorProxy.php @@ -0,0 +1,27 @@ +proxiedFactory->createResolvedType($type, $typeExtensions, $parent), + $this->dataCollector, + ); + } +} diff --git a/src/DataCollector/Proxy/ResolvedColumnTypeDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedColumnTypeDataCollectorProxy.php new file mode 100644 index 00000000..eea63c69 --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedColumnTypeDataCollectorProxy.php @@ -0,0 +1,107 @@ +proxiedType->getBlockPrefix(); + } + + public function getParent(): ?ResolvedColumnTypeInterface + { + return $this->proxiedType->getParent(); + } + + public function getInnerType(): ColumnTypeInterface + { + return $this->proxiedType->getInnerType(); + } + + public function getTypeExtensions(): array + { + return $this->proxiedType->getTypeExtensions(); + } + + public function createBuilder(ColumnFactoryInterface $factory, string $name, array $options): ColumnBuilderInterface + { + $builder = $this->proxiedType->createBuilder($factory, $name, $options); + $builder->setAttribute('data_collector/passed_options', $options); + $builder->setType($this); + + return $builder; + } + + public function createHeaderView(ColumnInterface $column, ?HeaderRowView $parent = null): ColumnHeaderView + { + return $this->proxiedType->createHeaderView($column, $parent); + } + + public function createValueView(ColumnInterface $column, ?ValueRowView $parent = null): ColumnValueView + { + return $this->proxiedType->createValueView($column, $parent); + } + + public function createExportHeaderView(ColumnInterface $column, ?HeaderRowView $parent = null): ColumnHeaderView + { + return $this->proxiedType->createExportHeaderView($column, $parent); + } + + public function createExportValueView(ColumnInterface $column, ?ValueRowView $parent = null): ColumnValueView + { + return $this->proxiedType->createExportValueView($column, $parent); + } + + public function buildColumn(ColumnBuilderInterface $builder, array $options): void + { + $this->proxiedType->buildColumn($builder, $options); + } + + public function buildHeaderView(ColumnHeaderView $view, ColumnInterface $column, array $options): void + { + $this->proxiedType->buildHeaderView($view, $column, $options); + $this->dataCollector->collectColumnHeaderView($column, $view); + } + + public function buildValueView(ColumnValueView $view, ColumnInterface $column, array $options): void + { + $this->proxiedType->buildValueView($view, $column, $options); + $this->dataCollector->collectColumnValueView($column, $view); + } + + public function buildExportHeaderView(ColumnHeaderView $view, ColumnInterface $column, array $options): void + { + $this->proxiedType->buildExportHeaderView($view, $column, $options); + } + + public function buildExportValueView(ColumnValueView $view, ColumnInterface $column, array $options): void + { + $this->proxiedType->buildExportValueView($view, $column, $options); + } + + public function getOptionsResolver(): OptionsResolver + { + return $this->proxiedType->getOptionsResolver(); + } +} diff --git a/src/DataCollector/Proxy/ResolvedColumnTypeFactoryDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedColumnTypeFactoryDataCollectorProxy.php new file mode 100644 index 00000000..789aaa2b --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedColumnTypeFactoryDataCollectorProxy.php @@ -0,0 +1,27 @@ +proxiedFactory->createResolvedType($type, $typeExtensions, $parent), + $this->dataCollector, + ); + } +} diff --git a/src/DataCollector/Proxy/ResolvedDataTableTypeDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedDataTableTypeDataCollectorProxy.php new file mode 100644 index 00000000..1637f70c --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedDataTableTypeDataCollectorProxy.php @@ -0,0 +1,85 @@ +proxiedType->getName(); + } + + public function getParent(): ?ResolvedDataTableTypeInterface + { + return $this->proxiedType->getParent(); + } + + public function getInnerType(): DataTableTypeInterface + { + return $this->proxiedType->getInnerType(); + } + + public function getTypeExtensions(): array + { + return $this->proxiedType->getTypeExtensions(); + } + + public function createBuilder(DataTableFactoryInterface $factory, string $name, ?ProxyQueryInterface $query = null, array $options = []): DataTableBuilderInterface + { + $builder = $this->proxiedType->createBuilder($factory, $name, $query, $options); + $builder->setAttribute('data_collector/passed_options', $options); + $builder->setType($this); + + return $builder; + } + + public function createView(DataTableInterface $dataTable): DataTableView + { + return $this->proxiedType->createView($dataTable); + } + + public function createExportView(DataTableInterface $dataTable): DataTableView + { + return $this->proxiedType->createExportView($dataTable); + } + + public function buildDataTable(DataTableBuilderInterface $builder, array $options): void + { + $this->proxiedType->buildDataTable($builder, $options); + } + + public function buildView(DataTableView $view, DataTableInterface $dataTable, array $options): void + { + $this->proxiedType->buildView($view, $dataTable, $options); + + $this->dataCollector->collectDataTableView($dataTable, $view); + } + + public function buildExportView(DataTableView $view, DataTableInterface $dataTable, array $options): void + { + $this->proxiedType->buildExportView($view, $dataTable, $options); + } + + public function getOptionsResolver(): OptionsResolver + { + return $this->proxiedType->getOptionsResolver(); + } +} diff --git a/src/DataCollector/Proxy/ResolvedDataTableTypeFactoryDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedDataTableTypeFactoryDataCollectorProxy.php new file mode 100644 index 00000000..006eaa20 --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedDataTableTypeFactoryDataCollectorProxy.php @@ -0,0 +1,27 @@ +proxiedFactory->createResolvedType($type, $typeExtensions, $parent), + $this->dataCollector, + ); + } +} diff --git a/src/DataCollector/Proxy/ResolvedExporterTypeDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedExporterTypeDataCollectorProxy.php new file mode 100644 index 00000000..d4ac513e --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedExporterTypeDataCollectorProxy.php @@ -0,0 +1,58 @@ +proxiedType->getName(); + } + + public function getParent(): ?ResolvedExporterTypeInterface + { + return $this->proxiedType->getParent(); + } + + public function getInnerType(): ExporterTypeInterface + { + return $this->proxiedType->getInnerType(); + } + + public function getTypeExtensions(): array + { + return $this->proxiedType->getTypeExtensions(); + } + + public function createBuilder(ExporterFactoryInterface $factory, string $name, array $options): ExporterBuilderInterface + { + $builder = $this->proxiedType->createBuilder($factory, $name, $options); + $builder->setAttribute('data_collector/passed_options', $options); + $builder->setType($this); + + return $builder; + } + + public function buildExporter(ExporterBuilderInterface $builder, array $options): void + { + $this->proxiedType->buildExporter($builder, $options); + } + + public function getOptionsResolver(): OptionsResolver + { + return $this->proxiedType->getOptionsResolver(); + } +} diff --git a/src/DataCollector/Proxy/ResolvedExporterTypeFactoryDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedExporterTypeFactoryDataCollectorProxy.php new file mode 100644 index 00000000..e63d4213 --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedExporterTypeFactoryDataCollectorProxy.php @@ -0,0 +1,24 @@ +proxiedFactory->createResolvedType($type, $typeExtensions, $parent), + ); + } +} diff --git a/src/DataCollector/Proxy/ResolvedFilterTypeDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedFilterTypeDataCollectorProxy.php new file mode 100644 index 00000000..e8f29afd --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedFilterTypeDataCollectorProxy.php @@ -0,0 +1,74 @@ +proxiedType->getBlockPrefix(); + } + + public function getParent(): ?ResolvedFilterTypeInterface + { + return $this->proxiedType->getParent(); + } + + public function getInnerType(): FilterTypeInterface + { + return $this->proxiedType->getInnerType(); + } + + public function getTypeExtensions(): array + { + return $this->proxiedType->getTypeExtensions(); + } + + public function createBuilder(FilterFactoryInterface $factory, string $name, array $options): FilterBuilderInterface + { + $builder = $this->proxiedType->createBuilder($factory, $name, $options); + $builder->setType($this); + + return $builder; + } + + public function createView(FilterInterface $filter, FilterData $data, DataTableView $parent): FilterView + { + return $this->proxiedType->createView($filter, $data, $parent); + } + + public function buildFilter(FilterBuilderInterface $builder, array $options): void + { + $this->proxiedType->buildFilter($builder, $options); + } + + public function buildView(FilterView $view, FilterInterface $filter, FilterData $data, array $options): void + { + $this->proxiedType->buildView($view, $filter, $data, $options); + $this->dataCollector->collectFilterView($filter, $view); + } + + public function getOptionsResolver(): OptionsResolver + { + return $this->proxiedType->getOptionsResolver(); + } +} diff --git a/src/DataCollector/Proxy/ResolvedFilterTypeFactoryDataCollectorProxy.php b/src/DataCollector/Proxy/ResolvedFilterTypeFactoryDataCollectorProxy.php new file mode 100644 index 00000000..219ea737 --- /dev/null +++ b/src/DataCollector/Proxy/ResolvedFilterTypeFactoryDataCollectorProxy.php @@ -0,0 +1,27 @@ +proxiedFactory->createResolvedType($type, $typeExtensions, $parent), + $this->dataCollector, + ); + } +} diff --git a/src/DataTable.php b/src/DataTable.php index c3fdf23b..d47e957f 100755 --- a/src/DataTable.php +++ b/src/DataTable.php @@ -132,6 +132,8 @@ public function initialize(): void return; } + $this->dispatch(DataTableEvents::PRE_INITIALIZE, new DataTableEvent($this)); + if ($paginationData = $this->getInitialPaginationData()) { $this->paginate($paginationData, false); } @@ -149,6 +151,8 @@ public function initialize(): void } $this->initialized = true; + + $this->dispatch(DataTableEvents::POST_INITIALIZE, new DataTableEvent($this)); } public function getName(): string diff --git a/src/DataTableConfigBuilder.php b/src/DataTableConfigBuilder.php index 780f74e6..bf06ad09 100755 --- a/src/DataTableConfigBuilder.php +++ b/src/DataTableConfigBuilder.php @@ -63,6 +63,7 @@ class DataTableConfigBuilder implements DataTableConfigBuilderInterface private ?RequestHandlerInterface $requestHandler = null; private array $themes = []; + private array $attributes = []; private array $headerRowAttributes = []; private array $valueRowAttributes = []; @@ -695,6 +696,43 @@ public function setThemes(array $themes): static return $this; } + public function getAttributes(): array + { + return $this->attributes; + } + + public function hasAttribute(string $name): bool + { + return array_key_exists($name, $this->attributes); + } + + public function getAttribute(string $name, mixed $default = null): mixed + { + return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default; + } + + public function setAttribute(string $name, mixed $value): static + { + if ($this->locked) { + throw $this->createBuilderLockedException(); + } + + $this->attributes[$name] = $value; + + return $this; + } + + public function setAttributes(array $attributes): static + { + if ($this->locked) { + throw $this->createBuilderLockedException(); + } + + $this->attributes = $attributes; + + return $this; + } + public function getHeaderRowAttributes(): array { return $this->headerRowAttributes; diff --git a/src/DataTableConfigBuilderInterface.php b/src/DataTableConfigBuilderInterface.php index 41a8cb32..7569ba2a 100755 --- a/src/DataTableConfigBuilderInterface.php +++ b/src/DataTableConfigBuilderInterface.php @@ -107,6 +107,10 @@ public function addTheme(string $theme): static; public function setThemes(array $themes): static; + public function setAttribute(string $name, mixed $value): static; + + public function setAttributes(array $attributes): static; + public function setHeaderRowAttribute(string $name, mixed $value): static; public function setHeaderRowAttributes(array $headerRowAttributes): static; diff --git a/src/DataTableConfigInterface.php b/src/DataTableConfigInterface.php index ed3f092b..3a98b8c9 100755 --- a/src/DataTableConfigInterface.php +++ b/src/DataTableConfigInterface.php @@ -103,6 +103,12 @@ public function getDefaultPaginationData(): ?PaginationData; public function getRequestHandler(): ?RequestHandlerInterface; + public function getAttributes(): array; + + public function hasAttribute(string $name): bool; + + public function getAttribute(string $name, mixed $default = null): mixed; + public function getHeaderRowAttributes(): array; public function hasHeaderRowAttribute(string $name): bool; diff --git a/src/Debug/TraceableDataTableFactory.php b/src/Debug/TraceableDataTableFactory.php deleted file mode 100644 index c83b8a6b..00000000 --- a/src/Debug/TraceableDataTableFactory.php +++ /dev/null @@ -1,47 +0,0 @@ -dataTableFactory->create($type, $data, $options); - - $this->dataCollector->collectDataTable($dataTable); - - return $dataTable; - } - - public function createNamed(string $name, string $type, mixed $data = null, array $options = []): DataTableInterface - { - $dataTable = $this->dataTableFactory->createNamed($name, $type, $data, $options); - - $this->dataCollector->collectDataTable($dataTable); - - return $dataTable; - } - - public function createBuilder(string $type, mixed $data = null, array $options = []): DataTableBuilderInterface - { - return $this->dataTableFactory->createBuilder($type, $data, $options); - } - - public function createNamedBuilder(string $name, string $type, mixed $data = null, array $options = []): DataTableBuilderInterface - { - return $this->dataTableFactory->createNamedBuilder($name, $type, $data, $options); - } -} diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 36aa1a82..8e6dd949 100755 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -144,6 +144,14 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->end() ->end() + ->arrayNode('profiler') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('max_depth') + ->defaultValue(3) + ->end() + ->end() + ->end() ->end() ; diff --git a/src/DependencyInjection/KreyuDataTableExtension.php b/src/DependencyInjection/KreyuDataTableExtension.php index 69fb45c4..57b9ddec 100755 --- a/src/DependencyInjection/KreyuDataTableExtension.php +++ b/src/DependencyInjection/KreyuDataTableExtension.php @@ -70,6 +70,12 @@ public function load(array $configs, ContainerBuilder $container): void ->getDefinition('kreyu_data_table.type.data_table') ->setArgument('$defaults', $config['defaults']) ; + + if ($container->getParameter('kernel.debug')) { + $container + ->getDefinition('kreyu_data_table.debug.data_collector') + ->setArgument('$maxDepth', $config['profiler']['max_depth']); + } } public function prepend(ContainerBuilder $container): void diff --git a/src/Event/DataTableEvents.php b/src/Event/DataTableEvents.php index fbceec7d..54a7a0f2 100755 --- a/src/Event/DataTableEvents.php +++ b/src/Event/DataTableEvents.php @@ -8,6 +8,16 @@ final class DataTableEvents { + /** + * @see DataTableInterface::initialize() + */ + public const PRE_INITIALIZE = 'kreyu_data_table.pre_initialize'; + + /** + * @see DataTableInterface::initialize() + */ + public const POST_INITIALIZE = 'kreyu_data_table.post_initialize'; + /** * @see DataTableInterface::paginate() */ diff --git a/src/Exporter/ExporterConfigBuilder.php b/src/Exporter/ExporterConfigBuilder.php index 850323b2..3a66b022 100755 --- a/src/Exporter/ExporterConfigBuilder.php +++ b/src/Exporter/ExporterConfigBuilder.php @@ -9,6 +9,8 @@ class ExporterConfigBuilder implements ExporterConfigBuilderInterface { + private array $attributes = []; + protected bool $locked = false; public function __construct( @@ -87,6 +89,43 @@ public function setOption(string $name, mixed $value): static return $this; } + public function getAttributes(): array + { + return $this->attributes; + } + + public function hasAttribute(string $name): bool + { + return array_key_exists($name, $this->attributes); + } + + public function getAttribute(string $name, mixed $default = null): mixed + { + return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default; + } + + public function setAttribute(string $name, mixed $value): static + { + if ($this->locked) { + throw $this->createBuilderLockedException(); + } + + $this->attributes[$name] = $value; + + return $this; + } + + public function setAttributes(array $attributes): static + { + if ($this->locked) { + throw $this->createBuilderLockedException(); + } + + $this->attributes = $attributes; + + return $this; + } + public function getExporterConfig(): ExporterConfigInterface { if ($this->locked) { diff --git a/src/Exporter/ExporterConfigBuilderInterface.php b/src/Exporter/ExporterConfigBuilderInterface.php index bdb629c9..0ee4ce6b 100755 --- a/src/Exporter/ExporterConfigBuilderInterface.php +++ b/src/Exporter/ExporterConfigBuilderInterface.php @@ -25,5 +25,9 @@ public function setOptions(array $options): static; */ public function setOption(string $name, mixed $value): static; + public function setAttribute(string $name, mixed $value): static; + + public function setAttributes(array $attributes): static; + public function getExporterConfig(): ExporterConfigInterface; } diff --git a/src/Exporter/ExporterConfigInterface.php b/src/Exporter/ExporterConfigInterface.php index a42d00cc..bd6a64e4 100755 --- a/src/Exporter/ExporterConfigInterface.php +++ b/src/Exporter/ExporterConfigInterface.php @@ -17,4 +17,10 @@ public function getOptions(): array; public function hasOption(string $name): bool; public function getOption(string $name, mixed $default = null): mixed; + + public function getAttributes(): array; + + public function hasAttribute(string $name): bool; + + public function getAttribute(string $name, mixed $default = null): mixed; } diff --git a/src/Filter/FilterConfigBuilder.php b/src/Filter/FilterConfigBuilder.php index abb9aeb2..23692187 100755 --- a/src/Filter/FilterConfigBuilder.php +++ b/src/Filter/FilterConfigBuilder.php @@ -16,6 +16,7 @@ class FilterConfigBuilder implements FilterConfigBuilderInterface { protected bool $locked = false; + private array $attributes = []; private FilterHandlerInterface $handler; private string $formType = TextType::class; private array $formOptions = []; @@ -93,6 +94,43 @@ public function getOption(string $name, mixed $default = null): mixed return array_key_exists($name, $this->options) ? $this->options[$name] : $default; } + public function getAttributes(): array + { + return $this->attributes; + } + + public function hasAttribute(string $name): bool + { + return array_key_exists($name, $this->attributes); + } + + public function getAttribute(string $name, mixed $default = null): mixed + { + return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default; + } + + public function setAttribute(string $name, mixed $value): static + { + if ($this->locked) { + throw $this->createBuilderLockedException(); + } + + $this->attributes[$name] = $value; + + return $this; + } + + public function setAttributes(array $attributes): static + { + if ($this->locked) { + throw $this->createBuilderLockedException(); + } + + $this->attributes = $attributes; + + return $this; + } + public function getHandler(): FilterHandlerInterface { if (!isset($this->handler)) { diff --git a/src/Filter/FilterConfigBuilderInterface.php b/src/Filter/FilterConfigBuilderInterface.php index 130fd52a..6247267e 100755 --- a/src/Filter/FilterConfigBuilderInterface.php +++ b/src/Filter/FilterConfigBuilderInterface.php @@ -18,6 +18,10 @@ public function setType(ResolvedFilterTypeInterface $type): static; public function setHandler(FilterHandlerInterface $handler): static; + public function setAttribute(string $name, mixed $value): static; + + public function setAttributes(array $attributes): static; + /** * @param class-string $formType */ diff --git a/src/Filter/FilterConfigInterface.php b/src/Filter/FilterConfigInterface.php index 7b69699c..b5ae3594 100755 --- a/src/Filter/FilterConfigInterface.php +++ b/src/Filter/FilterConfigInterface.php @@ -22,6 +22,12 @@ public function hasOption(string $name): bool; public function getOption(string $name, mixed $default = null): mixed; + public function getAttributes(): array; + + public function hasAttribute(string $name): bool; + + public function getAttribute(string $name, mixed $default = null): mixed; + public function getHandler(): FilterHandlerInterface; /** diff --git a/src/Resources/config/debug.php b/src/Resources/config/debug.php index 42ad5b10..42216c9a 100644 --- a/src/Resources/config/debug.php +++ b/src/Resources/config/debug.php @@ -4,21 +4,18 @@ use Kreyu\Bundle\DataTableBundle\DataCollector\DataTableDataCollector; use Kreyu\Bundle\DataTableBundle\DataCollector\DataTableDataExtractor; +use Kreyu\Bundle\DataTableBundle\DataCollector\Proxy\ResolvedActionTypeFactoryDataCollectorProxy; +use Kreyu\Bundle\DataTableBundle\DataCollector\Proxy\ResolvedColumnTypeFactoryDataCollectorProxy; +use Kreyu\Bundle\DataTableBundle\DataCollector\Proxy\ResolvedDataTableTypeFactoryDataCollectorProxy; +use Kreyu\Bundle\DataTableBundle\DataCollector\Proxy\ResolvedExporterTypeFactoryDataCollectorProxy; +use Kreyu\Bundle\DataTableBundle\DataCollector\Proxy\ResolvedFilterTypeFactoryDataCollectorProxy; use Kreyu\Bundle\DataTableBundle\DataCollector\Type\DataCollectorTypeExtension; -use Kreyu\Bundle\DataTableBundle\Debug\TraceableDataTableFactory; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $container) { $container->services() - ->set('kreyu_data_table.debug.factory', TraceableDataTableFactory::class) - ->decorate('kreyu_data_table.factory') - ->args([ - service('.inner'), - service('kreyu_data_table.debug.data_collector'), - ]) - ->set('kreyu_data_table.debug.data_collector', DataTableDataCollector::class) ->args([service('kreyu_data_table.debug.data_collector.extractor')]) ->tag('data_collector') @@ -28,5 +25,39 @@ ->set('kreyu_data_table.debug.data_collector.type_extension', DataCollectorTypeExtension::class) ->args([service('kreyu_data_table.debug.data_collector')]) ->tag('kreyu_data_table.type_extension') + + ->set('kreyu_data_table.debug.resolved_type_factory', ResolvedDataTableTypeFactoryDataCollectorProxy::class) + ->decorate('kreyu_data_table.resolved_type_factory') + ->args([ + service('.inner'), + service('kreyu_data_table.debug.data_collector'), + ]) + + ->set('kreyu_data_table.debug.column.resolved_type_factory', ResolvedColumnTypeFactoryDataCollectorProxy::class) + ->decorate('kreyu_data_table.column.resolved_type_factory') + ->args([ + service('.inner'), + service('kreyu_data_table.debug.data_collector'), + ]) + + ->set('kreyu_data_table.debug.filter.resolved_type_factory', ResolvedFilterTypeFactoryDataCollectorProxy::class) + ->decorate('kreyu_data_table.filter.resolved_type_factory') + ->args([ + service('.inner'), + service('kreyu_data_table.debug.data_collector'), + ]) + + ->set('kreyu_data_table.debug.action.resolved_type_factory', ResolvedActionTypeFactoryDataCollectorProxy::class) + ->decorate('kreyu_data_table.action.resolved_type_factory') + ->args([ + service('.inner'), + service('kreyu_data_table.debug.data_collector'), + ]) + + ->set('kreyu_data_table.debug.exporter.resolved_type_factory', ResolvedExporterTypeFactoryDataCollectorProxy::class) + ->decorate('kreyu_data_table.exporter.resolved_type_factory') + ->args([ + service('.inner'), + ]) ; }; diff --git a/src/Resources/views/data_collector/template.html.twig b/src/Resources/views/data_collector/template.html.twig index 3f4ba297..a1d837b1 100644 --- a/src/Resources/views/data_collector/template.html.twig +++ b/src/Resources/views/data_collector/template.html.twig @@ -1,23 +1,25 @@ {% extends '@WebProfiler/Profiler/layout.html.twig' %} {% block toolbar %} - {% set icon %} - {{ source('@KreyuDataTable/data_collector/Icon/table-heart.svg') }} - {{ collector.dataTables|length }} - {% endset %} - - {% set text %} -
- Number of data tables - {{ collector.dataTables|length }} -
- {% endset %} + {% if collector.data|length %} + {% set icon %} + {{ source('@KreyuDataTable/data_collector/Icon/table-heart.svg') }} + {{ collector.data|length }} + {% endset %} + + {% set text %} +
+ Number of data tables + {{ collector.data|length }} +
+ {% endset %} - {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true }) }} + {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true }) }} + {% endif %} {% endblock %} {% block menu %} - + {{ source('@KreyuDataTable/data_collector/Icon/table-heart.svg') }} @@ -28,84 +30,689 @@ {% block panel %}

Data Tables

-
- {% for dataTable in collector.dataTables %} -

{{ dataTable }}

+ + +
+
    + {% for data_table in collector.data %} +
  • +
    + + + + {{ data_table.name }} + +
    + + +
  • + {% endfor %} +
-{% endblock %} -{% macro render_columns_tab(columnsData) %} -
-

Columns {{ columnsData|length }}

-
- {% if not columnsData|length %} -
-

No columns found.

+
+
+ {% for data_table in collector.data %} +
+

{{ data_table.name }}

+ +
+ Type class: + {{ profiler_dump(data_table.type_class) }} +
+ +
+
+

Overview

+ +
+ {{ _self.render_data_table_overview(data_table) }} +
+
+ +
+

Value Rows

+ +
+ {{ _self.render_value_rows(data_table) }} +
+
+ +
+

Passed Options

+ +
+ {{ _self.render_passed_options(data_table, 'data table') }} +
+
+ +
+

Resolved Options

+ +
+ {{ _self.render_resolved_options(data_table) }} +
+
+ +
+

View Vars

+ +
+ {{ _self.render_view_variables(data_table.view_vars ?? []) }} +
+
+
- {% else %} - - - - - - - - - - {% for column in columnsData %} - - - - - - {% endfor %} - -
NameTypeOptions
{{ column.name }}{{ column.type }}{{ profiler_dump(column.options) }}
- {% endif %} + + {# Columns #} + {% for column in data_table.columns %} + + {% endfor %} + + {# Filters #} + {% for filter in data_table.filters %} + + {% endfor %} + + {# Actions #} + {% for action in data_table.actions %} + + {% endfor %} + + {# Row Actions #} + {% for action in data_table.row_actions %} + + {% endfor %} + + {# Batch Actions #} + {% for action in data_table.batch_actions %} + + {% endfor %} + + {# Exporters #} + {% for exporter in data_table.exporters %} + + {% endfor %} + {% endfor %}
+{% endblock %} + +{% macro render_data_table_overview(data) %} +
+
+ {{ data.total_count }} + Total item count +
+ + {% if data.resolved_options.seek('pagination_enabled') %} +
+
+ {{ data.page }} + Current page +
+
+ {{ data.per_page }} + Items per page +
+
+ {% endif %} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureEnabledPersistent
Pagination{{ _self.render_boolean(data.features.pagination.enabled) }}{{ _self.render_boolean(data.features.pagination.persistence_enabled) }}
Sorting{{ _self.render_boolean(data.features.sorting.enabled) }}{{ _self.render_boolean(data.features.sorting.persistence_enabled) }}
Filtration{{ _self.render_boolean(data.features.filtration.enabled) }}{{ _self.render_boolean(data.features.filtration.persistence_enabled) }}
Personalization{{ _self.render_boolean(data.features.personalization.enabled) }}{{ _self.render_boolean(data.features.personalization.persistence_enabled) }}
Exporting{{ _self.render_boolean(data.features.exporting.enabled) }}Not supported
{% endmacro %} -{% macro render_filters_tab(filtersData) %} -
-

Filters {{ filtersData|length }}

-
- {% if not filtersData|length %} -
-

No filters found.

+ +{% macro render_column_overview(column) %} +
+
+ {{ _self.render_boolean(column.resolved_options.visible) }} + Visible +
+ +
+
+ {{ _self.render_boolean(column.resolved_options.sort) }} + Sortable +
+ + {% if column.resolved_options.seek('sort') %} +
+ {{ _self.render_boolean(column.sort_direction|default(null)) }} + Sorted
- {% else %} - - - - - - - - - - - {% for filter in filtersData %} - - - - - - - {% endfor %} - -
NameTypeOperatorValue
{{ filter.name }}{{ filter.type }}{{ filter.operator }}{{ filter.value }}
+ + {% if column.sort_direction|default(null) %} +
+ {{ column.sort_direction|default(null) ? column.sort_direction|title : 'N/A' }} + Sort direction +
+ {% endif %} {% endif %}
+ +
+ +
+ {{ _self.render_boolean(column.resolved_options.export) }} + Exportable +
+ +
+ {{ _self.render_boolean(column.resolved_options.personalizable) }} + Personalizable +
+ + + + + + + + + + + + + + +
SettingValue
Priority{{ column.resolved_options.seek('priority') }}
+{% endmacro %} + +{% macro render_filter_overview(filter) %} +
+
+ {{ _self.render_boolean(filter.data.value|default(false)) }} + Applied +
+ +
+
+ {{ filter.operator_label|default('N/A') }} + Operator +
+
+ {{ _self.render_boolean(filter.resolved_options.operator_selectable) }} + Operator selectable +
+
+
+ + {% if filter.data.value|default(false) %} + + + + + + + + + + + + + +
DataDisplay value
{{ profiler_dump(filter.data, 1) }}{{ profiler_dump(filter.view_vars.seek('value'), 1) }}
+ {% else %} +
+

This filter was not applied.

+
+ {% endif %} +{% endmacro %} + +{% macro render_value_rows(data) %} + {% if data.value_rows ?? [] is not empty %} + + + + + + + + + {% for row_data in data.value_rows %} + + + + + {% endfor %} + +
Row IndexData
{{ loop.index }}{{ profiler_dump(row_data, 1) }}
+ {% else %} +
+

The data table has no value rows.

+
+ {% endif %} {% endmacro %} {% macro render_actions_tab(title, actionsData) %} @@ -130,7 +737,7 @@ {{ action.name }} {{ action.type }} - {{ profiler_dump(action.options) }} + {{ profiler_dump(action.options, 1) }} {% endfor %} @@ -139,3 +746,409 @@
{% endmacro %} + +{% macro render_passed_options(data, label) %} + {% if data.passed_options ?? [] is not empty %} + + + + + + + + + + {% for option, value in data.passed_options %} + + + + + + {% endfor %} + +
OptionPassed ValueResolved Value
{{ option }}{{ profiler_dump(value, 1) }} + {% set option_value = value.value|default(value) %} + {% set resolved_option_value = data.resolved_options[option].value|default(data.resolved_options[option]) %} + + {% if resolved_option_value == option_value %} + same as passed value + {% else %} + {{ profiler_dump(data.resolved_options.seek(option), 1) }} + {% endif %} +
+ {% else %} +
+

No options were passed when constructing this {{ label }}.

+
+ {% endif %} +{% endmacro %} + +{% macro render_resolved_options(data) %} + + + + + + + + + {% for option, value in data.resolved_options ?? [] %} + + + + + {% endfor %} + +
OptionValue
{{ option }}{{ profiler_dump(value, 1) }}
+{% endmacro %} + +{% macro render_view_variables(view_vars) %} + + + + + + + + + {% for variable, value in view_vars %} + + + + + {% endfor %} + +
VariableValue
{{ variable }}{{ profiler_dump(value, 1) }}
+{% endmacro %} + +{% macro render_boolean(value) %} + {% if value %} +
{{ source('@WebProfiler/Icon/yes.svg') }}
+ {% else %} +
{{ source('@WebProfiler/Icon/no.svg') }}
+ {% endif %} +{% endmacro %} + +{# Stylesheets mostly copied from Symfony Form integration with the Profiler #} +{# https://github.com/symfony/web-profiler-bundle/blob/master/Resources/views/Collector/form.html.twig #} +{% block stylesheets %} + {{ parent() }} + + +{% endblock %} + +{# Javascripts mostly copied from Symfony Form integration with the Profiler #} +{# https://github.com/symfony/web-profiler-bundle/blob/master/Resources/views/Collector/form.html.twig #} +{% block javascripts %} + {{ parent() }} + + +{% endblock %} \ No newline at end of file From de077d73e987b8648d3484750dae96972dcb3539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Wr=C3=B3blewski?= Date: Fri, 20 Sep 2024 22:29:02 +0200 Subject: [PATCH 2/2] Improve integration with Profiler --- src/DataCollector/DataTableDataExtractor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DataCollector/DataTableDataExtractor.php b/src/DataCollector/DataTableDataExtractor.php index fbfc716f..e8574464 100644 --- a/src/DataCollector/DataTableDataExtractor.php +++ b/src/DataCollector/DataTableDataExtractor.php @@ -10,7 +10,6 @@ use Kreyu\Bundle\DataTableBundle\DataTableView; use Kreyu\Bundle\DataTableBundle\Exporter\ExporterInterface; use Kreyu\Bundle\DataTableBundle\Filter\FilterInterface; -use Kreyu\Bundle\DataTableBundle\ValueRowView; use Symfony\Component\VarDumper\Caster\ClassStub; class DataTableDataExtractor implements DataTableDataExtractorInterface