diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..e27f86fe --- /dev/null +++ b/composer.lock @@ -0,0 +1,1850 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "38f417078fc5f615987c051d0a0c9213", + "packages": [ + { + "name": "latte/latte", + "version": "v3.1.6", + "source": { + "type": "git", + "url": "https://github.com/nette/latte.git", + "reference": "adccfac3d5d7bff441a0e5ae85978f448787f5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/latte/zipball/adccfac3d5d7bff441a0e5ae85978f448787f5d4", + "reference": "adccfac3d5d7bff441a0e5ae85978f448787f5d4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "require-dev": { + "nette/php-generator": "^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "nette/utils": "^4.0", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.10" + }, + "suggest": { + "ext-fileinfo": "to use filter |datastream", + "ext-iconv": "to use filters |reverse, |substring", + "ext-intl": "to use Latte\\Engine::setLocale()", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "nette/php-generator": "to use tag {templatePrint}", + "nette/utils": "to use filter |webalize" + }, + "bin": [ + "bin/latte-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Latte\\": "src/Latte" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "homepage": "https://latte.nette.org", + "keywords": [ + "context-sensitive", + "engine", + "escaping", + "html", + "nette", + "security", + "template", + "twig" + ], + "support": { + "issues": "https://github.com/nette/latte/issues", + "source": "https://github.com/nette/latte/tree/v3.1.6" + }, + "time": "2026-07-27T14:32:10+00:00" + }, + { + "name": "nette/application", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/application.git", + "reference": "104484c317fdb1b29baf77617ca040b97685e9bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/application/zipball/104484c317fdb1b29baf77617ca040b97685e9bb", + "reference": "104484c317fdb1b29baf77617ca040b97685e9bb", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.2 || ^4.0", + "nette/http": "^3.4", + "nette/routing": "^3.1.1", + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "latte/latte": "<3.1.4 || >=3.2", + "nette/caching": "<3.2", + "nette/di": "<3.2", + "nette/forms": "<3.2", + "nette/schema": "<1.3", + "tracy/tracy": "<2.12" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "latte/latte": "^3.1.4", + "mockery/mockery": "^1.6@stable", + "nette/caching": "^3.2", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.2@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "latte/latte": "Allows using Latte in templates", + "nette/forms": "Allows to use Nette\\Application\\UI\\Form" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🏆 Nette Application: a full-stack component-based MVC kernel for PHP that helps you write powerful and modern web applications. Write less, have cleaner code and your work will bring you joy.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "component-based", + "control", + "framework", + "mvc", + "mvp", + "nette", + "presenter", + "routing", + "seo" + ], + "support": { + "issues": "https://github.com/nette/application/issues", + "source": "https://github.com/nette/application/tree/v3.3.0" + }, + "time": "2026-06-29T19:05:48+00:00" + }, + { + "name": "nette/assets", + "version": "v1.0.7", + "source": { + "type": "git", + "url": "https://github.com/nette/assets.git", + "reference": "4a3d10902b6caca2eee3469e7863bea1b3bd1e2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/assets/zipball/4a3d10902b6caca2eee3469e7863bea1b3bd1e2b", + "reference": "4a3d10902b6caca2eee3469e7863bea1b3bd1e2b", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/bootstrap": "<3.2.5", + "nette/http": "<3.3.2" + }, + "require-dev": { + "latte/latte": "^3.0.22", + "mockery/mockery": "^1.6@stable", + "nette/application": "^3.2", + "nette/di": "^3.2", + "nette/http": "^3.3.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Assets in templates" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🎨 Nette Assets: elegant asset management for PHP with versioning, caching and mappers for various storage backends.", + "homepage": "https://nette.org", + "keywords": [ + "asset management", + "assets", + "nette", + "resources", + "static files", + "versioning" + ], + "support": { + "issues": "https://github.com/nette/assets/issues", + "source": "https://github.com/nette/assets/tree/v1.0.7" + }, + "time": "2026-03-28T17:15:28+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "3c8cbf8383b6df153bfb848a3c311ce42261a336" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/3c8cbf8383b6df153bfb848a3c311ce42261a336", + "reference": "3c8cbf8383b6df153bfb848a3c311ce42261a336", + "shasum": "" + }, + "require": { + "nette/di": "^3.2", + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "nette/caching": "<3.3", + "nette/mail": "<4.1.2", + "tracy/tracy": "<2.6" + }, + "require-dev": { + "latte/latte": "^3.0", + "nette/application": "^3.2", + "nette/assets": "^1.0", + "nette/caching": "^3.3", + "nette/database": "^3.2", + "nette/forms": "^3.2", + "nette/http": "^3.2", + "nette/mail": "^4.1", + "nette/neon": "^3.4", + "nette/phpstan-rules": "^1.0", + "nette/robot-loader": "^4.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.2", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.2@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.3.0" + }, + "time": "2026-06-21T22:20:56+00:00" + }, + { + "name": "nette/caching", + "version": "v3.4.2", + "source": { + "type": "git", + "url": "https://github.com/nette/caching.git", + "reference": "31f4bc6b366e6896998bd4538b26fa88a627bf2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/caching/zipball/31f4bc6b366e6896998bd4538b26fa88a627bf2b", + "reference": "31f4bc6b366e6896998bd4538b26fa88a627bf2b", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": "<3.0.12" + }, + "require-dev": { + "latte/latte": "^3.0.12", + "nette/di": "^3.1 || ^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.40@stable", + "psr/simple-cache": "^2.0 || ^3.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-pdo_sqlite": "to use SQLiteStorage or SQLiteJournal" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⏱ Nette Caching: library with easy-to-use API and many cache backends.", + "homepage": "https://nette.org", + "keywords": [ + "cache", + "journal", + "memcached", + "nette", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/caching/issues", + "source": "https://github.com/nette/caching/tree/v3.4.2" + }, + "time": "2026-05-12T01:08:42+00:00" + }, + { + "name": "nette/component-model", + "version": "v4.0.1", + "source": { + "type": "git", + "url": "https://github.com/nette/component-model.git", + "reference": "b4e82e1a3a7ca6f66ce766704aa2e148de277276" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/component-model/zipball/b4e82e1a3a7ca6f66ce766704aa2e148de277276", + "reference": "b4e82e1a3a7ca6f66ce766704aa2e148de277276", + "shasum": "" + }, + "require": { + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.12" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⚛ Nette Component Model", + "homepage": "https://nette.org", + "keywords": [ + "components", + "nette" + ], + "support": { + "issues": "https://github.com/nette/component-model/issues", + "source": "https://github.com/nette/component-model/tree/v4.0.1" + }, + "time": "2026-06-21T23:31:36+00:00" + }, + { + "name": "nette/database", + "version": "v3.2.9", + "source": { + "type": "git", + "url": "https://github.com/nette/database.git", + "reference": "6fe51398fcfc7719f64b7063f99886b438527755" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/database/zipball/6fe51398fcfc7719f64b7063f99886b438527755", + "reference": "6fe51398fcfc7719f64b7063f99886b438527755", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "nette/caching": "^3.2", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💾 Nette Database: layer with a familiar PDO-like API but much more powerful. Building queries, advanced joins, drivers for MySQL, PostgreSQL, SQLite, MS SQL Server and Oracle.", + "homepage": "https://nette.org", + "keywords": [ + "database", + "mssql", + "mysql", + "nette", + "notorm", + "oracle", + "pdo", + "postgresql", + "queries", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/database/issues", + "source": "https://github.com/nette/database/tree/v3.2.9" + }, + "time": "2026-04-22T05:48:11+00:00" + }, + { + "name": "nette/di", + "version": "v3.2.6", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "481ca2553e792daffa7fcf0ed43f705d80603fa4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/481ca2553e792daffa7fcf0ed43f705d80603fa4", + "reference": "481ca2553e792daffa7fcf0ed43f705d80603fa4", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-tokenizer": "*", + "nette/neon": "^3.4", + "nette/php-generator": "^4.1.6", + "nette/robot-loader": "^4.0", + "nette/schema": "^1.2.5", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.2.6" + }, + "time": "2026-05-06T02:17:57+00:00" + }, + { + "name": "nette/forms", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/forms.git", + "reference": "90aac9e6a55a71a76aaead65bca1129acb41ec84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/forms/zipball/90aac9e6a55a71a76aaead65bca1129acb41ec84", + "reference": "90aac9e6a55a71a76aaead65bca1129acb41ec84", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.2 || ^4.0", + "nette/http": "^3.4", + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "latte/latte": "<3.1.4 || >=3.2" + }, + "require-dev": { + "latte/latte": "^3.1.4", + "nette/application": "^3.2", + "nette/di": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "ext-intl": "to use date/time controls" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "bootstrap", + "csrf", + "javascript", + "nette", + "validation" + ], + "support": { + "issues": "https://github.com/nette/forms/issues", + "source": "https://github.com/nette/forms/tree/v3.3.0" + }, + "time": "2026-06-28T12:32:44+00:00" + }, + { + "name": "nette/http", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/nette/http.git", + "reference": "de5988d8802e76d9bda85fe5a871d29c794684f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/http/zipball/de5988d8802e76d9bda85fe5a871d29c794684f4", + "reference": "de5988d8802e76d9bda85fe5a871d29c794684f4", + "shasum": "" + }, + "require": { + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "nette/di": "<3.0.3", + "nette/schema": "<1.2" + }, + "require-dev": { + "nette/di": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/security": "^3.2", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.2@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "ext-fileinfo": "to detect MIME type of uploaded files by Nette\\Http\\FileUpload", + "ext-gd": "to use image function in Nette\\Http\\FileUpload", + "ext-intl": "to support punycode by Nette\\Http\\Url", + "ext-session": "to use Nette\\Http\\Session" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🌐 Nette Http: abstraction for HTTP request, response and session. Provides careful data sanitization and utility for URL and cookies manipulation.", + "homepage": "https://nette.org", + "keywords": [ + "cookies", + "http", + "nette", + "proxy", + "request", + "response", + "security", + "session", + "url" + ], + "support": { + "issues": "https://github.com/nette/http/issues", + "source": "https://github.com/nette/http/tree/v3.4.0" + }, + "time": "2026-06-13T01:04:19+00:00" + }, + { + "name": "nette/mail", + "version": "v4.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/mail.git", + "reference": "6dd1042fb3cb95ebd3c6ca79507154dc74215bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/mail/zipball/6dd1042fb3cb95ebd3c6ca79507154dc74215bd2", + "reference": "6dd1042fb3cb95ebd3c6ca79507154dc74215bd2", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "nette/utils": "^4.1", + "php": "8.2 - 8.5" + }, + "require-dev": { + "nette/di": "^3.1 || ^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.40@stable", + "tracy/tracy": "^2.11" + }, + "suggest": { + "ext-dom": "to use Nette\\Mail\\CssInliner", + "ext-fileinfo": "to detect type of attached files", + "ext-intl": "to send to internationalized (IDN) domains", + "ext-openssl": "to use Nette\\Mail\\DkimSigner with an RSA key", + "ext-sodium": "to use Nette\\Mail\\DkimSigner with an Ed25519 key" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📧 Nette Mail: A handy library for creating and sending emails in PHP.", + "homepage": "https://nette.org", + "keywords": [ + "mail", + "mailer", + "mime", + "nette", + "smtp" + ], + "support": { + "issues": "https://github.com/nette/mail/issues", + "source": "https://github.com/nette/mail/tree/v4.2.0" + }, + "time": "2026-07-27T15:28:54+00:00" + }, + { + "name": "nette/neon", + "version": "v3.4.8", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "9009f99ce1396b366a88ca16c90177148352b7d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/9009f99ce1396b366a88ca16c90177148352b7d3", + "reference": "9009f99ce1396b366a88ca16c90177148352b7d3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "8.0 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.7" + }, + "bin": [ + "bin/neon-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "https://neon.nette.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.4.8" + }, + "time": "2026-05-11T21:34:00+00:00" + }, + { + "name": "nette/php-generator", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "0d7060926f5c3e8c488b9b9ced42d857f12a34b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/0d7060926f5c3e8c488b9b9ced42d857f12a34b5", + "reference": "0d7060926f5c3e8c488b9b9ced42d857f12a34b5", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "nikic/php-parser": "^5.0", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.40@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v4.2.2" + }, + "time": "2026-02-26T00:58:33+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v4.1.2", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e", + "reference": "ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v4.1.2" + }, + "time": "2026-02-23T04:18:24+00:00" + }, + { + "name": "nette/routing", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/nette/routing.git", + "reference": "92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/routing/zipball/92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6", + "reference": "92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6", + "shasum": "" + }, + "require": { + "nette/http": "^3.2 || ~4.0.0", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Routing: two-ways URL conversion", + "homepage": "https://nette.org", + "keywords": [ + "nette" + ], + "support": { + "issues": "https://github.com/nette/routing/issues", + "source": "https://github.com/nette/routing/tree/v3.1.3" + }, + "time": "2026-02-23T04:05:29+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.5", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.5" + }, + "time": "2026-02-23T03:47:12+00:00" + }, + { + "name": "nette/security", + "version": "v3.2.6", + "source": { + "type": "git", + "url": "https://github.com/nette/security.git", + "reference": "6cad44dbac2153bccf36e73784a38c43d7cdae8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/security/zipball/6cad44dbac2153bccf36e73784a38c43d7cdae8b", + "reference": "6cad44dbac2153bccf36e73784a38c43d7cdae8b", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/di": "<3.0-stable", + "nette/http": "<3.1.3" + }, + "require-dev": { + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/http": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔑 Nette Security: provides authentication, authorization and a role-based access control management via ACL (Access Control List)", + "homepage": "https://nette.org", + "keywords": [ + "Authentication", + "acl", + "authorization", + "nette" + ], + "support": { + "issues": "https://github.com/nette/security/issues", + "source": "https://github.com/nette/security/tree/v3.2.6" + }, + "time": "2026-07-24T23:36:00+00:00" + }, + { + "name": "nette/utils", + "version": "v4.1.5", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "b043439dbdf954e6c28b5ea7e34b0100f83165e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/b043439dbdf954e6c28b5ea7e34b0100f83165e0", + "reference": "b043439dbdf954e6c28b5ea7e34b0100f83165e0", + "shasum": "" + }, + "require": { + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.5", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::chr(), ord() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.5" + }, + "time": "2026-07-17T23:02:45+00:00" + }, + { + "name": "tracy/tracy", + "version": "v2.12.0", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "535eda4871fd04f2756c8d95f6bdfa43706d79be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/535eda4871fd04f2756c8d95f6bdfa43706d79be", + "reference": "535eda4871fd04f2756c8d95f6bdfa43706d79be", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5 || ^3.0", + "nette/di": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "nette/utils": "^3.0 || ^4.0", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.12-dev" + } + }, + "autoload": { + "files": [ + "src/Tracy/functions.php" + ], + "psr-4": { + "Tracy\\": "src" + }, + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "support": { + "issues": "https://github.com/nette/tracy/issues", + "source": "https://github.com/nette/tracy/tree/v2.12.0" + }, + "time": "2026-05-04T00:23:53+00:00" + } + ], + "packages-dev": [ + { + "name": "nette/phpstan-rules", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/nette/phpstan-rules.git", + "reference": "6811d818c5272b43eceb9e8dfee28071cfcd1ec5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/phpstan-rules/zipball/6811d818c5272b43eceb9e8dfee28071cfcd1ec5", + "reference": "6811d818c5272b43eceb9e8dfee28071cfcd1ec5", + "shasum": "" + }, + "require": { + "php": "8.1 - 8.5", + "phpstan/phpstan": "^2.2.6" + }, + "require-dev": { + "nette/application": "^3.2", + "nette/assets": "^1.0", + "nette/component-model": "^3.1", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/schema": "^1.3", + "nette/tester": "^2.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\PHPStan\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + } + ], + "description": "🐘 PHPStan rules and type extensions for Nette libraries", + "homepage": "https://nette.org", + "keywords": [ + "PHPStan", + "nette", + "static analysis" + ], + "support": { + "issues": "https://github.com/nette/phpstan-rules/issues", + "source": "https://github.com/nette/phpstan-rules/tree/v1.0.5" + }, + "time": "2026-07-27T15:17:34+00:00" + }, + { + "name": "nette/tester", + "version": "v2.6.1", + "source": { + "type": "git", + "url": "https://github.com/nette/tester.git", + "reference": "86e4d80d0953256c3b2930b9d47a07d2a9528770" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tester/zipball/86e4d80d0953256c3b2930b9d47a07d2a9528770", + "reference": "86e4d80d0953256c3b2930b9d47a07d2a9528770", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.5" + }, + "require-dev": { + "ext-simplexml": "*", + "phpstan/phpstan": "^2.0@stable" + }, + "bin": [ + "src/tester" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Tester\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Miloslav Hůla", + "homepage": "https://github.com/milo" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Tester: enjoyable unit testing in PHP with code coverage reporter. 🍏🍏🍎🍏", + "homepage": "https://tester.nette.org", + "keywords": [ + "Xdebug", + "assertions", + "clover", + "code coverage", + "nette", + "pcov", + "phpdbg", + "phpunit", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/nette/tester/issues", + "source": "https://github.com/nette/tester/tree/v2.6.1" + }, + "time": "2026-05-11T18:11:12+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" + }, + "time": "2024-09-04T20:21:43+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.2.6", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a6e9b5a9420f6109c091e87d82683bd1a80b87ed", + "reference": "a6e9b5a9420f6109c091e87d82683bd1a80b87ed", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-07-26T21:22:49+00:00" + }, + { + "name": "symfony/thanks", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/thanks.git", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/thanks/zipball/f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": ">=8.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Thanks\\Thanks", + "branch-alias": { + "dev-main": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Thanks\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Encourages sending ⭐ and 💵 to fellow PHP package maintainers (not limited to Symfony components)!", + "support": { + "issues": "https://github.com/symfony/thanks/issues", + "source": "https://github.com/symfony/thanks/tree/v1.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-10-30T17:38:50+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">= 8.2" + }, + "platform-dev": {}, + "plugin-api-version": "2.9.0" +} diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 00000000..c0829940 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,22 @@ +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/latte/latte/bin/latte-lint'); + } +} + +return include __DIR__ . '/..'.'/latte/latte/bin/latte-lint'; diff --git a/vendor/bin/latte-lint.bat b/vendor/bin/latte-lint.bat new file mode 100644 index 00000000..2fb88910 --- /dev/null +++ b/vendor/bin/latte-lint.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/latte-lint +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/neon-lint b/vendor/bin/neon-lint new file mode 100644 index 00000000..c7741230 --- /dev/null +++ b/vendor/bin/neon-lint @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/nette/neon/bin/neon-lint'); + } +} + +return include __DIR__ . '/..'.'/nette/neon/bin/neon-lint'; diff --git a/vendor/bin/neon-lint.bat b/vendor/bin/neon-lint.bat new file mode 100644 index 00000000..31fa117a --- /dev/null +++ b/vendor/bin/neon-lint.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/neon-lint +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/phpstan b/vendor/bin/phpstan new file mode 100644 index 00000000..d76c0be7 --- /dev/null +++ b/vendor/bin/phpstan @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpstan/phpstan/phpstan'); + } +} + +return include __DIR__ . '/..'.'/phpstan/phpstan/phpstan'; diff --git a/vendor/bin/phpstan.bat b/vendor/bin/phpstan.bat new file mode 100644 index 00000000..7ec286d6 --- /dev/null +++ b/vendor/bin/phpstan.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/phpstan +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/phpstan.phar b/vendor/bin/phpstan.phar new file mode 100644 index 00000000..fecf96f6 --- /dev/null +++ b/vendor/bin/phpstan.phar @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpstan/phpstan/phpstan.phar'); + } +} + +return include __DIR__ . '/..'.'/phpstan/phpstan/phpstan.phar'; diff --git a/vendor/bin/phpstan.phar.bat b/vendor/bin/phpstan.phar.bat new file mode 100644 index 00000000..5f4d9eb0 --- /dev/null +++ b/vendor/bin/phpstan.phar.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/phpstan.phar +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/tester b/vendor/bin/tester new file mode 100644 index 00000000..d8003072 --- /dev/null +++ b/vendor/bin/tester @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/nette/tester/src/tester'); + } +} + +return include __DIR__ . '/..'.'/nette/tester/src/tester'; diff --git a/vendor/bin/tester.bat b/vendor/bin/tester.bat new file mode 100644 index 00000000..34024726 --- /dev/null +++ b/vendor/bin/tester.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/tester +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100644 index 00000000..7824d8f7 --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,579 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..2052022f --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,396 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to + * @internal + */ + private static $selfDir = null; + + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool + */ + private static $installedIsLocalDir; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return string + */ + private static function getSelfDir() + { + if (self::$selfDir === null) { + self::$selfDir = strtr(__DIR__, '\\', '/'); + } + + return self::$selfDir; + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + $copiedLocalDir = false; + + if (self::$canGetVendors) { + $selfDir = self::getSelfDir(); + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; + } + } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array() && !$copiedLocalDir) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..6618c4c6 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,708 @@ + $vendorDir . '/composer/InstalledVersions.php', + 'Latte\\Attributes\\TemplateFilter' => $vendorDir . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Attributes\\TemplateFunction' => $vendorDir . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Bridges\\Tracy\\BlueScreenPanel' => $vendorDir . '/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php', + 'Latte\\Bridges\\Tracy\\LattePanel' => $vendorDir . '/latte/latte/src/Bridges/Tracy/LattePanel.php', + 'Latte\\Bridges\\Tracy\\TracyExtension' => $vendorDir . '/latte/latte/src/Bridges/Tracy/TracyExtension.php', + 'Latte\\CompileException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Compiler\\Block' => $vendorDir . '/latte/latte/src/Latte/Compiler/Block.php', + 'Latte\\Compiler\\Dedent' => $vendorDir . '/latte/latte/src/Latte/Compiler/Dedent.php', + 'Latte\\Compiler\\Escaper' => $vendorDir . '/latte/latte/src/Latte/Compiler/Escaper.php', + 'Latte\\Compiler\\Node' => $vendorDir . '/latte/latte/src/Latte/Compiler/Node.php', + 'Latte\\Compiler\\NodeHelpers' => $vendorDir . '/latte/latte/src/Latte/Compiler/NodeHelpers.php', + 'Latte\\Compiler\\NodeTraverser' => $vendorDir . '/latte/latte/src/Latte/Compiler/NodeTraverser.php', + 'Latte\\Compiler\\Nodes\\AreaNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php', + 'Latte\\Compiler\\Nodes\\AuxiliaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\FragmentNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\AttributeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\BogusTagNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php', + 'Latte\\Compiler\\Nodes\\Html\\CommentNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ElementNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ExpressionAttributeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\TagNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php', + 'Latte\\Compiler\\Nodes\\NopNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/NopNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArgumentNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArrayItemNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ClosureUseNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ComplexTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ExpressionNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayAccessNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AuxiliaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\BinaryOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CastNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClassConstantFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CloneNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClosureNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ConstantFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\EmptyNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FilterCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FunctionCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InstanceofNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\IssetNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MatchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\NewNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PostOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PreOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticMethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticPropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TemporaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TernaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\UnaryOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\VariableNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php', + 'Latte\\Compiler\\Nodes\\Php\\FilterNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IdentifierNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\InterpolatedStringPartNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IntersectionTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListItemNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php', + 'Latte\\Compiler\\Nodes\\Php\\MatchArmNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ModifierNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NameNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NullableTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\OperatorNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ParameterNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ScalarNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\BooleanNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\FloatNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\IntegerNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\InterpolatedStringNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\NullNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\StringNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\SuperiorTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\UnionTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VarLikeIdentifierNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VariadicPlaceholderNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php', + 'Latte\\Compiler\\Nodes\\PrintNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/PrintNode.php', + 'Latte\\Compiler\\Nodes\\StatementNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php', + 'Latte\\Compiler\\Nodes\\TemplateNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php', + 'Latte\\Compiler\\Nodes\\TextNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/TextNode.php', + 'Latte\\Compiler\\PhpHelpers' => $vendorDir . '/latte/latte/src/Latte/Compiler/PhpHelpers.php', + 'Latte\\Compiler\\Position' => $vendorDir . '/latte/latte/src/Latte/Compiler/Position.php', + 'Latte\\Compiler\\PrintContext' => $vendorDir . '/latte/latte/src/Latte/Compiler/PrintContext.php', + 'Latte\\Compiler\\Range' => $vendorDir . '/latte/latte/src/Latte/Compiler/Range.php', + 'Latte\\Compiler\\Tag' => $vendorDir . '/latte/latte/src/Latte/Compiler/Tag.php', + 'Latte\\Compiler\\TagLexer' => $vendorDir . '/latte/latte/src/Latte/Compiler/TagLexer.php', + 'Latte\\Compiler\\TagParser' => $vendorDir . '/latte/latte/src/Latte/Compiler/TagParser.php', + 'Latte\\Compiler\\TagParserData' => $vendorDir . '/latte/latte/src/Latte/Compiler/TagParserData.php', + 'Latte\\Compiler\\TemplateGenerator' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateGenerator.php', + 'Latte\\Compiler\\TemplateLexer' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateLexer.php', + 'Latte\\Compiler\\TemplateParser' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateParser.php', + 'Latte\\Compiler\\TemplateParserHtml' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateParserHtml.php', + 'Latte\\Compiler\\Token' => $vendorDir . '/latte/latte/src/Latte/Compiler/Token.php', + 'Latte\\Compiler\\TokenStream' => $vendorDir . '/latte/latte/src/Latte/Compiler/TokenStream.php', + 'Latte\\ContentType' => $vendorDir . '/latte/latte/src/Latte/ContentType.php', + 'Latte\\Engine' => $vendorDir . '/latte/latte/src/Latte/Engine.php', + 'Latte\\Essential\\AuxiliaryIterator' => $vendorDir . '/latte/latte/src/Latte/Essential/AuxiliaryIterator.php', + 'Latte\\Essential\\Blueprint' => $vendorDir . '/latte/latte/src/Latte/Essential/Blueprint.php', + 'Latte\\Essential\\CachingIterator' => $vendorDir . '/latte/latte/src/Latte/Essential/CachingIterator.php', + 'Latte\\Essential\\CoreExtension' => $vendorDir . '/latte/latte/src/Latte/Essential/CoreExtension.php', + 'Latte\\Essential\\Filters' => $vendorDir . '/latte/latte/src/Latte/Essential/Filters.php', + 'Latte\\Essential\\Nodes\\BlockNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/BlockNode.php', + 'Latte\\Essential\\Nodes\\CaptureNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php', + 'Latte\\Essential\\Nodes\\ContentTypeNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php', + 'Latte\\Essential\\Nodes\\CustomFunctionCallNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php', + 'Latte\\Essential\\Nodes\\DebugbreakNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php', + 'Latte\\Essential\\Nodes\\DefineNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DefineNode.php', + 'Latte\\Essential\\Nodes\\DoNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DoNode.php', + 'Latte\\Essential\\Nodes\\DumpNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DumpNode.php', + 'Latte\\Essential\\Nodes\\EmbedNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php', + 'Latte\\Essential\\Nodes\\ExtendsNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php', + 'Latte\\Essential\\Nodes\\FirstLastSepNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php', + 'Latte\\Essential\\Nodes\\ForNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ForNode.php', + 'Latte\\Essential\\Nodes\\ForeachNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php', + 'Latte\\Essential\\Nodes\\IfChangedNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php', + 'Latte\\Essential\\Nodes\\IfContentNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php', + 'Latte\\Essential\\Nodes\\IfNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IfNode.php', + 'Latte\\Essential\\Nodes\\ImportNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ImportNode.php', + 'Latte\\Essential\\Nodes\\IncludeBlockNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php', + 'Latte\\Essential\\Nodes\\IncludeFileNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php', + 'Latte\\Essential\\Nodes\\IterateWhileNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php', + 'Latte\\Essential\\Nodes\\JumpNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/JumpNode.php', + 'Latte\\Essential\\Nodes\\NAttrNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php', + 'Latte\\Essential\\Nodes\\NClassNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NClassNode.php', + 'Latte\\Essential\\Nodes\\NElseNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NElseNode.php', + 'Latte\\Essential\\Nodes\\NTagNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NTagNode.php', + 'Latte\\Essential\\Nodes\\ParametersNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php', + 'Latte\\Essential\\Nodes\\RawPhpNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php', + 'Latte\\Essential\\Nodes\\RollbackNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php', + 'Latte\\Essential\\Nodes\\SpacelessNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php', + 'Latte\\Essential\\Nodes\\SwitchNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php', + 'Latte\\Essential\\Nodes\\TemplatePrintNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php', + 'Latte\\Essential\\Nodes\\TemplateTypeNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php', + 'Latte\\Essential\\Nodes\\TraceNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TraceNode.php', + 'Latte\\Essential\\Nodes\\TranslateNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php', + 'Latte\\Essential\\Nodes\\TryNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TryNode.php', + 'Latte\\Essential\\Nodes\\VarNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/VarNode.php', + 'Latte\\Essential\\Nodes\\VarPrintNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php', + 'Latte\\Essential\\Nodes\\VarTypeNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php', + 'Latte\\Essential\\Nodes\\WhileNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/WhileNode.php', + 'Latte\\Essential\\Passes' => $vendorDir . '/latte/latte/src/Latte/Essential/Passes.php', + 'Latte\\Essential\\RawPhpExtension' => $vendorDir . '/latte/latte/src/Latte/Essential/RawPhpExtension.php', + 'Latte\\Essential\\RollbackException' => $vendorDir . '/latte/latte/src/Latte/Essential/RollbackException.php', + 'Latte\\Essential\\Tracer' => $vendorDir . '/latte/latte/src/Latte/Essential/Tracer.php', + 'Latte\\Essential\\TranslatorExtension' => $vendorDir . '/latte/latte/src/Latte/Essential/TranslatorExtension.php', + 'Latte\\Essential\\WhitespaceMinifier' => $vendorDir . '/latte/latte/src/Latte/Essential/WhitespaceMinifier.php', + 'Latte\\Exception' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Extension' => $vendorDir . '/latte/latte/src/Latte/Extension.php', + 'Latte\\Feature' => $vendorDir . '/latte/latte/src/Latte/enums.php', + 'Latte\\Helpers' => $vendorDir . '/latte/latte/src/Latte/Helpers.php', + 'Latte\\Loader' => $vendorDir . '/latte/latte/src/Latte/Loader.php', + 'Latte\\Loaders\\FileLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/FileLoader.php', + 'Latte\\Loaders\\StringLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/StringLoader.php', + 'Latte\\Policy' => $vendorDir . '/latte/latte/src/Latte/Policy.php', + 'Latte\\PositionAwareException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\RuntimeException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Runtime\\Block' => $vendorDir . '/latte/latte/src/Latte/Runtime/Block.php', + 'Latte\\Runtime\\Cache' => $vendorDir . '/latte/latte/src/Latte/Runtime/Cache.php', + 'Latte\\Runtime\\FilterExecutor' => $vendorDir . '/latte/latte/src/Latte/Runtime/FilterExecutor.php', + 'Latte\\Runtime\\FilterInfo' => $vendorDir . '/latte/latte/src/Latte/Runtime/FilterInfo.php', + 'Latte\\Runtime\\FunctionExecutor' => $vendorDir . '/latte/latte/src/Latte/Runtime/FunctionExecutor.php', + 'Latte\\Runtime\\Helpers' => $vendorDir . '/latte/latte/src/Latte/Runtime/Helpers.php', + 'Latte\\Runtime\\Html' => $vendorDir . '/latte/latte/src/Latte/Runtime/Html.php', + 'Latte\\Runtime\\HtmlHelpers' => $vendorDir . '/latte/latte/src/Latte/Runtime/HtmlHelpers.php', + 'Latte\\Runtime\\HtmlStringable' => $vendorDir . '/latte/latte/src/Latte/Runtime/HtmlStringable.php', + 'Latte\\Runtime\\Template' => $vendorDir . '/latte/latte/src/Latte/Runtime/Template.php', + 'Latte\\Runtime\\XmlHelpers' => $vendorDir . '/latte/latte/src/Latte/Runtime/XmlHelpers.php', + 'Latte\\Sandbox\\Nodes\\FunctionCallNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php', + 'Latte\\Sandbox\\Nodes\\MethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\PropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php', + 'Latte\\Sandbox\\Nodes\\SandboxNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php', + 'Latte\\Sandbox\\Nodes\\StaticMethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\StaticPropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php', + 'Latte\\Sandbox\\RuntimeChecker' => $vendorDir . '/latte/latte/src/Latte/Sandbox/RuntimeChecker.php', + 'Latte\\Sandbox\\SandboxExtension' => $vendorDir . '/latte/latte/src/Latte/Sandbox/SandboxExtension.php', + 'Latte\\Sandbox\\SecurityPolicy' => $vendorDir . '/latte/latte/src/Latte/Sandbox/SecurityPolicy.php', + 'Latte\\SecurityViolationException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\TemplateNotFoundException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Tools\\Linter' => $vendorDir . '/latte/latte/src/Tools/Linter.php', + 'Latte\\Tools\\LinterExtension' => $vendorDir . '/latte/latte/src/Tools/LinterExtension.php', + 'NetteModule\\ErrorPresenter' => $vendorDir . '/nette/application/src/Application/ErrorPresenter.php', + 'NetteModule\\MicroPresenter' => $vendorDir . '/nette/application/src/Application/MicroPresenter.php', + 'Nette\\Application\\AbortException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Application' => $vendorDir . '/nette/application/src/Application/Application.php', + 'Nette\\Application\\ApplicationException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Attributes\\CrossOrigin' => $vendorDir . '/nette/application/src/Application/Attributes/CrossOrigin.php', + 'Nette\\Application\\Attributes\\Deprecated' => $vendorDir . '/nette/application/src/Application/Attributes/Deprecated.php', + 'Nette\\Application\\Attributes\\Parameter' => $vendorDir . '/nette/application/src/Application/Attributes/Parameter.php', + 'Nette\\Application\\Attributes\\Persistent' => $vendorDir . '/nette/application/src/Application/Attributes/Persistent.php', + 'Nette\\Application\\Attributes\\Requires' => $vendorDir . '/nette/application/src/Application/Attributes/Requires.php', + 'Nette\\Application\\Attributes\\TemplateVariable' => $vendorDir . '/nette/application/src/Application/Attributes/TemplateVariable.php', + 'Nette\\Application\\BadRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\ForbiddenRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Helpers' => $vendorDir . '/nette/application/src/Application/Helpers.php', + 'Nette\\Application\\IPresenter' => $vendorDir . '/nette/application/src/Application/IPresenter.php', + 'Nette\\Application\\IPresenterFactory' => $vendorDir . '/nette/application/src/Application/IPresenterFactory.php', + 'Nette\\Application\\IResponse' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\InvalidPresenterException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\LinkGenerator' => $vendorDir . '/nette/application/src/Application/LinkGenerator.php', + 'Nette\\Application\\PresenterFactory' => $vendorDir . '/nette/application/src/Application/PresenterFactory.php', + 'Nette\\Application\\Request' => $vendorDir . '/nette/application/src/Application/Request.php', + 'Nette\\Application\\Response' => $vendorDir . '/nette/application/src/Application/Response.php', + 'Nette\\Application\\Responses\\CallbackResponse' => $vendorDir . '/nette/application/src/Application/Responses/CallbackResponse.php', + 'Nette\\Application\\Responses\\FileResponse' => $vendorDir . '/nette/application/src/Application/Responses/FileResponse.php', + 'Nette\\Application\\Responses\\ForwardResponse' => $vendorDir . '/nette/application/src/Application/Responses/ForwardResponse.php', + 'Nette\\Application\\Responses\\JsonResponse' => $vendorDir . '/nette/application/src/Application/Responses/JsonResponse.php', + 'Nette\\Application\\Responses\\RedirectResponse' => $vendorDir . '/nette/application/src/Application/Responses/RedirectResponse.php', + 'Nette\\Application\\Responses\\TextResponse' => $vendorDir . '/nette/application/src/Application/Responses/TextResponse.php', + 'Nette\\Application\\Responses\\VoidResponse' => $vendorDir . '/nette/application/src/Application/Responses/VoidResponse.php', + 'Nette\\Application\\Routers\\CliRouter' => $vendorDir . '/nette/application/src/Application/Routers/CliRouter.php', + 'Nette\\Application\\Routers\\Route' => $vendorDir . '/nette/application/src/Application/Routers/Route.php', + 'Nette\\Application\\Routers\\RouteList' => $vendorDir . '/nette/application/src/Application/Routers/RouteList.php', + 'Nette\\Application\\Routers\\SimpleRouter' => $vendorDir . '/nette/application/src/Application/Routers/SimpleRouter.php', + 'Nette\\Application\\SwitchException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\UI\\AccessPolicy' => $vendorDir . '/nette/application/src/Application/UI/AccessPolicy.php', + 'Nette\\Application\\UI\\BadSignalException' => $vendorDir . '/nette/application/src/Application/UI/BadSignalException.php', + 'Nette\\Application\\UI\\Component' => $vendorDir . '/nette/application/src/Application/UI/Component.php', + 'Nette\\Application\\UI\\ComponentReflection' => $vendorDir . '/nette/application/src/Application/UI/ComponentReflection.php', + 'Nette\\Application\\UI\\Control' => $vendorDir . '/nette/application/src/Application/UI/Control.php', + 'Nette\\Application\\UI\\Form' => $vendorDir . '/nette/application/src/Application/UI/Form.php', + 'Nette\\Application\\UI\\IRenderable' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ISignalReceiver' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\IStatePersistent' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplate' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplateFactory' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\InvalidLinkException' => $vendorDir . '/nette/application/src/Application/UI/InvalidLinkException.php', + 'Nette\\Application\\UI\\InvalidRequestParameterException' => $vendorDir . '/nette/application/src/Application/UI/InvalidRequestParameterException.php', + 'Nette\\Application\\UI\\Link' => $vendorDir . '/nette/application/src/Application/UI/Link.php', + 'Nette\\Application\\UI\\MethodReflection' => $vendorDir . '/nette/application/src/Application/UI/MethodReflection.php', + 'Nette\\Application\\UI\\Multiplier' => $vendorDir . '/nette/application/src/Application/UI/Multiplier.php', + 'Nette\\Application\\UI\\ParameterConverter' => $vendorDir . '/nette/application/src/Application/UI/ParameterConverter.php', + 'Nette\\Application\\UI\\Presenter' => $vendorDir . '/nette/application/src/Application/UI/Presenter.php', + 'Nette\\Application\\UI\\Renderable' => $vendorDir . '/nette/application/src/Application/UI/Renderable.php', + 'Nette\\Application\\UI\\SignalReceiver' => $vendorDir . '/nette/application/src/Application/UI/SignalReceiver.php', + 'Nette\\Application\\UI\\StatePersistent' => $vendorDir . '/nette/application/src/Application/UI/StatePersistent.php', + 'Nette\\Application\\UI\\Template' => $vendorDir . '/nette/application/src/Application/UI/Template.php', + 'Nette\\Application\\UI\\TemplateFactory' => $vendorDir . '/nette/application/src/Application/UI/TemplateFactory.php', + 'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Assets\\Asset' => $vendorDir . '/nette/assets/src/Assets/Asset.php', + 'Nette\\Assets\\AssetNotFoundException' => $vendorDir . '/nette/assets/src/Assets/exceptions.php', + 'Nette\\Assets\\AudioAsset' => $vendorDir . '/nette/assets/src/Assets/AudioAsset.php', + 'Nette\\Assets\\EntryAsset' => $vendorDir . '/nette/assets/src/Assets/EntryAsset.php', + 'Nette\\Assets\\FilesystemMapper' => $vendorDir . '/nette/assets/src/Assets/FilesystemMapper.php', + 'Nette\\Assets\\FontAsset' => $vendorDir . '/nette/assets/src/Assets/FontAsset.php', + 'Nette\\Assets\\GenericAsset' => $vendorDir . '/nette/assets/src/Assets/GenericAsset.php', + 'Nette\\Assets\\Helpers' => $vendorDir . '/nette/assets/src/Assets/Helpers.php', + 'Nette\\Assets\\HtmlRenderable' => $vendorDir . '/nette/assets/src/Assets/HtmlRenderable.php', + 'Nette\\Assets\\ImageAsset' => $vendorDir . '/nette/assets/src/Assets/ImageAsset.php', + 'Nette\\Assets\\LazyLoad' => $vendorDir . '/nette/assets/src/Assets/LazyLoad.php', + 'Nette\\Assets\\Mapper' => $vendorDir . '/nette/assets/src/Assets/Mapper.php', + 'Nette\\Assets\\Registry' => $vendorDir . '/nette/assets/src/Assets/Registry.php', + 'Nette\\Assets\\ScriptAsset' => $vendorDir . '/nette/assets/src/Assets/ScriptAsset.php', + 'Nette\\Assets\\StyleAsset' => $vendorDir . '/nette/assets/src/Assets/StyleAsset.php', + 'Nette\\Assets\\VideoAsset' => $vendorDir . '/nette/assets/src/Assets/VideoAsset.php', + 'Nette\\Assets\\ViteMapper' => $vendorDir . '/nette/assets/src/Assets/ViteMapper.php', + 'Nette\\Bootstrap\\Configurator' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\Bootstrap\\Extensions\\ConstantsExtension' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Extensions/ConstantsExtension.php', + 'Nette\\Bootstrap\\Extensions\\PhpExtension' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Extensions/PhpExtension.php', + 'Nette\\Bridges\\ApplicationDI\\ApplicationExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php', + 'Nette\\Bridges\\ApplicationDI\\LatteExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/LatteExtension.php', + 'Nette\\Bridges\\ApplicationDI\\PresenterFactoryCallback' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php', + 'Nette\\Bridges\\ApplicationDI\\RoutingExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\DefaultTemplate' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php', + 'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Bridges\\ApplicationLatte\\LatteFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\ControlNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/ControlNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkBaseNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\NNonceNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetAreaNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\TemplatePrintNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetRuntime' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php', + 'Nette\\Bridges\\ApplicationLatte\\Template' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Template.php', + 'Nette\\Bridges\\ApplicationLatte\\TemplateFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\UIExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIExtension.php', + 'Nette\\Bridges\\ApplicationTracy\\RoutingPanel' => $vendorDir . '/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php', + 'Nette\\Bridges\\AssetsDI\\DIExtension' => $vendorDir . '/nette/assets/src/Bridges/AssetsDI/DIExtension.php', + 'Nette\\Bridges\\AssetsLatte\\LatteExtension' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\AssetNode' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\NAssetNode' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Runtime' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/Runtime.php', + 'Nette\\Bridges\\CacheDI\\CacheExtension' => $vendorDir . '/nette/caching/src/Bridges/CacheDI/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\CacheExtension' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\Nodes\\CacheNode' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/Nodes/CacheNode.php', + 'Nette\\Bridges\\CacheLatte\\Runtime' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/Runtime.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => $vendorDir . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\DatabaseDI\\DatabaseExtension' => $vendorDir . '/nette/database/src/Bridges/DatabaseDI/DatabaseExtension.php', + 'Nette\\Bridges\\DatabaseTracy\\ConnectionPanel' => $vendorDir . '/nette/database/src/Bridges/DatabaseTracy/ConnectionPanel.php', + 'Nette\\Bridges\\FormsDI\\FormsExtension' => $vendorDir . '/nette/forms/src/Bridges/FormsDI/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\FormsExtension' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FieldNNameNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormContainerNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormContainerNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNNameNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormPrintNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormPrintNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputErrorNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputErrorNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\LabelNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/LabelNode.php', + 'Nette\\Bridges\\FormsLatte\\Runtime' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Runtime.php', + 'Nette\\Bridges\\HttpDI\\HttpExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/HttpExtension.php', + 'Nette\\Bridges\\HttpDI\\SessionExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/SessionExtension.php', + 'Nette\\Bridges\\HttpTracy\\SessionPanel' => $vendorDir . '/nette/http/src/Bridges/HttpTracy/SessionPanel.php', + 'Nette\\Bridges\\MailDI\\MailExtension' => $vendorDir . '/nette/mail/src/Bridges/MailDI/MailExtension.php', + 'Nette\\Bridges\\MailTracy\\MailPanel' => $vendorDir . '/nette/mail/src/Bridges/MailTracy/MailPanel.php', + 'Nette\\Bridges\\Psr\\PsrCacheAdapter' => $vendorDir . '/nette/caching/src/Bridges/Psr/PsrCacheAdapter.php', + 'Nette\\Bridges\\SecurityDI\\SecurityExtension' => $vendorDir . '/nette/security/src/Bridges/SecurityDI/SecurityExtension.php', + 'Nette\\Bridges\\SecurityHttp\\CookieStorage' => $vendorDir . '/nette/security/src/Bridges/SecurityHttp/CookieStorage.php', + 'Nette\\Bridges\\SecurityHttp\\SessionStorage' => $vendorDir . '/nette/security/src/Bridges/SecurityHttp/SessionStorage.php', + 'Nette\\Bridges\\SecurityTracy\\UserPanel' => $vendorDir . '/nette/security/src/Bridges/SecurityTracy/UserPanel.php', + 'Nette\\Caching\\BulkReader' => $vendorDir . '/nette/caching/src/Caching/BulkReader.php', + 'Nette\\Caching\\BulkWriter' => $vendorDir . '/nette/caching/src/Caching/BulkWriter.php', + 'Nette\\Caching\\Cache' => $vendorDir . '/nette/caching/src/Caching/Cache.php', + 'Nette\\Caching\\IBulkReader' => $vendorDir . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\IStorage' => $vendorDir . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\OutputHelper' => $vendorDir . '/nette/caching/src/Caching/OutputHelper.php', + 'Nette\\Caching\\Storage' => $vendorDir . '/nette/caching/src/Caching/Storage.php', + 'Nette\\Caching\\Storages\\DevNullStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/DevNullStorage.php', + 'Nette\\Caching\\Storages\\FileStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/FileStorage.php', + 'Nette\\Caching\\Storages\\IJournal' => $vendorDir . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\Storages\\Journal' => $vendorDir . '/nette/caching/src/Caching/Storages/Journal.php', + 'Nette\\Caching\\Storages\\MemcachedStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemcachedStorage.php', + 'Nette\\Caching\\Storages\\MemoryStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemoryStorage.php', + 'Nette\\Caching\\Storages\\SQLiteJournal' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteJournal.php', + 'Nette\\Caching\\Storages\\SQLiteStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteStorage.php', + 'Nette\\ComponentModel\\ArrayAccess' => $vendorDir . '/nette/component-model/src/ComponentModel/ArrayAccess.php', + 'Nette\\ComponentModel\\Component' => $vendorDir . '/nette/component-model/src/ComponentModel/Component.php', + 'Nette\\ComponentModel\\Container' => $vendorDir . '/nette/component-model/src/ComponentModel/Container.php', + 'Nette\\ComponentModel\\IComponent' => $vendorDir . '/nette/component-model/src/ComponentModel/IComponent.php', + 'Nette\\ComponentModel\\IContainer' => $vendorDir . '/nette/component-model/src/ComponentModel/IContainer.php', + 'Nette\\Configurator' => $vendorDir . '/nette/bootstrap/src/Configurator.php', + 'Nette\\DI\\Attributes\\Inject' => $vendorDir . '/nette/di/src/DI/Attributes/Inject.php', + 'Nette\\DI\\Autowiring' => $vendorDir . '/nette/di/src/DI/Autowiring.php', + 'Nette\\DI\\Compiler' => $vendorDir . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => $vendorDir . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapter' => $vendorDir . '/nette/di/src/DI/Config/Adapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => $vendorDir . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => $vendorDir . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Config\\Loader' => $vendorDir . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => $vendorDir . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => $vendorDir . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => $vendorDir . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\Definitions\\AccessorDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/AccessorDefinition.php', + 'Nette\\DI\\Definitions\\Definition' => $vendorDir . '/nette/di/src/DI/Definitions/Definition.php', + 'Nette\\DI\\Definitions\\FactoryDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/FactoryDefinition.php', + 'Nette\\DI\\Definitions\\ImportedDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/ImportedDefinition.php', + 'Nette\\DI\\Definitions\\LocatorDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/LocatorDefinition.php', + 'Nette\\DI\\Definitions\\Reference' => $vendorDir . '/nette/di/src/DI/Definitions/Reference.php', + 'Nette\\DI\\Definitions\\ServiceDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/ServiceDefinition.php', + 'Nette\\DI\\Definitions\\Statement' => $vendorDir . '/nette/di/src/DI/Definitions/Statement.php', + 'Nette\\DI\\DependencyChecker' => $vendorDir . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\DynamicParameter' => $vendorDir . '/nette/di/src/DI/DynamicParameter.php', + 'Nette\\DI\\Extensions\\DIExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\DefinitionSchema' => $vendorDir . '/nette/di/src/DI/Extensions/DefinitionSchema.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => $vendorDir . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\ParametersExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ParametersExtension.php', + 'Nette\\DI\\Extensions\\SearchExtension' => $vendorDir . '/nette/di/src/DI/Extensions/SearchExtension.php', + 'Nette\\DI\\Extensions\\ServicesExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ServicesExtension.php', + 'Nette\\DI\\Helpers' => $vendorDir . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\InvalidConfigurationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\MissingServiceException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\NotAllowedDuringResolvingException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => $vendorDir . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\Resolver' => $vendorDir . '/nette/di/src/DI/Resolver.php', + 'Nette\\DI\\ServiceCreationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => $vendorDir . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Statement' => $vendorDir . '/nette/di/src/compatibility.php', + 'Nette\\Database\\CheckConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Connection' => $vendorDir . '/nette/database/src/Database/Connection.php', + 'Nette\\Database\\ConnectionException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\ConnectionLostException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\ConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Context' => $vendorDir . '/nette/database/src/compatibility.php', + 'Nette\\Database\\Conventions' => $vendorDir . '/nette/database/src/Database/Conventions.php', + 'Nette\\Database\\Conventions\\AmbiguousReferenceKeyException' => $vendorDir . '/nette/database/src/Database/Conventions/AmbiguousReferenceKeyException.php', + 'Nette\\Database\\Conventions\\DiscoveredConventions' => $vendorDir . '/nette/database/src/Database/Conventions/DiscoveredConventions.php', + 'Nette\\Database\\Conventions\\StaticConventions' => $vendorDir . '/nette/database/src/Database/Conventions/StaticConventions.php', + 'Nette\\Database\\DateTime' => $vendorDir . '/nette/database/src/Database/DateTime.php', + 'Nette\\Database\\DeadlockException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Driver' => $vendorDir . '/nette/database/src/Database/Driver.php', + 'Nette\\Database\\DriverException' => $vendorDir . '/nette/database/src/Database/DriverException.php', + 'Nette\\Database\\Drivers\\MsSqlDriver' => $vendorDir . '/nette/database/src/Database/Drivers/MsSqlDriver.php', + 'Nette\\Database\\Drivers\\MySqlDriver' => $vendorDir . '/nette/database/src/Database/Drivers/MySqlDriver.php', + 'Nette\\Database\\Drivers\\OciDriver' => $vendorDir . '/nette/database/src/Database/Drivers/OciDriver.php', + 'Nette\\Database\\Drivers\\OdbcDriver' => $vendorDir . '/nette/database/src/Database/Drivers/OdbcDriver.php', + 'Nette\\Database\\Drivers\\PgSqlDriver' => $vendorDir . '/nette/database/src/Database/Drivers/PgSqlDriver.php', + 'Nette\\Database\\Drivers\\SqliteDriver' => $vendorDir . '/nette/database/src/Database/Drivers/SqliteDriver.php', + 'Nette\\Database\\Drivers\\SqlsrvDriver' => $vendorDir . '/nette/database/src/Database/Drivers/SqlsrvDriver.php', + 'Nette\\Database\\Explorer' => $vendorDir . '/nette/database/src/Database/Explorer.php', + 'Nette\\Database\\ForeignKeyConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Helpers' => $vendorDir . '/nette/database/src/Database/Helpers.php', + 'Nette\\Database\\IConventions' => $vendorDir . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\IRow' => $vendorDir . '/nette/database/src/Database/IRow.php', + 'Nette\\Database\\IRowContainer' => $vendorDir . '/nette/database/src/Database/IRowContainer.php', + 'Nette\\Database\\IStructure' => $vendorDir . '/nette/database/src/Database/IStructure.php', + 'Nette\\Database\\ISupplementalDriver' => $vendorDir . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\LockTimeoutException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\NotNullConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Reflection' => $vendorDir . '/nette/database/src/Database/Reflection.php', + 'Nette\\Database\\Reflection\\Column' => $vendorDir . '/nette/database/src/Database/Reflection/Column.php', + 'Nette\\Database\\Reflection\\ForeignKey' => $vendorDir . '/nette/database/src/Database/Reflection/ForeignKey.php', + 'Nette\\Database\\Reflection\\Index' => $vendorDir . '/nette/database/src/Database/Reflection/Index.php', + 'Nette\\Database\\Reflection\\Table' => $vendorDir . '/nette/database/src/Database/Reflection/Table.php', + 'Nette\\Database\\ResultSet' => $vendorDir . '/nette/database/src/Database/ResultSet.php', + 'Nette\\Database\\Row' => $vendorDir . '/nette/database/src/Database/Row.php', + 'Nette\\Database\\SqlLiteral' => $vendorDir . '/nette/database/src/Database/SqlLiteral.php', + 'Nette\\Database\\SqlPreprocessor' => $vendorDir . '/nette/database/src/Database/SqlPreprocessor.php', + 'Nette\\Database\\Structure' => $vendorDir . '/nette/database/src/Database/Structure.php', + 'Nette\\Database\\Table\\ActiveRow' => $vendorDir . '/nette/database/src/Database/Table/ActiveRow.php', + 'Nette\\Database\\Table\\GroupedSelection' => $vendorDir . '/nette/database/src/Database/Table/GroupedSelection.php', + 'Nette\\Database\\Table\\IRow' => $vendorDir . '/nette/database/src/Database/Table/IRow.php', + 'Nette\\Database\\Table\\IRowContainer' => $vendorDir . '/nette/database/src/Database/Table/IRowContainer.php', + 'Nette\\Database\\Table\\Selection' => $vendorDir . '/nette/database/src/Database/Table/Selection.php', + 'Nette\\Database\\Table\\SqlBuilder' => $vendorDir . '/nette/database/src/Database/Table/SqlBuilder.php', + 'Nette\\Database\\UniqueConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Forms\\Blueprint' => $vendorDir . '/nette/forms/src/Forms/Blueprint.php', + 'Nette\\Forms\\Container' => $vendorDir . '/nette/forms/src/Forms/Container.php', + 'Nette\\Forms\\Control' => $vendorDir . '/nette/forms/src/Forms/Control.php', + 'Nette\\Forms\\ControlGroup' => $vendorDir . '/nette/forms/src/Forms/ControlGroup.php', + 'Nette\\Forms\\Controls\\BaseControl' => $vendorDir . '/nette/forms/src/Forms/Controls/BaseControl.php', + 'Nette\\Forms\\Controls\\Button' => $vendorDir . '/nette/forms/src/Forms/Controls/Button.php', + 'Nette\\Forms\\Controls\\Checkbox' => $vendorDir . '/nette/forms/src/Forms/Controls/Checkbox.php', + 'Nette\\Forms\\Controls\\CheckboxList' => $vendorDir . '/nette/forms/src/Forms/Controls/CheckboxList.php', + 'Nette\\Forms\\Controls\\ChoiceControl' => $vendorDir . '/nette/forms/src/Forms/Controls/ChoiceControl.php', + 'Nette\\Forms\\Controls\\ColorPicker' => $vendorDir . '/nette/forms/src/Forms/Controls/ColorPicker.php', + 'Nette\\Forms\\Controls\\CsrfProtection' => $vendorDir . '/nette/forms/src/Forms/Controls/CsrfProtection.php', + 'Nette\\Forms\\Controls\\DateTimeControl' => $vendorDir . '/nette/forms/src/Forms/Controls/DateTimeControl.php', + 'Nette\\Forms\\Controls\\HiddenField' => $vendorDir . '/nette/forms/src/Forms/Controls/HiddenField.php', + 'Nette\\Forms\\Controls\\ImageButton' => $vendorDir . '/nette/forms/src/Forms/Controls/ImageButton.php', + 'Nette\\Forms\\Controls\\MultiChoiceControl' => $vendorDir . '/nette/forms/src/Forms/Controls/MultiChoiceControl.php', + 'Nette\\Forms\\Controls\\MultiSelectBox' => $vendorDir . '/nette/forms/src/Forms/Controls/MultiSelectBox.php', + 'Nette\\Forms\\Controls\\RadioList' => $vendorDir . '/nette/forms/src/Forms/Controls/RadioList.php', + 'Nette\\Forms\\Controls\\SelectBox' => $vendorDir . '/nette/forms/src/Forms/Controls/SelectBox.php', + 'Nette\\Forms\\Controls\\SubmitButton' => $vendorDir . '/nette/forms/src/Forms/Controls/SubmitButton.php', + 'Nette\\Forms\\Controls\\TextArea' => $vendorDir . '/nette/forms/src/Forms/Controls/TextArea.php', + 'Nette\\Forms\\Controls\\TextBase' => $vendorDir . '/nette/forms/src/Forms/Controls/TextBase.php', + 'Nette\\Forms\\Controls\\TextInput' => $vendorDir . '/nette/forms/src/Forms/Controls/TextInput.php', + 'Nette\\Forms\\Controls\\UploadControl' => $vendorDir . '/nette/forms/src/Forms/Controls/UploadControl.php', + 'Nette\\Forms\\Form' => $vendorDir . '/nette/forms/src/Forms/Form.php', + 'Nette\\Forms\\FormRenderer' => $vendorDir . '/nette/forms/src/Forms/FormRenderer.php', + 'Nette\\Forms\\Helpers' => $vendorDir . '/nette/forms/src/Forms/Helpers.php', + 'Nette\\Forms\\IControl' => $vendorDir . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\IFormRenderer' => $vendorDir . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\ISubmitterControl' => $vendorDir . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\Rendering\\DefaultFormRenderer' => $vendorDir . '/nette/forms/src/Forms/Rendering/DefaultFormRenderer.php', + 'Nette\\Forms\\Rule' => $vendorDir . '/nette/forms/src/Forms/Rule.php', + 'Nette\\Forms\\Rules' => $vendorDir . '/nette/forms/src/Forms/Rules.php', + 'Nette\\Forms\\SubmitterControl' => $vendorDir . '/nette/forms/src/Forms/SubmitterControl.php', + 'Nette\\Forms\\Validator' => $vendorDir . '/nette/forms/src/Forms/Validator.php', + 'Nette\\HtmlStringable' => $vendorDir . '/nette/utils/src/HtmlStringable.php', + 'Nette\\Http\\Context' => $vendorDir . '/nette/http/src/Http/Context.php', + 'Nette\\Http\\FetchDest' => $vendorDir . '/nette/http/src/Http/enums.php', + 'Nette\\Http\\FetchSite' => $vendorDir . '/nette/http/src/Http/enums.php', + 'Nette\\Http\\FileUpload' => $vendorDir . '/nette/http/src/Http/FileUpload.php', + 'Nette\\Http\\Helpers' => $vendorDir . '/nette/http/src/Http/Helpers.php', + 'Nette\\Http\\IPAddress' => $vendorDir . '/nette/http/src/Http/IPAddress.php', + 'Nette\\Http\\IRequest' => $vendorDir . '/nette/http/src/Http/IRequest.php', + 'Nette\\Http\\IResponse' => $vendorDir . '/nette/http/src/Http/IResponse.php', + 'Nette\\Http\\Request' => $vendorDir . '/nette/http/src/Http/Request.php', + 'Nette\\Http\\RequestFactory' => $vendorDir . '/nette/http/src/Http/RequestFactory.php', + 'Nette\\Http\\Response' => $vendorDir . '/nette/http/src/Http/Response.php', + 'Nette\\Http\\SameSite' => $vendorDir . '/nette/http/src/Http/enums.php', + 'Nette\\Http\\Session' => $vendorDir . '/nette/http/src/Http/Session.php', + 'Nette\\Http\\SessionSection' => $vendorDir . '/nette/http/src/Http/SessionSection.php', + 'Nette\\Http\\Url' => $vendorDir . '/nette/http/src/Http/Url.php', + 'Nette\\Http\\UrlImmutable' => $vendorDir . '/nette/http/src/Http/UrlImmutable.php', + 'Nette\\Http\\UrlScript' => $vendorDir . '/nette/http/src/Http/UrlScript.php', + 'Nette\\Http\\UrlValidator' => $vendorDir . '/nette/http/src/Http/UrlValidator.php', + 'Nette\\IOException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\Loaders\\RobotLoader' => $vendorDir . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/compatibility.php', + 'Nette\\Localization\\Translator' => $vendorDir . '/nette/utils/src/Translator.php', + 'Nette\\Mail\\CssInliner' => $vendorDir . '/nette/mail/src/Mail/CssInliner.php', + 'Nette\\Mail\\DkimSigner' => $vendorDir . '/nette/mail/src/Mail/DkimSigner.php', + 'Nette\\Mail\\FallbackMailer' => $vendorDir . '/nette/mail/src/Mail/FallbackMailer.php', + 'Nette\\Mail\\FallbackMailerException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\FileMailer' => $vendorDir . '/nette/mail/src/Mail/FileMailer.php', + 'Nette\\Mail\\HtmlComposer' => $vendorDir . '/nette/mail/src/Mail/HtmlComposer.php', + 'Nette\\Mail\\IMailer' => $vendorDir . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Interceptor' => $vendorDir . '/nette/mail/src/Mail/Interceptor.php', + 'Nette\\Mail\\Mailer' => $vendorDir . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Message' => $vendorDir . '/nette/mail/src/Mail/Message.php', + 'Nette\\Mail\\MimePart' => $vendorDir . '/nette/mail/src/Mail/MimePart.php', + 'Nette\\Mail\\SendException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SendmailMailer' => $vendorDir . '/nette/mail/src/Mail/SendmailMailer.php', + 'Nette\\Mail\\SignException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\Signer' => $vendorDir . '/nette/mail/src/Mail/Signer.php', + 'Nette\\Mail\\SmtpException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SmtpMailer' => $vendorDir . '/nette/mail/src/Mail/SmtpMailer.php', + 'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Neon\\Decoder' => $vendorDir . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => $vendorDir . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => $vendorDir . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => $vendorDir . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Lexer' => $vendorDir . '/nette/neon/src/Neon/Lexer.php', + 'Nette\\Neon\\Neon' => $vendorDir . '/nette/neon/src/Neon/Neon.php', + 'Nette\\Neon\\Node' => $vendorDir . '/nette/neon/src/Neon/Node.php', + 'Nette\\Neon\\Node\\ArrayItemNode' => $vendorDir . '/nette/neon/src/Neon/Node/ArrayItemNode.php', + 'Nette\\Neon\\Node\\ArrayNode' => $vendorDir . '/nette/neon/src/Neon/Node/ArrayNode.php', + 'Nette\\Neon\\Node\\BlockArrayNode' => $vendorDir . '/nette/neon/src/Neon/Node/BlockArrayNode.php', + 'Nette\\Neon\\Node\\EntityChainNode' => $vendorDir . '/nette/neon/src/Neon/Node/EntityChainNode.php', + 'Nette\\Neon\\Node\\EntityNode' => $vendorDir . '/nette/neon/src/Neon/Node/EntityNode.php', + 'Nette\\Neon\\Node\\InlineArrayNode' => $vendorDir . '/nette/neon/src/Neon/Node/InlineArrayNode.php', + 'Nette\\Neon\\Node\\LiteralNode' => $vendorDir . '/nette/neon/src/Neon/Node/LiteralNode.php', + 'Nette\\Neon\\Node\\StringNode' => $vendorDir . '/nette/neon/src/Neon/Node/StringNode.php', + 'Nette\\Neon\\Parser' => $vendorDir . '/nette/neon/src/Neon/Parser.php', + 'Nette\\Neon\\Token' => $vendorDir . '/nette/neon/src/Neon/Token.php', + 'Nette\\Neon\\TokenStream' => $vendorDir . '/nette/neon/src/Neon/TokenStream.php', + 'Nette\\Neon\\Traverser' => $vendorDir . '/nette/neon/src/Neon/Traverser.php', + 'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\PhpGenerator\\Attribute' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Attribute.php', + 'Nette\\PhpGenerator\\ClassLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassLike.php', + 'Nette\\PhpGenerator\\ClassManipulator' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassManipulator.php', + 'Nette\\PhpGenerator\\ClassType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Dumper' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Dumper.php', + 'Nette\\PhpGenerator\\EnumCase' => $vendorDir . '/nette/php-generator/src/PhpGenerator/EnumCase.php', + 'Nette\\PhpGenerator\\EnumType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/EnumType.php', + 'Nette\\PhpGenerator\\Extractor' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Extractor.php', + 'Nette\\PhpGenerator\\Factory' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => $vendorDir . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\InterfaceType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/InterfaceType.php', + 'Nette\\PhpGenerator\\Literal' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Literal.php', + 'Nette\\PhpGenerator\\Method' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Printer' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Printer.php', + 'Nette\\PhpGenerator\\PromotedParameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PromotedParameter.php', + 'Nette\\PhpGenerator\\Property' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\PropertyAccessMode' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PropertyAccessMode.php', + 'Nette\\PhpGenerator\\PropertyHook' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PropertyHook.php', + 'Nette\\PhpGenerator\\PropertyHookType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PropertyHookType.php', + 'Nette\\PhpGenerator\\PsrPrinter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php', + 'Nette\\PhpGenerator\\TraitType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/TraitType.php', + 'Nette\\PhpGenerator\\TraitUse' => $vendorDir . '/nette/php-generator/src/PhpGenerator/TraitUse.php', + 'Nette\\PhpGenerator\\Traits\\AttributeAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\ConstantsAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/ConstantsAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\MethodsAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/MethodsAware.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertiesAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/PropertiesAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertyLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/PropertyLike.php', + 'Nette\\PhpGenerator\\Traits\\TraitsAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/TraitsAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\PhpGenerator\\Type' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Type.php', + 'Nette\\PhpGenerator\\Visibility' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Visibility.php', + 'Nette\\Routing\\Route' => $vendorDir . '/nette/routing/src/Routing/Route.php', + 'Nette\\Routing\\RouteList' => $vendorDir . '/nette/routing/src/Routing/RouteList.php', + 'Nette\\Routing\\Router' => $vendorDir . '/nette/routing/src/Routing/Router.php', + 'Nette\\Routing\\SimpleRouter' => $vendorDir . '/nette/routing/src/Routing/SimpleRouter.php', + 'Nette\\Schema\\Context' => $vendorDir . '/nette/schema/src/Schema/Context.php', + 'Nette\\Schema\\DynamicParameter' => $vendorDir . '/nette/schema/src/Schema/DynamicParameter.php', + 'Nette\\Schema\\Elements\\AnyOf' => $vendorDir . '/nette/schema/src/Schema/Elements/AnyOf.php', + 'Nette\\Schema\\Elements\\Base' => $vendorDir . '/nette/schema/src/Schema/Elements/Base.php', + 'Nette\\Schema\\Elements\\Structure' => $vendorDir . '/nette/schema/src/Schema/Elements/Structure.php', + 'Nette\\Schema\\Elements\\Type' => $vendorDir . '/nette/schema/src/Schema/Elements/Type.php', + 'Nette\\Schema\\Expect' => $vendorDir . '/nette/schema/src/Schema/Expect.php', + 'Nette\\Schema\\Helpers' => $vendorDir . '/nette/schema/src/Schema/Helpers.php', + 'Nette\\Schema\\Message' => $vendorDir . '/nette/schema/src/Schema/Message.php', + 'Nette\\Schema\\Processor' => $vendorDir . '/nette/schema/src/Schema/Processor.php', + 'Nette\\Schema\\Schema' => $vendorDir . '/nette/schema/src/Schema/Schema.php', + 'Nette\\Schema\\ValidationException' => $vendorDir . '/nette/schema/src/Schema/ValidationException.php', + 'Nette\\Security\\AuthenticationException' => $vendorDir . '/nette/security/src/Security/AuthenticationException.php', + 'Nette\\Security\\Authenticator' => $vendorDir . '/nette/security/src/Security/Authenticator.php', + 'Nette\\Security\\Authorizator' => $vendorDir . '/nette/security/src/Security/Authorizator.php', + 'Nette\\Security\\IAuthenticator' => $vendorDir . '/nette/security/src/Security/IAuthenticator.php', + 'Nette\\Security\\IAuthorizator' => $vendorDir . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IIdentity' => $vendorDir . '/nette/security/src/Security/IIdentity.php', + 'Nette\\Security\\IResource' => $vendorDir . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IRole' => $vendorDir . '/nette/security/src/compatibility.php', + 'Nette\\Security\\Identity' => $vendorDir . '/nette/security/src/Security/Identity.php', + 'Nette\\Security\\IdentityHandler' => $vendorDir . '/nette/security/src/Security/IdentityHandler.php', + 'Nette\\Security\\Passwords' => $vendorDir . '/nette/security/src/Security/Passwords.php', + 'Nette\\Security\\Permission' => $vendorDir . '/nette/security/src/Security/Permission.php', + 'Nette\\Security\\Resource' => $vendorDir . '/nette/security/src/Security/Resource.php', + 'Nette\\Security\\Role' => $vendorDir . '/nette/security/src/Security/Role.php', + 'Nette\\Security\\SimpleAuthenticator' => $vendorDir . '/nette/security/src/Security/SimpleAuthenticator.php', + 'Nette\\Security\\SimpleIdentity' => $vendorDir . '/nette/security/src/Security/SimpleIdentity.php', + 'Nette\\Security\\User' => $vendorDir . '/nette/security/src/Security/User.php', + 'Nette\\Security\\UserStorage' => $vendorDir . '/nette/security/src/Security/UserStorage.php', + 'Nette\\ShouldNotHappenException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/SmartObject.php', + 'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/StaticClass.php', + 'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\DateTimeImmutable' => $vendorDir . '/nette/utils/src/Utils/DateTimeImmutable.php', + 'Nette\\Utils\\FileInfo' => $vendorDir . '/nette/utils/src/Utils/FileInfo.php', + 'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => $vendorDir . '/nette/utils/src/Utils/Finder.php', + 'Nette\\Utils\\Floats' => $vendorDir . '/nette/utils/src/Utils/Floats.php', + 'Nette\\Utils\\Helpers' => $vendorDir . '/nette/utils/src/Utils/Helpers.php', + 'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/compatibility.php', + 'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageColor' => $vendorDir . '/nette/utils/src/Utils/ImageColor.php', + 'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ImageType' => $vendorDir . '/nette/utils/src/Utils/ImageType.php', + 'Nette\\Utils\\Iterables' => $vendorDir . '/nette/utils/src/Utils/Iterables.php', + 'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Process' => $vendorDir . '/nette/utils/src/Utils/Process.php', + 'Nette\\Utils\\ProcessFailedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ProcessTimeoutException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\ReflectionMethod' => $vendorDir . '/nette/utils/src/Utils/ReflectionMethod.php', + 'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\Type' => $vendorDir . '/nette/utils/src/Utils/Type.php', + 'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php', + 'Tester\\Ansi' => $vendorDir . '/nette/tester/src/Framework/Ansi.php', + 'Tester\\Assert' => $vendorDir . '/nette/tester/src/Framework/Assert.php', + 'Tester\\AssertException' => $vendorDir . '/nette/tester/src/Framework/AssertException.php', + 'Tester\\CodeCoverage\\Collector' => $vendorDir . '/nette/tester/src/CodeCoverage/Collector.php', + 'Tester\\CodeCoverage\\Generators\\AbstractGenerator' => $vendorDir . '/nette/tester/src/CodeCoverage/Generators/AbstractGenerator.php', + 'Tester\\CodeCoverage\\Generators\\CloverXMLGenerator' => $vendorDir . '/nette/tester/src/CodeCoverage/Generators/CloverXMLGenerator.php', + 'Tester\\CodeCoverage\\Generators\\HtmlGenerator' => $vendorDir . '/nette/tester/src/CodeCoverage/Generators/HtmlGenerator.php', + 'Tester\\CodeCoverage\\PhpParser' => $vendorDir . '/nette/tester/src/CodeCoverage/PhpParser.php', + 'Tester\\DataProvider' => $vendorDir . '/nette/tester/src/Framework/DataProvider.php', + 'Tester\\DomQuery' => $vendorDir . '/nette/tester/src/Framework/DomQuery.php', + 'Tester\\Dumper' => $vendorDir . '/nette/tester/src/Framework/Dumper.php', + 'Tester\\Environment' => $vendorDir . '/nette/tester/src/Framework/Environment.php', + 'Tester\\Expect' => $vendorDir . '/nette/tester/src/Framework/Expect.php', + 'Tester\\FileMock' => $vendorDir . '/nette/tester/src/Framework/FileMock.php', + 'Tester\\FileMutator' => $vendorDir . '/nette/tester/src/Framework/FileMutator.php', + 'Tester\\Helpers' => $vendorDir . '/nette/tester/src/Framework/Helpers.php', + 'Tester\\HttpAssert' => $vendorDir . '/nette/tester/src/Framework/HttpAssert.php', + 'Tester\\Runner\\CliTester' => $vendorDir . '/nette/tester/src/Runner/CliTester.php', + 'Tester\\Runner\\CommandLine' => $vendorDir . '/nette/tester/src/Runner/CommandLine.php', + 'Tester\\Runner\\InterruptException' => $vendorDir . '/nette/tester/src/Runner/exceptions.php', + 'Tester\\Runner\\Job' => $vendorDir . '/nette/tester/src/Runner/Job.php', + 'Tester\\Runner\\OutputHandler' => $vendorDir . '/nette/tester/src/Runner/OutputHandler.php', + 'Tester\\Runner\\Output\\ConsolePrinter' => $vendorDir . '/nette/tester/src/Runner/Output/ConsolePrinter.php', + 'Tester\\Runner\\Output\\JUnitPrinter' => $vendorDir . '/nette/tester/src/Runner/Output/JUnitPrinter.php', + 'Tester\\Runner\\Output\\Logger' => $vendorDir . '/nette/tester/src/Runner/Output/Logger.php', + 'Tester\\Runner\\Output\\TapPrinter' => $vendorDir . '/nette/tester/src/Runner/Output/TapPrinter.php', + 'Tester\\Runner\\PhpInterpreter' => $vendorDir . '/nette/tester/src/Runner/PhpInterpreter.php', + 'Tester\\Runner\\Runner' => $vendorDir . '/nette/tester/src/Runner/Runner.php', + 'Tester\\Runner\\Test' => $vendorDir . '/nette/tester/src/Runner/Test.php', + 'Tester\\Runner\\TestHandler' => $vendorDir . '/nette/tester/src/Runner/TestHandler.php', + 'Tester\\TestCase' => $vendorDir . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseException' => $vendorDir . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseSkippedException' => $vendorDir . '/nette/tester/src/Framework/TestCase.php', + 'Tracy\\Bar' => $vendorDir . '/tracy/tracy/src/Tracy/Bar/Bar.php', + 'Tracy\\BlueScreen' => $vendorDir . '/tracy/tracy/src/Tracy/BlueScreen/BlueScreen.php', + 'Tracy\\Bridges\\Nette\\Bridge' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/Bridge.php', + 'Tracy\\Bridges\\Nette\\MailSender' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/MailSender.php', + 'Tracy\\Bridges\\Nette\\TracyExtension' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/TracyExtension.php', + 'Tracy\\Bridges\\Psr\\PsrToTracyLoggerAdapter' => $vendorDir . '/tracy/tracy/src/Bridges/Psr/PsrToTracyLoggerAdapter.php', + 'Tracy\\Bridges\\Psr\\TracyToPsrLoggerAdapter' => $vendorDir . '/tracy/tracy/src/Bridges/Psr/TracyToPsrLoggerAdapter.php', + 'Tracy\\CodeHighlighter' => $vendorDir . '/tracy/tracy/src/Tracy/BlueScreen/CodeHighlighter.php', + 'Tracy\\Debugger' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/Debugger.php', + 'Tracy\\DefaultBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/Bar/DefaultBarPanel.php', + 'Tracy\\DeferredContent' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/DeferredContent.php', + 'Tracy\\DevelopmentStrategy' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/DevelopmentStrategy.php', + 'Tracy\\Dumper' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Dumper.php', + 'Tracy\\Dumper\\Describer' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Describer.php', + 'Tracy\\Dumper\\Exposer' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Exposer.php', + 'Tracy\\Dumper\\Renderer' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Renderer.php', + 'Tracy\\Dumper\\Value' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Value.php', + 'Tracy\\FileSession' => $vendorDir . '/tracy/tracy/src/Tracy/Session/FileSession.php', + 'Tracy\\Helpers' => $vendorDir . '/tracy/tracy/src/Tracy/Helpers.php', + 'Tracy\\IBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/Bar/IBarPanel.php', + 'Tracy\\ILogger' => $vendorDir . '/tracy/tracy/src/Tracy/Logger/ILogger.php', + 'Tracy\\Logger' => $vendorDir . '/tracy/tracy/src/Tracy/Logger/Logger.php', + 'Tracy\\NativeSession' => $vendorDir . '/tracy/tracy/src/Tracy/Session/NativeSession.php', + 'Tracy\\OutputDebugger' => $vendorDir . '/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php', + 'Tracy\\ProductionStrategy' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/ProductionStrategy.php', + 'Tracy\\SessionStorage' => $vendorDir . '/tracy/tracy/src/Tracy/Session/SessionStorage.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 00000000..1cb9657e --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,11 @@ + $vendorDir . '/phpstan/phpstan/bootstrap.php', + 'd507e002f7fce7f0c6dbf1f22edcb902' => $vendorDir . '/tracy/tracy/src/Tracy/functions.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..15a2ff3a --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/tracy/tracy/src'), + 'Tester\\' => array($vendorDir . '/nette/tester/src'), + 'Symfony\\Thanks\\' => array($vendorDir . '/symfony/thanks/src'), + 'PHPStan\\ExtensionInstaller\\' => array($vendorDir . '/phpstan/extension-installer/src'), + 'Nette\\PHPStan\\' => array($vendorDir . '/nette/phpstan-rules/src'), + 'Nette\\' => array($vendorDir . '/nette/security/src', $vendorDir . '/nette/mail/src', $vendorDir . '/nette/forms/src', $vendorDir . '/nette/database/src', $vendorDir . '/nette/bootstrap/src', $vendorDir . '/nette/assets/src', $vendorDir . '/nette/application/src', $vendorDir . '/nette/routing/src', $vendorDir . '/nette/di/src', $vendorDir . '/nette/caching/src', $vendorDir . '/nette/schema/src', $vendorDir . '/nette/robot-loader/src', $vendorDir . '/nette/php-generator/src', $vendorDir . '/nette/neon/src', $vendorDir . '/nette/component-model/src', $vendorDir . '/nette/http/src', $vendorDir . '/nette/utils/src'), + 'Latte\\' => array($vendorDir . '/latte/latte/src/Latte'), + 'App\\' => array($baseDir . '/app'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 00000000..ca07bdda --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,48 @@ +register(true); + + $filesToLoad = \Composer\Autoload\ComposerStaticInit38f417078fc5f615987c051d0a0c9213::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); + } + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 00000000..c66538dc --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,805 @@ + __DIR__ . '/..' . '/phpstan/phpstan/bootstrap.php', + 'd507e002f7fce7f0c6dbf1f22edcb902' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/functions.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'T' => + array ( + 'Tracy\\' => 6, + 'Tester\\' => 7, + ), + 'S' => + array ( + 'Symfony\\Thanks\\' => 15, + ), + 'P' => + array ( + 'PHPStan\\ExtensionInstaller\\' => 27, + ), + 'N' => + array ( + 'Nette\\PHPStan\\' => 14, + 'Nette\\' => 6, + ), + 'L' => + array ( + 'Latte\\' => 6, + ), + 'A' => + array ( + 'App\\' => 4, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Tracy\\' => + array ( + 0 => __DIR__ . '/..' . '/tracy/tracy/src', + ), + 'Tester\\' => + array ( + 0 => __DIR__ . '/..' . '/nette/tester/src', + ), + 'Symfony\\Thanks\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/thanks/src', + ), + 'PHPStan\\ExtensionInstaller\\' => + array ( + 0 => __DIR__ . '/..' . '/phpstan/extension-installer/src', + ), + 'Nette\\PHPStan\\' => + array ( + 0 => __DIR__ . '/..' . '/nette/phpstan-rules/src', + ), + 'Nette\\' => + array ( + 0 => __DIR__ . '/..' . '/nette/security/src', + 1 => __DIR__ . '/..' . '/nette/mail/src', + 2 => __DIR__ . '/..' . '/nette/forms/src', + 3 => __DIR__ . '/..' . '/nette/database/src', + 4 => __DIR__ . '/..' . '/nette/bootstrap/src', + 5 => __DIR__ . '/..' . '/nette/assets/src', + 6 => __DIR__ . '/..' . '/nette/application/src', + 7 => __DIR__ . '/..' . '/nette/routing/src', + 8 => __DIR__ . '/..' . '/nette/di/src', + 9 => __DIR__ . '/..' . '/nette/caching/src', + 10 => __DIR__ . '/..' . '/nette/schema/src', + 11 => __DIR__ . '/..' . '/nette/robot-loader/src', + 12 => __DIR__ . '/..' . '/nette/php-generator/src', + 13 => __DIR__ . '/..' . '/nette/neon/src', + 14 => __DIR__ . '/..' . '/nette/component-model/src', + 15 => __DIR__ . '/..' . '/nette/http/src', + 16 => __DIR__ . '/..' . '/nette/utils/src', + ), + 'Latte\\' => + array ( + 0 => __DIR__ . '/..' . '/latte/latte/src/Latte', + ), + 'App\\' => + array ( + 0 => __DIR__ . '/../..' . '/app', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'Latte\\Attributes\\TemplateFilter' => __DIR__ . '/..' . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Attributes\\TemplateFunction' => __DIR__ . '/..' . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Bridges\\Tracy\\BlueScreenPanel' => __DIR__ . '/..' . '/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php', + 'Latte\\Bridges\\Tracy\\LattePanel' => __DIR__ . '/..' . '/latte/latte/src/Bridges/Tracy/LattePanel.php', + 'Latte\\Bridges\\Tracy\\TracyExtension' => __DIR__ . '/..' . '/latte/latte/src/Bridges/Tracy/TracyExtension.php', + 'Latte\\CompileException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Compiler\\Block' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Block.php', + 'Latte\\Compiler\\Dedent' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Dedent.php', + 'Latte\\Compiler\\Escaper' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Escaper.php', + 'Latte\\Compiler\\Node' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Node.php', + 'Latte\\Compiler\\NodeHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/NodeHelpers.php', + 'Latte\\Compiler\\NodeTraverser' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/NodeTraverser.php', + 'Latte\\Compiler\\Nodes\\AreaNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php', + 'Latte\\Compiler\\Nodes\\AuxiliaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\FragmentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\AttributeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\BogusTagNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php', + 'Latte\\Compiler\\Nodes\\Html\\CommentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ElementNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ExpressionAttributeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\TagNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php', + 'Latte\\Compiler\\Nodes\\NopNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/NopNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArgumentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArrayItemNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ClosureUseNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ComplexTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ExpressionNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayAccessNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AuxiliaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\BinaryOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CastNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClassConstantFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CloneNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClosureNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ConstantFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\EmptyNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FilterCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FunctionCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InstanceofNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\IssetNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MatchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\NewNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PostOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PreOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticMethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticPropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TemporaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TernaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\UnaryOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\VariableNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php', + 'Latte\\Compiler\\Nodes\\Php\\FilterNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IdentifierNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\InterpolatedStringPartNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IntersectionTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListItemNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php', + 'Latte\\Compiler\\Nodes\\Php\\MatchArmNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ModifierNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NameNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NullableTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\OperatorNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ParameterNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ScalarNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\BooleanNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\FloatNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\IntegerNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\InterpolatedStringNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\NullNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\StringNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\SuperiorTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\UnionTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VarLikeIdentifierNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VariadicPlaceholderNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php', + 'Latte\\Compiler\\Nodes\\PrintNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/PrintNode.php', + 'Latte\\Compiler\\Nodes\\StatementNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php', + 'Latte\\Compiler\\Nodes\\TemplateNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php', + 'Latte\\Compiler\\Nodes\\TextNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/TextNode.php', + 'Latte\\Compiler\\PhpHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/PhpHelpers.php', + 'Latte\\Compiler\\Position' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Position.php', + 'Latte\\Compiler\\PrintContext' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/PrintContext.php', + 'Latte\\Compiler\\Range' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Range.php', + 'Latte\\Compiler\\Tag' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Tag.php', + 'Latte\\Compiler\\TagLexer' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TagLexer.php', + 'Latte\\Compiler\\TagParser' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TagParser.php', + 'Latte\\Compiler\\TagParserData' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TagParserData.php', + 'Latte\\Compiler\\TemplateGenerator' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateGenerator.php', + 'Latte\\Compiler\\TemplateLexer' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateLexer.php', + 'Latte\\Compiler\\TemplateParser' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateParser.php', + 'Latte\\Compiler\\TemplateParserHtml' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateParserHtml.php', + 'Latte\\Compiler\\Token' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Token.php', + 'Latte\\Compiler\\TokenStream' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TokenStream.php', + 'Latte\\ContentType' => __DIR__ . '/..' . '/latte/latte/src/Latte/ContentType.php', + 'Latte\\Engine' => __DIR__ . '/..' . '/latte/latte/src/Latte/Engine.php', + 'Latte\\Essential\\AuxiliaryIterator' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/AuxiliaryIterator.php', + 'Latte\\Essential\\Blueprint' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Blueprint.php', + 'Latte\\Essential\\CachingIterator' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/CachingIterator.php', + 'Latte\\Essential\\CoreExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/CoreExtension.php', + 'Latte\\Essential\\Filters' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Filters.php', + 'Latte\\Essential\\Nodes\\BlockNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/BlockNode.php', + 'Latte\\Essential\\Nodes\\CaptureNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php', + 'Latte\\Essential\\Nodes\\ContentTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php', + 'Latte\\Essential\\Nodes\\CustomFunctionCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php', + 'Latte\\Essential\\Nodes\\DebugbreakNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php', + 'Latte\\Essential\\Nodes\\DefineNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DefineNode.php', + 'Latte\\Essential\\Nodes\\DoNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DoNode.php', + 'Latte\\Essential\\Nodes\\DumpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DumpNode.php', + 'Latte\\Essential\\Nodes\\EmbedNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php', + 'Latte\\Essential\\Nodes\\ExtendsNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php', + 'Latte\\Essential\\Nodes\\FirstLastSepNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php', + 'Latte\\Essential\\Nodes\\ForNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ForNode.php', + 'Latte\\Essential\\Nodes\\ForeachNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php', + 'Latte\\Essential\\Nodes\\IfChangedNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php', + 'Latte\\Essential\\Nodes\\IfContentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php', + 'Latte\\Essential\\Nodes\\IfNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IfNode.php', + 'Latte\\Essential\\Nodes\\ImportNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ImportNode.php', + 'Latte\\Essential\\Nodes\\IncludeBlockNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php', + 'Latte\\Essential\\Nodes\\IncludeFileNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php', + 'Latte\\Essential\\Nodes\\IterateWhileNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php', + 'Latte\\Essential\\Nodes\\JumpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/JumpNode.php', + 'Latte\\Essential\\Nodes\\NAttrNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php', + 'Latte\\Essential\\Nodes\\NClassNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NClassNode.php', + 'Latte\\Essential\\Nodes\\NElseNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NElseNode.php', + 'Latte\\Essential\\Nodes\\NTagNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NTagNode.php', + 'Latte\\Essential\\Nodes\\ParametersNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php', + 'Latte\\Essential\\Nodes\\RawPhpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php', + 'Latte\\Essential\\Nodes\\RollbackNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php', + 'Latte\\Essential\\Nodes\\SpacelessNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php', + 'Latte\\Essential\\Nodes\\SwitchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php', + 'Latte\\Essential\\Nodes\\TemplatePrintNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php', + 'Latte\\Essential\\Nodes\\TemplateTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php', + 'Latte\\Essential\\Nodes\\TraceNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TraceNode.php', + 'Latte\\Essential\\Nodes\\TranslateNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php', + 'Latte\\Essential\\Nodes\\TryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TryNode.php', + 'Latte\\Essential\\Nodes\\VarNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/VarNode.php', + 'Latte\\Essential\\Nodes\\VarPrintNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php', + 'Latte\\Essential\\Nodes\\VarTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php', + 'Latte\\Essential\\Nodes\\WhileNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/WhileNode.php', + 'Latte\\Essential\\Passes' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Passes.php', + 'Latte\\Essential\\RawPhpExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/RawPhpExtension.php', + 'Latte\\Essential\\RollbackException' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/RollbackException.php', + 'Latte\\Essential\\Tracer' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Tracer.php', + 'Latte\\Essential\\TranslatorExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/TranslatorExtension.php', + 'Latte\\Essential\\WhitespaceMinifier' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/WhitespaceMinifier.php', + 'Latte\\Exception' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Extension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Extension.php', + 'Latte\\Feature' => __DIR__ . '/..' . '/latte/latte/src/Latte/enums.php', + 'Latte\\Helpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Helpers.php', + 'Latte\\Loader' => __DIR__ . '/..' . '/latte/latte/src/Latte/Loader.php', + 'Latte\\Loaders\\FileLoader' => __DIR__ . '/..' . '/latte/latte/src/Latte/Loaders/FileLoader.php', + 'Latte\\Loaders\\StringLoader' => __DIR__ . '/..' . '/latte/latte/src/Latte/Loaders/StringLoader.php', + 'Latte\\Policy' => __DIR__ . '/..' . '/latte/latte/src/Latte/Policy.php', + 'Latte\\PositionAwareException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\RuntimeException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Runtime\\Block' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Block.php', + 'Latte\\Runtime\\Cache' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Cache.php', + 'Latte\\Runtime\\FilterExecutor' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/FilterExecutor.php', + 'Latte\\Runtime\\FilterInfo' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/FilterInfo.php', + 'Latte\\Runtime\\FunctionExecutor' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/FunctionExecutor.php', + 'Latte\\Runtime\\Helpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Helpers.php', + 'Latte\\Runtime\\Html' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Html.php', + 'Latte\\Runtime\\HtmlHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/HtmlHelpers.php', + 'Latte\\Runtime\\HtmlStringable' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/HtmlStringable.php', + 'Latte\\Runtime\\Template' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Template.php', + 'Latte\\Runtime\\XmlHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/XmlHelpers.php', + 'Latte\\Sandbox\\Nodes\\FunctionCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php', + 'Latte\\Sandbox\\Nodes\\MethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\PropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php', + 'Latte\\Sandbox\\Nodes\\SandboxNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php', + 'Latte\\Sandbox\\Nodes\\StaticMethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\StaticPropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php', + 'Latte\\Sandbox\\RuntimeChecker' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/RuntimeChecker.php', + 'Latte\\Sandbox\\SandboxExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/SandboxExtension.php', + 'Latte\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/SecurityPolicy.php', + 'Latte\\SecurityViolationException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\TemplateNotFoundException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Tools\\Linter' => __DIR__ . '/..' . '/latte/latte/src/Tools/Linter.php', + 'Latte\\Tools\\LinterExtension' => __DIR__ . '/..' . '/latte/latte/src/Tools/LinterExtension.php', + 'NetteModule\\ErrorPresenter' => __DIR__ . '/..' . '/nette/application/src/Application/ErrorPresenter.php', + 'NetteModule\\MicroPresenter' => __DIR__ . '/..' . '/nette/application/src/Application/MicroPresenter.php', + 'Nette\\Application\\AbortException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Application' => __DIR__ . '/..' . '/nette/application/src/Application/Application.php', + 'Nette\\Application\\ApplicationException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Attributes\\CrossOrigin' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/CrossOrigin.php', + 'Nette\\Application\\Attributes\\Deprecated' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Deprecated.php', + 'Nette\\Application\\Attributes\\Parameter' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Parameter.php', + 'Nette\\Application\\Attributes\\Persistent' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Persistent.php', + 'Nette\\Application\\Attributes\\Requires' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Requires.php', + 'Nette\\Application\\Attributes\\TemplateVariable' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/TemplateVariable.php', + 'Nette\\Application\\BadRequestException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\ForbiddenRequestException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Helpers' => __DIR__ . '/..' . '/nette/application/src/Application/Helpers.php', + 'Nette\\Application\\IPresenter' => __DIR__ . '/..' . '/nette/application/src/Application/IPresenter.php', + 'Nette\\Application\\IPresenterFactory' => __DIR__ . '/..' . '/nette/application/src/Application/IPresenterFactory.php', + 'Nette\\Application\\IResponse' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\InvalidPresenterException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\LinkGenerator' => __DIR__ . '/..' . '/nette/application/src/Application/LinkGenerator.php', + 'Nette\\Application\\PresenterFactory' => __DIR__ . '/..' . '/nette/application/src/Application/PresenterFactory.php', + 'Nette\\Application\\Request' => __DIR__ . '/..' . '/nette/application/src/Application/Request.php', + 'Nette\\Application\\Response' => __DIR__ . '/..' . '/nette/application/src/Application/Response.php', + 'Nette\\Application\\Responses\\CallbackResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/CallbackResponse.php', + 'Nette\\Application\\Responses\\FileResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/FileResponse.php', + 'Nette\\Application\\Responses\\ForwardResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/ForwardResponse.php', + 'Nette\\Application\\Responses\\JsonResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/JsonResponse.php', + 'Nette\\Application\\Responses\\RedirectResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/RedirectResponse.php', + 'Nette\\Application\\Responses\\TextResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/TextResponse.php', + 'Nette\\Application\\Responses\\VoidResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/VoidResponse.php', + 'Nette\\Application\\Routers\\CliRouter' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/CliRouter.php', + 'Nette\\Application\\Routers\\Route' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/Route.php', + 'Nette\\Application\\Routers\\RouteList' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/RouteList.php', + 'Nette\\Application\\Routers\\SimpleRouter' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/SimpleRouter.php', + 'Nette\\Application\\SwitchException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\UI\\AccessPolicy' => __DIR__ . '/..' . '/nette/application/src/Application/UI/AccessPolicy.php', + 'Nette\\Application\\UI\\BadSignalException' => __DIR__ . '/..' . '/nette/application/src/Application/UI/BadSignalException.php', + 'Nette\\Application\\UI\\Component' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Component.php', + 'Nette\\Application\\UI\\ComponentReflection' => __DIR__ . '/..' . '/nette/application/src/Application/UI/ComponentReflection.php', + 'Nette\\Application\\UI\\Control' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Control.php', + 'Nette\\Application\\UI\\Form' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Form.php', + 'Nette\\Application\\UI\\IRenderable' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ISignalReceiver' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\IStatePersistent' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplate' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplateFactory' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\InvalidLinkException' => __DIR__ . '/..' . '/nette/application/src/Application/UI/InvalidLinkException.php', + 'Nette\\Application\\UI\\InvalidRequestParameterException' => __DIR__ . '/..' . '/nette/application/src/Application/UI/InvalidRequestParameterException.php', + 'Nette\\Application\\UI\\Link' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Link.php', + 'Nette\\Application\\UI\\MethodReflection' => __DIR__ . '/..' . '/nette/application/src/Application/UI/MethodReflection.php', + 'Nette\\Application\\UI\\Multiplier' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Multiplier.php', + 'Nette\\Application\\UI\\ParameterConverter' => __DIR__ . '/..' . '/nette/application/src/Application/UI/ParameterConverter.php', + 'Nette\\Application\\UI\\Presenter' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Presenter.php', + 'Nette\\Application\\UI\\Renderable' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Renderable.php', + 'Nette\\Application\\UI\\SignalReceiver' => __DIR__ . '/..' . '/nette/application/src/Application/UI/SignalReceiver.php', + 'Nette\\Application\\UI\\StatePersistent' => __DIR__ . '/..' . '/nette/application/src/Application/UI/StatePersistent.php', + 'Nette\\Application\\UI\\Template' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Template.php', + 'Nette\\Application\\UI\\TemplateFactory' => __DIR__ . '/..' . '/nette/application/src/Application/UI/TemplateFactory.php', + 'Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Assets\\Asset' => __DIR__ . '/..' . '/nette/assets/src/Assets/Asset.php', + 'Nette\\Assets\\AssetNotFoundException' => __DIR__ . '/..' . '/nette/assets/src/Assets/exceptions.php', + 'Nette\\Assets\\AudioAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/AudioAsset.php', + 'Nette\\Assets\\EntryAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/EntryAsset.php', + 'Nette\\Assets\\FilesystemMapper' => __DIR__ . '/..' . '/nette/assets/src/Assets/FilesystemMapper.php', + 'Nette\\Assets\\FontAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/FontAsset.php', + 'Nette\\Assets\\GenericAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/GenericAsset.php', + 'Nette\\Assets\\Helpers' => __DIR__ . '/..' . '/nette/assets/src/Assets/Helpers.php', + 'Nette\\Assets\\HtmlRenderable' => __DIR__ . '/..' . '/nette/assets/src/Assets/HtmlRenderable.php', + 'Nette\\Assets\\ImageAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/ImageAsset.php', + 'Nette\\Assets\\LazyLoad' => __DIR__ . '/..' . '/nette/assets/src/Assets/LazyLoad.php', + 'Nette\\Assets\\Mapper' => __DIR__ . '/..' . '/nette/assets/src/Assets/Mapper.php', + 'Nette\\Assets\\Registry' => __DIR__ . '/..' . '/nette/assets/src/Assets/Registry.php', + 'Nette\\Assets\\ScriptAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/ScriptAsset.php', + 'Nette\\Assets\\StyleAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/StyleAsset.php', + 'Nette\\Assets\\VideoAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/VideoAsset.php', + 'Nette\\Assets\\ViteMapper' => __DIR__ . '/..' . '/nette/assets/src/Assets/ViteMapper.php', + 'Nette\\Bootstrap\\Configurator' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\Bootstrap\\Extensions\\ConstantsExtension' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Extensions/ConstantsExtension.php', + 'Nette\\Bootstrap\\Extensions\\PhpExtension' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Extensions/PhpExtension.php', + 'Nette\\Bridges\\ApplicationDI\\ApplicationExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php', + 'Nette\\Bridges\\ApplicationDI\\LatteExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/LatteExtension.php', + 'Nette\\Bridges\\ApplicationDI\\PresenterFactoryCallback' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php', + 'Nette\\Bridges\\ApplicationDI\\RoutingExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\DefaultTemplate' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php', + 'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Bridges\\ApplicationLatte\\LatteFactory' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\ControlNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/ControlNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkBaseNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\NNonceNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetAreaNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\TemplatePrintNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetRuntime' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php', + 'Nette\\Bridges\\ApplicationLatte\\Template' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Template.php', + 'Nette\\Bridges\\ApplicationLatte\\TemplateFactory' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\UIExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/UIExtension.php', + 'Nette\\Bridges\\ApplicationTracy\\RoutingPanel' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php', + 'Nette\\Bridges\\AssetsDI\\DIExtension' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsDI/DIExtension.php', + 'Nette\\Bridges\\AssetsLatte\\LatteExtension' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\AssetNode' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\NAssetNode' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Runtime' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/Runtime.php', + 'Nette\\Bridges\\CacheDI\\CacheExtension' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheDI/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\CacheExtension' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheLatte/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\Nodes\\CacheNode' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheLatte/Nodes/CacheNode.php', + 'Nette\\Bridges\\CacheLatte\\Runtime' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheLatte/Runtime.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => __DIR__ . '/..' . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\DatabaseDI\\DatabaseExtension' => __DIR__ . '/..' . '/nette/database/src/Bridges/DatabaseDI/DatabaseExtension.php', + 'Nette\\Bridges\\DatabaseTracy\\ConnectionPanel' => __DIR__ . '/..' . '/nette/database/src/Bridges/DatabaseTracy/ConnectionPanel.php', + 'Nette\\Bridges\\FormsDI\\FormsExtension' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsDI/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\FormsExtension' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FieldNNameNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormContainerNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormContainerNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNNameNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormPrintNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormPrintNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputErrorNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputErrorNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\LabelNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/LabelNode.php', + 'Nette\\Bridges\\FormsLatte\\Runtime' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Runtime.php', + 'Nette\\Bridges\\HttpDI\\HttpExtension' => __DIR__ . '/..' . '/nette/http/src/Bridges/HttpDI/HttpExtension.php', + 'Nette\\Bridges\\HttpDI\\SessionExtension' => __DIR__ . '/..' . '/nette/http/src/Bridges/HttpDI/SessionExtension.php', + 'Nette\\Bridges\\HttpTracy\\SessionPanel' => __DIR__ . '/..' . '/nette/http/src/Bridges/HttpTracy/SessionPanel.php', + 'Nette\\Bridges\\MailDI\\MailExtension' => __DIR__ . '/..' . '/nette/mail/src/Bridges/MailDI/MailExtension.php', + 'Nette\\Bridges\\MailTracy\\MailPanel' => __DIR__ . '/..' . '/nette/mail/src/Bridges/MailTracy/MailPanel.php', + 'Nette\\Bridges\\Psr\\PsrCacheAdapter' => __DIR__ . '/..' . '/nette/caching/src/Bridges/Psr/PsrCacheAdapter.php', + 'Nette\\Bridges\\SecurityDI\\SecurityExtension' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityDI/SecurityExtension.php', + 'Nette\\Bridges\\SecurityHttp\\CookieStorage' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityHttp/CookieStorage.php', + 'Nette\\Bridges\\SecurityHttp\\SessionStorage' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityHttp/SessionStorage.php', + 'Nette\\Bridges\\SecurityTracy\\UserPanel' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityTracy/UserPanel.php', + 'Nette\\Caching\\BulkReader' => __DIR__ . '/..' . '/nette/caching/src/Caching/BulkReader.php', + 'Nette\\Caching\\BulkWriter' => __DIR__ . '/..' . '/nette/caching/src/Caching/BulkWriter.php', + 'Nette\\Caching\\Cache' => __DIR__ . '/..' . '/nette/caching/src/Caching/Cache.php', + 'Nette\\Caching\\IBulkReader' => __DIR__ . '/..' . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\IStorage' => __DIR__ . '/..' . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\OutputHelper' => __DIR__ . '/..' . '/nette/caching/src/Caching/OutputHelper.php', + 'Nette\\Caching\\Storage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storage.php', + 'Nette\\Caching\\Storages\\DevNullStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/DevNullStorage.php', + 'Nette\\Caching\\Storages\\FileStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/FileStorage.php', + 'Nette\\Caching\\Storages\\IJournal' => __DIR__ . '/..' . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\Storages\\Journal' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/Journal.php', + 'Nette\\Caching\\Storages\\MemcachedStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/MemcachedStorage.php', + 'Nette\\Caching\\Storages\\MemoryStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/MemoryStorage.php', + 'Nette\\Caching\\Storages\\SQLiteJournal' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/SQLiteJournal.php', + 'Nette\\Caching\\Storages\\SQLiteStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/SQLiteStorage.php', + 'Nette\\ComponentModel\\ArrayAccess' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/ArrayAccess.php', + 'Nette\\ComponentModel\\Component' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/Component.php', + 'Nette\\ComponentModel\\Container' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/Container.php', + 'Nette\\ComponentModel\\IComponent' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/IComponent.php', + 'Nette\\ComponentModel\\IContainer' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/IContainer.php', + 'Nette\\Configurator' => __DIR__ . '/..' . '/nette/bootstrap/src/Configurator.php', + 'Nette\\DI\\Attributes\\Inject' => __DIR__ . '/..' . '/nette/di/src/DI/Attributes/Inject.php', + 'Nette\\DI\\Autowiring' => __DIR__ . '/..' . '/nette/di/src/DI/Autowiring.php', + 'Nette\\DI\\Compiler' => __DIR__ . '/..' . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => __DIR__ . '/..' . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => __DIR__ . '/..' . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Config\\Loader' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => __DIR__ . '/..' . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => __DIR__ . '/..' . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => __DIR__ . '/..' . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\Definitions\\AccessorDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/AccessorDefinition.php', + 'Nette\\DI\\Definitions\\Definition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/Definition.php', + 'Nette\\DI\\Definitions\\FactoryDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/FactoryDefinition.php', + 'Nette\\DI\\Definitions\\ImportedDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/ImportedDefinition.php', + 'Nette\\DI\\Definitions\\LocatorDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/LocatorDefinition.php', + 'Nette\\DI\\Definitions\\Reference' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/Reference.php', + 'Nette\\DI\\Definitions\\ServiceDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/ServiceDefinition.php', + 'Nette\\DI\\Definitions\\Statement' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/Statement.php', + 'Nette\\DI\\DependencyChecker' => __DIR__ . '/..' . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\DynamicParameter' => __DIR__ . '/..' . '/nette/di/src/DI/DynamicParameter.php', + 'Nette\\DI\\Extensions\\DIExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\DefinitionSchema' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DefinitionSchema.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\ParametersExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ParametersExtension.php', + 'Nette\\DI\\Extensions\\SearchExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/SearchExtension.php', + 'Nette\\DI\\Extensions\\ServicesExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ServicesExtension.php', + 'Nette\\DI\\Helpers' => __DIR__ . '/..' . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\InvalidConfigurationException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\MissingServiceException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\NotAllowedDuringResolvingException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => __DIR__ . '/..' . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\Resolver' => __DIR__ . '/..' . '/nette/di/src/DI/Resolver.php', + 'Nette\\DI\\ServiceCreationException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => __DIR__ . '/..' . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Statement' => __DIR__ . '/..' . '/nette/di/src/compatibility.php', + 'Nette\\Database\\CheckConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Connection' => __DIR__ . '/..' . '/nette/database/src/Database/Connection.php', + 'Nette\\Database\\ConnectionException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\ConnectionLostException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\ConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Context' => __DIR__ . '/..' . '/nette/database/src/compatibility.php', + 'Nette\\Database\\Conventions' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions.php', + 'Nette\\Database\\Conventions\\AmbiguousReferenceKeyException' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions/AmbiguousReferenceKeyException.php', + 'Nette\\Database\\Conventions\\DiscoveredConventions' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions/DiscoveredConventions.php', + 'Nette\\Database\\Conventions\\StaticConventions' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions/StaticConventions.php', + 'Nette\\Database\\DateTime' => __DIR__ . '/..' . '/nette/database/src/Database/DateTime.php', + 'Nette\\Database\\DeadlockException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Driver' => __DIR__ . '/..' . '/nette/database/src/Database/Driver.php', + 'Nette\\Database\\DriverException' => __DIR__ . '/..' . '/nette/database/src/Database/DriverException.php', + 'Nette\\Database\\Drivers\\MsSqlDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/MsSqlDriver.php', + 'Nette\\Database\\Drivers\\MySqlDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/MySqlDriver.php', + 'Nette\\Database\\Drivers\\OciDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/OciDriver.php', + 'Nette\\Database\\Drivers\\OdbcDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/OdbcDriver.php', + 'Nette\\Database\\Drivers\\PgSqlDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/PgSqlDriver.php', + 'Nette\\Database\\Drivers\\SqliteDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/SqliteDriver.php', + 'Nette\\Database\\Drivers\\SqlsrvDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/SqlsrvDriver.php', + 'Nette\\Database\\Explorer' => __DIR__ . '/..' . '/nette/database/src/Database/Explorer.php', + 'Nette\\Database\\ForeignKeyConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Helpers' => __DIR__ . '/..' . '/nette/database/src/Database/Helpers.php', + 'Nette\\Database\\IConventions' => __DIR__ . '/..' . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\IRow' => __DIR__ . '/..' . '/nette/database/src/Database/IRow.php', + 'Nette\\Database\\IRowContainer' => __DIR__ . '/..' . '/nette/database/src/Database/IRowContainer.php', + 'Nette\\Database\\IStructure' => __DIR__ . '/..' . '/nette/database/src/Database/IStructure.php', + 'Nette\\Database\\ISupplementalDriver' => __DIR__ . '/..' . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\LockTimeoutException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\NotNullConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Reflection' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection.php', + 'Nette\\Database\\Reflection\\Column' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/Column.php', + 'Nette\\Database\\Reflection\\ForeignKey' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/ForeignKey.php', + 'Nette\\Database\\Reflection\\Index' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/Index.php', + 'Nette\\Database\\Reflection\\Table' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/Table.php', + 'Nette\\Database\\ResultSet' => __DIR__ . '/..' . '/nette/database/src/Database/ResultSet.php', + 'Nette\\Database\\Row' => __DIR__ . '/..' . '/nette/database/src/Database/Row.php', + 'Nette\\Database\\SqlLiteral' => __DIR__ . '/..' . '/nette/database/src/Database/SqlLiteral.php', + 'Nette\\Database\\SqlPreprocessor' => __DIR__ . '/..' . '/nette/database/src/Database/SqlPreprocessor.php', + 'Nette\\Database\\Structure' => __DIR__ . '/..' . '/nette/database/src/Database/Structure.php', + 'Nette\\Database\\Table\\ActiveRow' => __DIR__ . '/..' . '/nette/database/src/Database/Table/ActiveRow.php', + 'Nette\\Database\\Table\\GroupedSelection' => __DIR__ . '/..' . '/nette/database/src/Database/Table/GroupedSelection.php', + 'Nette\\Database\\Table\\IRow' => __DIR__ . '/..' . '/nette/database/src/Database/Table/IRow.php', + 'Nette\\Database\\Table\\IRowContainer' => __DIR__ . '/..' . '/nette/database/src/Database/Table/IRowContainer.php', + 'Nette\\Database\\Table\\Selection' => __DIR__ . '/..' . '/nette/database/src/Database/Table/Selection.php', + 'Nette\\Database\\Table\\SqlBuilder' => __DIR__ . '/..' . '/nette/database/src/Database/Table/SqlBuilder.php', + 'Nette\\Database\\UniqueConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\FileNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Forms\\Blueprint' => __DIR__ . '/..' . '/nette/forms/src/Forms/Blueprint.php', + 'Nette\\Forms\\Container' => __DIR__ . '/..' . '/nette/forms/src/Forms/Container.php', + 'Nette\\Forms\\Control' => __DIR__ . '/..' . '/nette/forms/src/Forms/Control.php', + 'Nette\\Forms\\ControlGroup' => __DIR__ . '/..' . '/nette/forms/src/Forms/ControlGroup.php', + 'Nette\\Forms\\Controls\\BaseControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/BaseControl.php', + 'Nette\\Forms\\Controls\\Button' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/Button.php', + 'Nette\\Forms\\Controls\\Checkbox' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/Checkbox.php', + 'Nette\\Forms\\Controls\\CheckboxList' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/CheckboxList.php', + 'Nette\\Forms\\Controls\\ChoiceControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/ChoiceControl.php', + 'Nette\\Forms\\Controls\\ColorPicker' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/ColorPicker.php', + 'Nette\\Forms\\Controls\\CsrfProtection' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/CsrfProtection.php', + 'Nette\\Forms\\Controls\\DateTimeControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/DateTimeControl.php', + 'Nette\\Forms\\Controls\\HiddenField' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/HiddenField.php', + 'Nette\\Forms\\Controls\\ImageButton' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/ImageButton.php', + 'Nette\\Forms\\Controls\\MultiChoiceControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/MultiChoiceControl.php', + 'Nette\\Forms\\Controls\\MultiSelectBox' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/MultiSelectBox.php', + 'Nette\\Forms\\Controls\\RadioList' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/RadioList.php', + 'Nette\\Forms\\Controls\\SelectBox' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/SelectBox.php', + 'Nette\\Forms\\Controls\\SubmitButton' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/SubmitButton.php', + 'Nette\\Forms\\Controls\\TextArea' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/TextArea.php', + 'Nette\\Forms\\Controls\\TextBase' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/TextBase.php', + 'Nette\\Forms\\Controls\\TextInput' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/TextInput.php', + 'Nette\\Forms\\Controls\\UploadControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/UploadControl.php', + 'Nette\\Forms\\Form' => __DIR__ . '/..' . '/nette/forms/src/Forms/Form.php', + 'Nette\\Forms\\FormRenderer' => __DIR__ . '/..' . '/nette/forms/src/Forms/FormRenderer.php', + 'Nette\\Forms\\Helpers' => __DIR__ . '/..' . '/nette/forms/src/Forms/Helpers.php', + 'Nette\\Forms\\IControl' => __DIR__ . '/..' . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\IFormRenderer' => __DIR__ . '/..' . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\ISubmitterControl' => __DIR__ . '/..' . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\Rendering\\DefaultFormRenderer' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rendering/DefaultFormRenderer.php', + 'Nette\\Forms\\Rule' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rule.php', + 'Nette\\Forms\\Rules' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rules.php', + 'Nette\\Forms\\SubmitterControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/SubmitterControl.php', + 'Nette\\Forms\\Validator' => __DIR__ . '/..' . '/nette/forms/src/Forms/Validator.php', + 'Nette\\HtmlStringable' => __DIR__ . '/..' . '/nette/utils/src/HtmlStringable.php', + 'Nette\\Http\\Context' => __DIR__ . '/..' . '/nette/http/src/Http/Context.php', + 'Nette\\Http\\FetchDest' => __DIR__ . '/..' . '/nette/http/src/Http/enums.php', + 'Nette\\Http\\FetchSite' => __DIR__ . '/..' . '/nette/http/src/Http/enums.php', + 'Nette\\Http\\FileUpload' => __DIR__ . '/..' . '/nette/http/src/Http/FileUpload.php', + 'Nette\\Http\\Helpers' => __DIR__ . '/..' . '/nette/http/src/Http/Helpers.php', + 'Nette\\Http\\IPAddress' => __DIR__ . '/..' . '/nette/http/src/Http/IPAddress.php', + 'Nette\\Http\\IRequest' => __DIR__ . '/..' . '/nette/http/src/Http/IRequest.php', + 'Nette\\Http\\IResponse' => __DIR__ . '/..' . '/nette/http/src/Http/IResponse.php', + 'Nette\\Http\\Request' => __DIR__ . '/..' . '/nette/http/src/Http/Request.php', + 'Nette\\Http\\RequestFactory' => __DIR__ . '/..' . '/nette/http/src/Http/RequestFactory.php', + 'Nette\\Http\\Response' => __DIR__ . '/..' . '/nette/http/src/Http/Response.php', + 'Nette\\Http\\SameSite' => __DIR__ . '/..' . '/nette/http/src/Http/enums.php', + 'Nette\\Http\\Session' => __DIR__ . '/..' . '/nette/http/src/Http/Session.php', + 'Nette\\Http\\SessionSection' => __DIR__ . '/..' . '/nette/http/src/Http/SessionSection.php', + 'Nette\\Http\\Url' => __DIR__ . '/..' . '/nette/http/src/Http/Url.php', + 'Nette\\Http\\UrlImmutable' => __DIR__ . '/..' . '/nette/http/src/Http/UrlImmutable.php', + 'Nette\\Http\\UrlScript' => __DIR__ . '/..' . '/nette/http/src/Http/UrlScript.php', + 'Nette\\Http\\UrlValidator' => __DIR__ . '/..' . '/nette/http/src/Http/UrlValidator.php', + 'Nette\\IOException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidArgumentException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidStateException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => __DIR__ . '/..' . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => __DIR__ . '/..' . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\Loaders\\RobotLoader' => __DIR__ . '/..' . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php', + 'Nette\\Localization\\Translator' => __DIR__ . '/..' . '/nette/utils/src/Translator.php', + 'Nette\\Mail\\CssInliner' => __DIR__ . '/..' . '/nette/mail/src/Mail/CssInliner.php', + 'Nette\\Mail\\DkimSigner' => __DIR__ . '/..' . '/nette/mail/src/Mail/DkimSigner.php', + 'Nette\\Mail\\FallbackMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/FallbackMailer.php', + 'Nette\\Mail\\FallbackMailerException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\FileMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/FileMailer.php', + 'Nette\\Mail\\HtmlComposer' => __DIR__ . '/..' . '/nette/mail/src/Mail/HtmlComposer.php', + 'Nette\\Mail\\IMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Interceptor' => __DIR__ . '/..' . '/nette/mail/src/Mail/Interceptor.php', + 'Nette\\Mail\\Mailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Message' => __DIR__ . '/..' . '/nette/mail/src/Mail/Message.php', + 'Nette\\Mail\\MimePart' => __DIR__ . '/..' . '/nette/mail/src/Mail/MimePart.php', + 'Nette\\Mail\\SendException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SendmailMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/SendmailMailer.php', + 'Nette\\Mail\\SignException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\Signer' => __DIR__ . '/..' . '/nette/mail/src/Mail/Signer.php', + 'Nette\\Mail\\SmtpException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SmtpMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/SmtpMailer.php', + 'Nette\\MemberAccessException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Neon\\Decoder' => __DIR__ . '/..' . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => __DIR__ . '/..' . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => __DIR__ . '/..' . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => __DIR__ . '/..' . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Lexer' => __DIR__ . '/..' . '/nette/neon/src/Neon/Lexer.php', + 'Nette\\Neon\\Neon' => __DIR__ . '/..' . '/nette/neon/src/Neon/Neon.php', + 'Nette\\Neon\\Node' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node.php', + 'Nette\\Neon\\Node\\ArrayItemNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/ArrayItemNode.php', + 'Nette\\Neon\\Node\\ArrayNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/ArrayNode.php', + 'Nette\\Neon\\Node\\BlockArrayNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/BlockArrayNode.php', + 'Nette\\Neon\\Node\\EntityChainNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/EntityChainNode.php', + 'Nette\\Neon\\Node\\EntityNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/EntityNode.php', + 'Nette\\Neon\\Node\\InlineArrayNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/InlineArrayNode.php', + 'Nette\\Neon\\Node\\LiteralNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/LiteralNode.php', + 'Nette\\Neon\\Node\\StringNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/StringNode.php', + 'Nette\\Neon\\Parser' => __DIR__ . '/..' . '/nette/neon/src/Neon/Parser.php', + 'Nette\\Neon\\Token' => __DIR__ . '/..' . '/nette/neon/src/Neon/Token.php', + 'Nette\\Neon\\TokenStream' => __DIR__ . '/..' . '/nette/neon/src/Neon/TokenStream.php', + 'Nette\\Neon\\Traverser' => __DIR__ . '/..' . '/nette/neon/src/Neon/Traverser.php', + 'Nette\\NotImplementedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\NotSupportedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\OutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\PhpGenerator\\Attribute' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Attribute.php', + 'Nette\\PhpGenerator\\ClassLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassLike.php', + 'Nette\\PhpGenerator\\ClassManipulator' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassManipulator.php', + 'Nette\\PhpGenerator\\ClassType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Dumper' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Dumper.php', + 'Nette\\PhpGenerator\\EnumCase' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/EnumCase.php', + 'Nette\\PhpGenerator\\EnumType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/EnumType.php', + 'Nette\\PhpGenerator\\Extractor' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Extractor.php', + 'Nette\\PhpGenerator\\Factory' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\InterfaceType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/InterfaceType.php', + 'Nette\\PhpGenerator\\Literal' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Literal.php', + 'Nette\\PhpGenerator\\Method' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Printer' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Printer.php', + 'Nette\\PhpGenerator\\PromotedParameter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PromotedParameter.php', + 'Nette\\PhpGenerator\\Property' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\PropertyAccessMode' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PropertyAccessMode.php', + 'Nette\\PhpGenerator\\PropertyHook' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PropertyHook.php', + 'Nette\\PhpGenerator\\PropertyHookType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PropertyHookType.php', + 'Nette\\PhpGenerator\\PsrPrinter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php', + 'Nette\\PhpGenerator\\TraitType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/TraitType.php', + 'Nette\\PhpGenerator\\TraitUse' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/TraitUse.php', + 'Nette\\PhpGenerator\\Traits\\AttributeAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\ConstantsAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/ConstantsAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\MethodsAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/MethodsAware.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertiesAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/PropertiesAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertyLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/PropertyLike.php', + 'Nette\\PhpGenerator\\Traits\\TraitsAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/TraitsAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\PhpGenerator\\Type' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Type.php', + 'Nette\\PhpGenerator\\Visibility' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Visibility.php', + 'Nette\\Routing\\Route' => __DIR__ . '/..' . '/nette/routing/src/Routing/Route.php', + 'Nette\\Routing\\RouteList' => __DIR__ . '/..' . '/nette/routing/src/Routing/RouteList.php', + 'Nette\\Routing\\Router' => __DIR__ . '/..' . '/nette/routing/src/Routing/Router.php', + 'Nette\\Routing\\SimpleRouter' => __DIR__ . '/..' . '/nette/routing/src/Routing/SimpleRouter.php', + 'Nette\\Schema\\Context' => __DIR__ . '/..' . '/nette/schema/src/Schema/Context.php', + 'Nette\\Schema\\DynamicParameter' => __DIR__ . '/..' . '/nette/schema/src/Schema/DynamicParameter.php', + 'Nette\\Schema\\Elements\\AnyOf' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/AnyOf.php', + 'Nette\\Schema\\Elements\\Base' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Base.php', + 'Nette\\Schema\\Elements\\Structure' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Structure.php', + 'Nette\\Schema\\Elements\\Type' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Type.php', + 'Nette\\Schema\\Expect' => __DIR__ . '/..' . '/nette/schema/src/Schema/Expect.php', + 'Nette\\Schema\\Helpers' => __DIR__ . '/..' . '/nette/schema/src/Schema/Helpers.php', + 'Nette\\Schema\\Message' => __DIR__ . '/..' . '/nette/schema/src/Schema/Message.php', + 'Nette\\Schema\\Processor' => __DIR__ . '/..' . '/nette/schema/src/Schema/Processor.php', + 'Nette\\Schema\\Schema' => __DIR__ . '/..' . '/nette/schema/src/Schema/Schema.php', + 'Nette\\Schema\\ValidationException' => __DIR__ . '/..' . '/nette/schema/src/Schema/ValidationException.php', + 'Nette\\Security\\AuthenticationException' => __DIR__ . '/..' . '/nette/security/src/Security/AuthenticationException.php', + 'Nette\\Security\\Authenticator' => __DIR__ . '/..' . '/nette/security/src/Security/Authenticator.php', + 'Nette\\Security\\Authorizator' => __DIR__ . '/..' . '/nette/security/src/Security/Authorizator.php', + 'Nette\\Security\\IAuthenticator' => __DIR__ . '/..' . '/nette/security/src/Security/IAuthenticator.php', + 'Nette\\Security\\IAuthorizator' => __DIR__ . '/..' . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IIdentity' => __DIR__ . '/..' . '/nette/security/src/Security/IIdentity.php', + 'Nette\\Security\\IResource' => __DIR__ . '/..' . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IRole' => __DIR__ . '/..' . '/nette/security/src/compatibility.php', + 'Nette\\Security\\Identity' => __DIR__ . '/..' . '/nette/security/src/Security/Identity.php', + 'Nette\\Security\\IdentityHandler' => __DIR__ . '/..' . '/nette/security/src/Security/IdentityHandler.php', + 'Nette\\Security\\Passwords' => __DIR__ . '/..' . '/nette/security/src/Security/Passwords.php', + 'Nette\\Security\\Permission' => __DIR__ . '/..' . '/nette/security/src/Security/Permission.php', + 'Nette\\Security\\Resource' => __DIR__ . '/..' . '/nette/security/src/Security/Resource.php', + 'Nette\\Security\\Role' => __DIR__ . '/..' . '/nette/security/src/Security/Role.php', + 'Nette\\Security\\SimpleAuthenticator' => __DIR__ . '/..' . '/nette/security/src/Security/SimpleAuthenticator.php', + 'Nette\\Security\\SimpleIdentity' => __DIR__ . '/..' . '/nette/security/src/Security/SimpleIdentity.php', + 'Nette\\Security\\User' => __DIR__ . '/..' . '/nette/security/src/Security/User.php', + 'Nette\\Security\\UserStorage' => __DIR__ . '/..' . '/nette/security/src/Security/UserStorage.php', + 'Nette\\ShouldNotHappenException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\SmartObject' => __DIR__ . '/..' . '/nette/utils/src/SmartObject.php', + 'Nette\\StaticClass' => __DIR__ . '/..' . '/nette/utils/src/StaticClass.php', + 'Nette\\UnexpectedValueException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Utils\\ArrayHash' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => __DIR__ . '/..' . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => __DIR__ . '/..' . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => __DIR__ . '/..' . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\DateTimeImmutable' => __DIR__ . '/..' . '/nette/utils/src/Utils/DateTimeImmutable.php', + 'Nette\\Utils\\FileInfo' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileInfo.php', + 'Nette\\Utils\\FileSystem' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => __DIR__ . '/..' . '/nette/utils/src/Utils/Finder.php', + 'Nette\\Utils\\Floats' => __DIR__ . '/..' . '/nette/utils/src/Utils/Floats.php', + 'Nette\\Utils\\Helpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/Helpers.php', + 'Nette\\Utils\\Html' => __DIR__ . '/..' . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php', + 'Nette\\Utils\\Image' => __DIR__ . '/..' . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageColor' => __DIR__ . '/..' . '/nette/utils/src/Utils/ImageColor.php', + 'Nette\\Utils\\ImageException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ImageType' => __DIR__ . '/..' . '/nette/utils/src/Utils/ImageType.php', + 'Nette\\Utils\\Iterables' => __DIR__ . '/..' . '/nette/utils/src/Utils/Iterables.php', + 'Nette\\Utils\\Json' => __DIR__ . '/..' . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\Paginator' => __DIR__ . '/..' . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Process' => __DIR__ . '/..' . '/nette/utils/src/Utils/Process.php', + 'Nette\\Utils\\ProcessFailedException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ProcessTimeoutException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Random' => __DIR__ . '/..' . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => __DIR__ . '/..' . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\ReflectionMethod' => __DIR__ . '/..' . '/nette/utils/src/Utils/ReflectionMethod.php', + 'Nette\\Utils\\RegexpException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => __DIR__ . '/..' . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\Type' => __DIR__ . '/..' . '/nette/utils/src/Utils/Type.php', + 'Nette\\Utils\\UnknownImageFileException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => __DIR__ . '/..' . '/nette/utils/src/Utils/Validators.php', + 'Tester\\Ansi' => __DIR__ . '/..' . '/nette/tester/src/Framework/Ansi.php', + 'Tester\\Assert' => __DIR__ . '/..' . '/nette/tester/src/Framework/Assert.php', + 'Tester\\AssertException' => __DIR__ . '/..' . '/nette/tester/src/Framework/AssertException.php', + 'Tester\\CodeCoverage\\Collector' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Collector.php', + 'Tester\\CodeCoverage\\Generators\\AbstractGenerator' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Generators/AbstractGenerator.php', + 'Tester\\CodeCoverage\\Generators\\CloverXMLGenerator' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Generators/CloverXMLGenerator.php', + 'Tester\\CodeCoverage\\Generators\\HtmlGenerator' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Generators/HtmlGenerator.php', + 'Tester\\CodeCoverage\\PhpParser' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/PhpParser.php', + 'Tester\\DataProvider' => __DIR__ . '/..' . '/nette/tester/src/Framework/DataProvider.php', + 'Tester\\DomQuery' => __DIR__ . '/..' . '/nette/tester/src/Framework/DomQuery.php', + 'Tester\\Dumper' => __DIR__ . '/..' . '/nette/tester/src/Framework/Dumper.php', + 'Tester\\Environment' => __DIR__ . '/..' . '/nette/tester/src/Framework/Environment.php', + 'Tester\\Expect' => __DIR__ . '/..' . '/nette/tester/src/Framework/Expect.php', + 'Tester\\FileMock' => __DIR__ . '/..' . '/nette/tester/src/Framework/FileMock.php', + 'Tester\\FileMutator' => __DIR__ . '/..' . '/nette/tester/src/Framework/FileMutator.php', + 'Tester\\Helpers' => __DIR__ . '/..' . '/nette/tester/src/Framework/Helpers.php', + 'Tester\\HttpAssert' => __DIR__ . '/..' . '/nette/tester/src/Framework/HttpAssert.php', + 'Tester\\Runner\\CliTester' => __DIR__ . '/..' . '/nette/tester/src/Runner/CliTester.php', + 'Tester\\Runner\\CommandLine' => __DIR__ . '/..' . '/nette/tester/src/Runner/CommandLine.php', + 'Tester\\Runner\\InterruptException' => __DIR__ . '/..' . '/nette/tester/src/Runner/exceptions.php', + 'Tester\\Runner\\Job' => __DIR__ . '/..' . '/nette/tester/src/Runner/Job.php', + 'Tester\\Runner\\OutputHandler' => __DIR__ . '/..' . '/nette/tester/src/Runner/OutputHandler.php', + 'Tester\\Runner\\Output\\ConsolePrinter' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/ConsolePrinter.php', + 'Tester\\Runner\\Output\\JUnitPrinter' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/JUnitPrinter.php', + 'Tester\\Runner\\Output\\Logger' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/Logger.php', + 'Tester\\Runner\\Output\\TapPrinter' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/TapPrinter.php', + 'Tester\\Runner\\PhpInterpreter' => __DIR__ . '/..' . '/nette/tester/src/Runner/PhpInterpreter.php', + 'Tester\\Runner\\Runner' => __DIR__ . '/..' . '/nette/tester/src/Runner/Runner.php', + 'Tester\\Runner\\Test' => __DIR__ . '/..' . '/nette/tester/src/Runner/Test.php', + 'Tester\\Runner\\TestHandler' => __DIR__ . '/..' . '/nette/tester/src/Runner/TestHandler.php', + 'Tester\\TestCase' => __DIR__ . '/..' . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseException' => __DIR__ . '/..' . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseSkippedException' => __DIR__ . '/..' . '/nette/tester/src/Framework/TestCase.php', + 'Tracy\\Bar' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Bar/Bar.php', + 'Tracy\\BlueScreen' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/BlueScreen/BlueScreen.php', + 'Tracy\\Bridges\\Nette\\Bridge' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Nette/Bridge.php', + 'Tracy\\Bridges\\Nette\\MailSender' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Nette/MailSender.php', + 'Tracy\\Bridges\\Nette\\TracyExtension' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Nette/TracyExtension.php', + 'Tracy\\Bridges\\Psr\\PsrToTracyLoggerAdapter' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Psr/PsrToTracyLoggerAdapter.php', + 'Tracy\\Bridges\\Psr\\TracyToPsrLoggerAdapter' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Psr/TracyToPsrLoggerAdapter.php', + 'Tracy\\CodeHighlighter' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/BlueScreen/CodeHighlighter.php', + 'Tracy\\Debugger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/Debugger.php', + 'Tracy\\DefaultBarPanel' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Bar/DefaultBarPanel.php', + 'Tracy\\DeferredContent' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/DeferredContent.php', + 'Tracy\\DevelopmentStrategy' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/DevelopmentStrategy.php', + 'Tracy\\Dumper' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Dumper.php', + 'Tracy\\Dumper\\Describer' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Describer.php', + 'Tracy\\Dumper\\Exposer' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Exposer.php', + 'Tracy\\Dumper\\Renderer' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Renderer.php', + 'Tracy\\Dumper\\Value' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Value.php', + 'Tracy\\FileSession' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Session/FileSession.php', + 'Tracy\\Helpers' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Helpers.php', + 'Tracy\\IBarPanel' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Bar/IBarPanel.php', + 'Tracy\\ILogger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Logger/ILogger.php', + 'Tracy\\Logger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Logger/Logger.php', + 'Tracy\\NativeSession' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Session/NativeSession.php', + 'Tracy\\OutputDebugger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php', + 'Tracy\\ProductionStrategy' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/ProductionStrategy.php', + 'Tracy\\SessionStorage' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Session/SessionStorage.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit38f417078fc5f615987c051d0a0c9213::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit38f417078fc5f615987c051d0a0c9213::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit38f417078fc5f615987c051d0a0c9213::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 00000000..b90313d7 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,1912 @@ +{ + "packages": [ + { + "name": "latte/latte", + "version": "v3.1.6", + "version_normalized": "3.1.6.0", + "source": { + "type": "git", + "url": "https://github.com/nette/latte.git", + "reference": "adccfac3d5d7bff441a0e5ae85978f448787f5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/latte/zipball/adccfac3d5d7bff441a0e5ae85978f448787f5d4", + "reference": "adccfac3d5d7bff441a0e5ae85978f448787f5d4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "require-dev": { + "nette/php-generator": "^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "nette/utils": "^4.0", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.10" + }, + "suggest": { + "ext-fileinfo": "to use filter |datastream", + "ext-iconv": "to use filters |reverse, |substring", + "ext-intl": "to use Latte\\Engine::setLocale()", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "nette/php-generator": "to use tag {templatePrint}", + "nette/utils": "to use filter |webalize" + }, + "time": "2026-07-27T14:32:10+00:00", + "bin": [ + "bin/latte-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Latte\\": "src/Latte" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "homepage": "https://latte.nette.org", + "keywords": [ + "context-sensitive", + "engine", + "escaping", + "html", + "nette", + "security", + "template", + "twig" + ], + "support": { + "issues": "https://github.com/nette/latte/issues", + "source": "https://github.com/nette/latte/tree/v3.1.6" + }, + "install-path": "../latte/latte" + }, + { + "name": "nette/application", + "version": "v3.3.0", + "version_normalized": "3.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/application.git", + "reference": "104484c317fdb1b29baf77617ca040b97685e9bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/application/zipball/104484c317fdb1b29baf77617ca040b97685e9bb", + "reference": "104484c317fdb1b29baf77617ca040b97685e9bb", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.2 || ^4.0", + "nette/http": "^3.4", + "nette/routing": "^3.1.1", + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "latte/latte": "<3.1.4 || >=3.2", + "nette/caching": "<3.2", + "nette/di": "<3.2", + "nette/forms": "<3.2", + "nette/schema": "<1.3", + "tracy/tracy": "<2.12" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "latte/latte": "^3.1.4", + "mockery/mockery": "^1.6@stable", + "nette/caching": "^3.2", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.2@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "latte/latte": "Allows using Latte in templates", + "nette/forms": "Allows to use Nette\\Application\\UI\\Form" + }, + "time": "2026-06-29T19:05:48+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🏆 Nette Application: a full-stack component-based MVC kernel for PHP that helps you write powerful and modern web applications. Write less, have cleaner code and your work will bring you joy.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "component-based", + "control", + "framework", + "mvc", + "mvp", + "nette", + "presenter", + "routing", + "seo" + ], + "support": { + "issues": "https://github.com/nette/application/issues", + "source": "https://github.com/nette/application/tree/v3.3.0" + }, + "install-path": "../nette/application" + }, + { + "name": "nette/assets", + "version": "v1.0.7", + "version_normalized": "1.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/nette/assets.git", + "reference": "4a3d10902b6caca2eee3469e7863bea1b3bd1e2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/assets/zipball/4a3d10902b6caca2eee3469e7863bea1b3bd1e2b", + "reference": "4a3d10902b6caca2eee3469e7863bea1b3bd1e2b", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/bootstrap": "<3.2.5", + "nette/http": "<3.3.2" + }, + "require-dev": { + "latte/latte": "^3.0.22", + "mockery/mockery": "^1.6@stable", + "nette/application": "^3.2", + "nette/di": "^3.2", + "nette/http": "^3.3.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Assets in templates" + }, + "time": "2026-03-28T17:15:28+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🎨 Nette Assets: elegant asset management for PHP with versioning, caching and mappers for various storage backends.", + "homepage": "https://nette.org", + "keywords": [ + "asset management", + "assets", + "nette", + "resources", + "static files", + "versioning" + ], + "support": { + "issues": "https://github.com/nette/assets/issues", + "source": "https://github.com/nette/assets/tree/v1.0.7" + }, + "install-path": "../nette/assets" + }, + { + "name": "nette/bootstrap", + "version": "v3.3.0", + "version_normalized": "3.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "3c8cbf8383b6df153bfb848a3c311ce42261a336" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/3c8cbf8383b6df153bfb848a3c311ce42261a336", + "reference": "3c8cbf8383b6df153bfb848a3c311ce42261a336", + "shasum": "" + }, + "require": { + "nette/di": "^3.2", + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "nette/caching": "<3.3", + "nette/mail": "<4.1.2", + "tracy/tracy": "<2.6" + }, + "require-dev": { + "latte/latte": "^3.0", + "nette/application": "^3.2", + "nette/assets": "^1.0", + "nette/caching": "^3.3", + "nette/database": "^3.2", + "nette/forms": "^3.2", + "nette/http": "^3.2", + "nette/mail": "^4.1", + "nette/neon": "^3.4", + "nette/phpstan-rules": "^1.0", + "nette/robot-loader": "^4.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.2", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.2@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "time": "2026-06-21T22:20:56+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.3.0" + }, + "install-path": "../nette/bootstrap" + }, + { + "name": "nette/caching", + "version": "v3.4.2", + "version_normalized": "3.4.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/caching.git", + "reference": "31f4bc6b366e6896998bd4538b26fa88a627bf2b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/caching/zipball/31f4bc6b366e6896998bd4538b26fa88a627bf2b", + "reference": "31f4bc6b366e6896998bd4538b26fa88a627bf2b", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": "<3.0.12" + }, + "require-dev": { + "latte/latte": "^3.0.12", + "nette/di": "^3.1 || ^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.40@stable", + "psr/simple-cache": "^2.0 || ^3.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-pdo_sqlite": "to use SQLiteStorage or SQLiteJournal" + }, + "time": "2026-05-12T01:08:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⏱ Nette Caching: library with easy-to-use API and many cache backends.", + "homepage": "https://nette.org", + "keywords": [ + "cache", + "journal", + "memcached", + "nette", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/caching/issues", + "source": "https://github.com/nette/caching/tree/v3.4.2" + }, + "install-path": "../nette/caching" + }, + { + "name": "nette/component-model", + "version": "v4.0.1", + "version_normalized": "4.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/component-model.git", + "reference": "b4e82e1a3a7ca6f66ce766704aa2e148de277276" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/component-model/zipball/b4e82e1a3a7ca6f66ce766704aa2e148de277276", + "reference": "b4e82e1a3a7ca6f66ce766704aa2e148de277276", + "shasum": "" + }, + "require": { + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.12" + }, + "time": "2026-06-21T23:31:36+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⚛ Nette Component Model", + "homepage": "https://nette.org", + "keywords": [ + "components", + "nette" + ], + "support": { + "issues": "https://github.com/nette/component-model/issues", + "source": "https://github.com/nette/component-model/tree/v4.0.1" + }, + "install-path": "../nette/component-model" + }, + { + "name": "nette/database", + "version": "v3.2.9", + "version_normalized": "3.2.9.0", + "source": { + "type": "git", + "url": "https://github.com/nette/database.git", + "reference": "6fe51398fcfc7719f64b7063f99886b438527755" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/database/zipball/6fe51398fcfc7719f64b7063f99886b438527755", + "reference": "6fe51398fcfc7719f64b7063f99886b438527755", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "nette/caching": "^3.2", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "time": "2026-04-22T05:48:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💾 Nette Database: layer with a familiar PDO-like API but much more powerful. Building queries, advanced joins, drivers for MySQL, PostgreSQL, SQLite, MS SQL Server and Oracle.", + "homepage": "https://nette.org", + "keywords": [ + "database", + "mssql", + "mysql", + "nette", + "notorm", + "oracle", + "pdo", + "postgresql", + "queries", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/database/issues", + "source": "https://github.com/nette/database/tree/v3.2.9" + }, + "install-path": "../nette/database" + }, + { + "name": "nette/di", + "version": "v3.2.6", + "version_normalized": "3.2.6.0", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "481ca2553e792daffa7fcf0ed43f705d80603fa4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/481ca2553e792daffa7fcf0ed43f705d80603fa4", + "reference": "481ca2553e792daffa7fcf0ed43f705d80603fa4", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-tokenizer": "*", + "nette/neon": "^3.4", + "nette/php-generator": "^4.1.6", + "nette/robot-loader": "^4.0", + "nette/schema": "^1.2.5", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "time": "2026-05-06T02:17:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.2.6" + }, + "install-path": "../nette/di" + }, + { + "name": "nette/forms", + "version": "v3.3.0", + "version_normalized": "3.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/forms.git", + "reference": "90aac9e6a55a71a76aaead65bca1129acb41ec84" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/forms/zipball/90aac9e6a55a71a76aaead65bca1129acb41ec84", + "reference": "90aac9e6a55a71a76aaead65bca1129acb41ec84", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.2 || ^4.0", + "nette/http": "^3.4", + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "latte/latte": "<3.1.4 || >=3.2" + }, + "require-dev": { + "latte/latte": "^3.1.4", + "nette/application": "^3.2", + "nette/di": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "ext-intl": "to use date/time controls" + }, + "time": "2026-06-28T12:32:44+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "bootstrap", + "csrf", + "javascript", + "nette", + "validation" + ], + "support": { + "issues": "https://github.com/nette/forms/issues", + "source": "https://github.com/nette/forms/tree/v3.3.0" + }, + "install-path": "../nette/forms" + }, + { + "name": "nette/http", + "version": "v3.4.0", + "version_normalized": "3.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/http.git", + "reference": "de5988d8802e76d9bda85fe5a871d29c794684f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/http/zipball/de5988d8802e76d9bda85fe5a871d29c794684f4", + "reference": "de5988d8802e76d9bda85fe5a871d29c794684f4", + "shasum": "" + }, + "require": { + "nette/utils": "^4.1", + "php": "8.3 - 8.5" + }, + "conflict": { + "nette/di": "<3.0.3", + "nette/schema": "<1.2" + }, + "require-dev": { + "nette/di": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/security": "^3.2", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.2@stable", + "tracy/tracy": "^2.12" + }, + "suggest": { + "ext-fileinfo": "to detect MIME type of uploaded files by Nette\\Http\\FileUpload", + "ext-gd": "to use image function in Nette\\Http\\FileUpload", + "ext-intl": "to support punycode by Nette\\Http\\Url", + "ext-session": "to use Nette\\Http\\Session" + }, + "time": "2026-06-13T01:04:19+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🌐 Nette Http: abstraction for HTTP request, response and session. Provides careful data sanitization and utility for URL and cookies manipulation.", + "homepage": "https://nette.org", + "keywords": [ + "cookies", + "http", + "nette", + "proxy", + "request", + "response", + "security", + "session", + "url" + ], + "support": { + "issues": "https://github.com/nette/http/issues", + "source": "https://github.com/nette/http/tree/v3.4.0" + }, + "install-path": "../nette/http" + }, + { + "name": "nette/mail", + "version": "v4.2.0", + "version_normalized": "4.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/mail.git", + "reference": "6dd1042fb3cb95ebd3c6ca79507154dc74215bd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/mail/zipball/6dd1042fb3cb95ebd3c6ca79507154dc74215bd2", + "reference": "6dd1042fb3cb95ebd3c6ca79507154dc74215bd2", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "nette/utils": "^4.1", + "php": "8.2 - 8.5" + }, + "require-dev": { + "nette/di": "^3.1 || ^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.40@stable", + "tracy/tracy": "^2.11" + }, + "suggest": { + "ext-dom": "to use Nette\\Mail\\CssInliner", + "ext-fileinfo": "to detect type of attached files", + "ext-intl": "to send to internationalized (IDN) domains", + "ext-openssl": "to use Nette\\Mail\\DkimSigner with an RSA key", + "ext-sodium": "to use Nette\\Mail\\DkimSigner with an Ed25519 key" + }, + "time": "2026-07-27T15:28:54+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📧 Nette Mail: A handy library for creating and sending emails in PHP.", + "homepage": "https://nette.org", + "keywords": [ + "mail", + "mailer", + "mime", + "nette", + "smtp" + ], + "support": { + "issues": "https://github.com/nette/mail/issues", + "source": "https://github.com/nette/mail/tree/v4.2.0" + }, + "install-path": "../nette/mail" + }, + { + "name": "nette/neon", + "version": "v3.4.8", + "version_normalized": "3.4.8.0", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "9009f99ce1396b366a88ca16c90177148352b7d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/9009f99ce1396b366a88ca16c90177148352b7d3", + "reference": "9009f99ce1396b366a88ca16c90177148352b7d3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "8.0 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.7" + }, + "time": "2026-05-11T21:34:00+00:00", + "bin": [ + "bin/neon-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "https://neon.nette.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.4.8" + }, + "install-path": "../nette/neon" + }, + { + "name": "nette/php-generator", + "version": "v4.2.2", + "version_normalized": "4.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "0d7060926f5c3e8c488b9b9ced42d857f12a34b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/0d7060926f5c3e8c488b9b9ced42d857f12a34b5", + "reference": "0d7060926f5c3e8c488b9b9ced42d857f12a34b5", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "nikic/php-parser": "^5.0", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.40@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" + }, + "time": "2026-02-26T00:58:33+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v4.2.2" + }, + "install-path": "../nette/php-generator" + }, + { + "name": "nette/phpstan-rules", + "version": "v1.0.5", + "version_normalized": "1.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/nette/phpstan-rules.git", + "reference": "6811d818c5272b43eceb9e8dfee28071cfcd1ec5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/phpstan-rules/zipball/6811d818c5272b43eceb9e8dfee28071cfcd1ec5", + "reference": "6811d818c5272b43eceb9e8dfee28071cfcd1ec5", + "shasum": "" + }, + "require": { + "php": "8.1 - 8.5", + "phpstan/phpstan": "^2.2.6" + }, + "require-dev": { + "nette/application": "^3.2", + "nette/assets": "^1.0", + "nette/component-model": "^3.1", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/schema": "^1.3", + "nette/tester": "^2.6" + }, + "time": "2026-07-27T15:17:34+00:00", + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\PHPStan\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + } + ], + "description": "🐘 PHPStan rules and type extensions for Nette libraries", + "homepage": "https://nette.org", + "keywords": [ + "PHPStan", + "nette", + "static analysis" + ], + "support": { + "issues": "https://github.com/nette/phpstan-rules/issues", + "source": "https://github.com/nette/phpstan-rules/tree/v1.0.5" + }, + "install-path": "../nette/phpstan-rules" + }, + { + "name": "nette/robot-loader", + "version": "v4.1.2", + "version_normalized": "4.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e", + "reference": "ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.9" + }, + "time": "2026-02-23T04:18:24+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v4.1.2" + }, + "install-path": "../nette/robot-loader" + }, + { + "name": "nette/routing", + "version": "v3.1.3", + "version_normalized": "3.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/routing.git", + "reference": "92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/routing/zipball/92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6", + "reference": "92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6", + "shasum": "" + }, + "require": { + "nette/http": "^3.2 || ~4.0.0", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.9" + }, + "time": "2026-02-23T04:05:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Routing: two-ways URL conversion", + "homepage": "https://nette.org", + "keywords": [ + "nette" + ], + "support": { + "issues": "https://github.com/nette/routing/issues", + "source": "https://github.com/nette/routing/tree/v3.1.3" + }, + "install-path": "../nette/routing" + }, + { + "name": "nette/schema", + "version": "v1.3.5", + "version_normalized": "1.3.5.0", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.8" + }, + "time": "2026-02-23T03:47:12+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.5" + }, + "install-path": "../nette/schema" + }, + { + "name": "nette/security", + "version": "v3.2.6", + "version_normalized": "3.2.6.0", + "source": { + "type": "git", + "url": "https://github.com/nette/security.git", + "reference": "6cad44dbac2153bccf36e73784a38c43d7cdae8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/security/zipball/6cad44dbac2153bccf36e73784a38c43d7cdae8b", + "reference": "6cad44dbac2153bccf36e73784a38c43d7cdae8b", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/di": "<3.0-stable", + "nette/http": "<3.1.3" + }, + "require-dev": { + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/http": "^3.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "time": "2026-07-24T23:36:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔑 Nette Security: provides authentication, authorization and a role-based access control management via ACL (Access Control List)", + "homepage": "https://nette.org", + "keywords": [ + "Authentication", + "acl", + "authorization", + "nette" + ], + "support": { + "issues": "https://github.com/nette/security/issues", + "source": "https://github.com/nette/security/tree/v3.2.6" + }, + "install-path": "../nette/security" + }, + { + "name": "nette/tester", + "version": "v2.6.1", + "version_normalized": "2.6.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/tester.git", + "reference": "86e4d80d0953256c3b2930b9d47a07d2a9528770" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tester/zipball/86e4d80d0953256c3b2930b9d47a07d2a9528770", + "reference": "86e4d80d0953256c3b2930b9d47a07d2a9528770", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.5" + }, + "require-dev": { + "ext-simplexml": "*", + "phpstan/phpstan": "^2.0@stable" + }, + "time": "2026-05-11T18:11:12+00:00", + "bin": [ + "src/tester" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Tester\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Miloslav Hůla", + "homepage": "https://github.com/milo" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Tester: enjoyable unit testing in PHP with code coverage reporter. 🍏🍏🍎🍏", + "homepage": "https://tester.nette.org", + "keywords": [ + "Xdebug", + "assertions", + "clover", + "code coverage", + "nette", + "pcov", + "phpdbg", + "phpunit", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/nette/tester/issues", + "source": "https://github.com/nette/tester/tree/v2.6.1" + }, + "install-path": "../nette/tester" + }, + { + "name": "nette/utils", + "version": "v4.1.5", + "version_normalized": "4.1.5.0", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "b043439dbdf954e6c28b5ea7e34b0100f83165e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/b043439dbdf954e6c28b5ea7e34b0100f83165e0", + "reference": "b043439dbdf954e6c28b5ea7e34b0100f83165e0", + "shasum": "" + }, + "require": { + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.5", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::chr(), ord() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "time": "2026-07-17T23:02:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.5" + }, + "install-path": "../nette/utils" + }, + { + "name": "phpstan/extension-installer", + "version": "1.4.3", + "version_normalized": "1.4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "time": "2024-09-04T20:21:43+00:00", + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" + }, + "install-path": "../phpstan/extension-installer" + }, + { + "name": "phpstan/phpstan", + "version": "2.2.6", + "version_normalized": "2.2.6.0", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a6e9b5a9420f6109c091e87d82683bd1a80b87ed", + "reference": "a6e9b5a9420f6109c091e87d82683bd1a80b87ed", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "time": "2026-07-26T21:22:49+00:00", + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "install-path": "../phpstan/phpstan" + }, + { + "name": "symfony/thanks", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/thanks.git", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/thanks/zipball/f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": ">=8.1" + }, + "time": "2025-10-30T17:38:50+00:00", + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Thanks\\Thanks", + "branch-alias": { + "dev-main": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Thanks\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Encourages sending ⭐ and 💵 to fellow PHP package maintainers (not limited to Symfony components)!", + "support": { + "issues": "https://github.com/symfony/thanks/issues", + "source": "https://github.com/symfony/thanks/tree/v1.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/thanks" + }, + { + "name": "tracy/tracy", + "version": "v2.12.0", + "version_normalized": "2.12.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "535eda4871fd04f2756c8d95f6bdfa43706d79be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/535eda4871fd04f2756c8d95f6bdfa43706d79be", + "reference": "535eda4871fd04f2756c8d95f6bdfa43706d79be", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5 || ^3.0", + "nette/di": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "nette/utils": "^3.0 || ^4.0", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "time": "2026-05-04T00:23:53+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.12-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/Tracy/functions.php" + ], + "psr-4": { + "Tracy\\": "src" + }, + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "support": { + "issues": "https://github.com/nette/tracy/issues", + "source": "https://github.com/nette/tracy/tree/v2.12.0" + }, + "install-path": "../tracy/tracy" + } + ], + "dev": true, + "dev-package-names": [ + "nette/phpstan-rules", + "nette/tester", + "phpstan/extension-installer", + "phpstan/phpstan", + "symfony/thanks" + ] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 00000000..c5925798 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,239 @@ + array( + 'name' => 'nette/web-project', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => 'ff25b87b06e8e06360033757aed317ca76313e5b', + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + 'latte/latte' => array( + 'pretty_version' => 'v3.1.6', + 'version' => '3.1.6.0', + 'reference' => 'adccfac3d5d7bff441a0e5ae85978f448787f5d4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../latte/latte', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/application' => array( + 'pretty_version' => 'v3.3.0', + 'version' => '3.3.0.0', + 'reference' => '104484c317fdb1b29baf77617ca040b97685e9bb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/application', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/assets' => array( + 'pretty_version' => 'v1.0.7', + 'version' => '1.0.7.0', + 'reference' => '4a3d10902b6caca2eee3469e7863bea1b3bd1e2b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/assets', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/bootstrap' => array( + 'pretty_version' => 'v3.3.0', + 'version' => '3.3.0.0', + 'reference' => '3c8cbf8383b6df153bfb848a3c311ce42261a336', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/bootstrap', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/caching' => array( + 'pretty_version' => 'v3.4.2', + 'version' => '3.4.2.0', + 'reference' => '31f4bc6b366e6896998bd4538b26fa88a627bf2b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/caching', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/component-model' => array( + 'pretty_version' => 'v4.0.1', + 'version' => '4.0.1.0', + 'reference' => 'b4e82e1a3a7ca6f66ce766704aa2e148de277276', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/component-model', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/database' => array( + 'pretty_version' => 'v3.2.9', + 'version' => '3.2.9.0', + 'reference' => '6fe51398fcfc7719f64b7063f99886b438527755', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/database', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/di' => array( + 'pretty_version' => 'v3.2.6', + 'version' => '3.2.6.0', + 'reference' => '481ca2553e792daffa7fcf0ed43f705d80603fa4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/di', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/forms' => array( + 'pretty_version' => 'v3.3.0', + 'version' => '3.3.0.0', + 'reference' => '90aac9e6a55a71a76aaead65bca1129acb41ec84', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/forms', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/http' => array( + 'pretty_version' => 'v3.4.0', + 'version' => '3.4.0.0', + 'reference' => 'de5988d8802e76d9bda85fe5a871d29c794684f4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/http', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/mail' => array( + 'pretty_version' => 'v4.2.0', + 'version' => '4.2.0.0', + 'reference' => '6dd1042fb3cb95ebd3c6ca79507154dc74215bd2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/mail', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/neon' => array( + 'pretty_version' => 'v3.4.8', + 'version' => '3.4.8.0', + 'reference' => '9009f99ce1396b366a88ca16c90177148352b7d3', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/neon', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/php-generator' => array( + 'pretty_version' => 'v4.2.2', + 'version' => '4.2.2.0', + 'reference' => '0d7060926f5c3e8c488b9b9ced42d857f12a34b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/php-generator', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/phpstan-rules' => array( + 'pretty_version' => 'v1.0.5', + 'version' => '1.0.5.0', + 'reference' => '6811d818c5272b43eceb9e8dfee28071cfcd1ec5', + 'type' => 'phpstan-extension', + 'install_path' => __DIR__ . '/../nette/phpstan-rules', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'nette/robot-loader' => array( + 'pretty_version' => 'v4.1.2', + 'version' => '4.1.2.0', + 'reference' => 'ad3f4be7a9cd8a95ccc7596a1c4982a3b103d91e', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/robot-loader', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/routing' => array( + 'pretty_version' => 'v3.1.3', + 'version' => '3.1.3.0', + 'reference' => '92c0f7f89bdc5f93adec24b2ed7bb0c10e2550a6', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/routing', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/schema' => array( + 'pretty_version' => 'v1.3.5', + 'version' => '1.3.5.0', + 'reference' => 'f0ab1a3cda782dbc5da270d28545236aa80c4002', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/schema', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/security' => array( + 'pretty_version' => 'v3.2.6', + 'version' => '3.2.6.0', + 'reference' => '6cad44dbac2153bccf36e73784a38c43d7cdae8b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/security', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/tester' => array( + 'pretty_version' => 'v2.6.1', + 'version' => '2.6.1.0', + 'reference' => '86e4d80d0953256c3b2930b9d47a07d2a9528770', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/tester', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'nette/utils' => array( + 'pretty_version' => 'v4.1.5', + 'version' => '4.1.5.0', + 'reference' => 'b043439dbdf954e6c28b5ea7e34b0100f83165e0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/utils', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/web-project' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => 'ff25b87b06e8e06360033757aed317ca76313e5b', + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpstan/extension-installer' => array( + 'pretty_version' => '1.4.3', + 'version' => '1.4.3.0', + 'reference' => '85e90b3942d06b2326fba0403ec24fe912372936', + 'type' => 'composer-plugin', + 'install_path' => __DIR__ . '/../phpstan/extension-installer', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'phpstan/phpstan' => array( + 'pretty_version' => '2.2.6', + 'version' => '2.2.6.0', + 'reference' => 'a6e9b5a9420f6109c091e87d82683bd1a80b87ed', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpstan/phpstan', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'symfony/thanks' => array( + 'pretty_version' => 'v1.4.1', + 'version' => '1.4.1.0', + 'reference' => 'f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64', + 'type' => 'composer-plugin', + 'install_path' => __DIR__ . '/../symfony/thanks', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'tracy/tracy' => array( + 'pretty_version' => 'v2.12.0', + 'version' => '2.12.0.0', + 'reference' => '535eda4871fd04f2756c8d95f6bdfa43706d79be', + 'type' => 'library', + 'install_path' => __DIR__ . '/../tracy/tracy', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/vendor/latte/latte/bin/latte-lint b/vendor/latte/latte/bin/latte-lint new file mode 100644 index 00000000..bfd6c26e --- /dev/null +++ b/vendor/latte/latte/bin/latte-lint @@ -0,0 +1,43 @@ +#!/usr/bin/env php + $argv */ +$argv = $_SERVER['argv'] ?? []; + +if (count($argv) < 2) { + echo "Usage: latte-lint \n"; + exit(1); +} + +if ($debug = in_array('--debug', $argv, true)) { + echo "Debug mode\n"; +} +if ($strict = in_array('--strict', $argv, true)) { + echo "Strict mode\n"; +} + +$path = $argv[1]; + +try { + $linter = new Latte\Tools\Linter(debug: $debug, strict: $strict); + $ok = $linter->scanDirectory($path); + exit($ok ? 0 : 1); + +} catch (Throwable $e) { + fwrite(STDERR, $debug ? "\n$e\n" : "\nError: {$e->getMessage()}\n"); + exit(2); +} diff --git a/vendor/latte/latte/composer.json b/vendor/latte/latte/composer.json new file mode 100644 index 00000000..de78c533 --- /dev/null +++ b/vendor/latte/latte/composer.json @@ -0,0 +1,65 @@ +{ + "name": "latte/latte", + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "keywords": ["template", "nette", "security", "engine", "html", "twig", "context-sensitive", "escaping"], + "homepage": "https://latte.nette.org", + "license": ["BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": "8.2 - 8.5", + "ext-json": "*", + "ext-tokenizer": "*" + }, + "require-dev": { + "nette/tester": "^2.6", + "tracy/tracy": "^2.10", + "nette/utils": "^4.0", + "nette/php-generator": "^4.0", + "phpstan/phpstan": "^2.1@stable", + "phpstan/extension-installer": "^1.4@stable", + "nette/phpstan-rules": "^1.0" + }, + "suggest": { + "ext-iconv": "to use filters |reverse, |substring", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "ext-fileinfo": "to use filter |datastream", + "ext-intl": "to use Latte\\Engine::setLocale()", + "nette/utils": "to use filter |webalize", + "nette/php-generator": "to use tag {templatePrint}" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "autoload": { + "classmap": ["src/"], + "psr-4": { + "Latte\\": "src/Latte" + } + }, + "minimum-stability": "dev", + "bin": ["bin/latte-lint"], + "scripts": { + "phpstan": "phpstan analyse", + "tester": "tester tests -s" + }, + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } + } +} diff --git a/vendor/latte/latte/license.md b/vendor/latte/latte/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/latte/latte/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as is" and +any express or implied warranties, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose are +disclaimed. In no event shall the copyright owner or contributors be liable for +any direct, indirect, incidental, special, exemplary, or consequential damages +(including, but not limited to, procurement of substitute goods or services; +loss of use, data, or profits; or business interruption) however caused and on +any theory of liability, whether in contract, strict liability, or tort +(including negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/latte/latte/readme.md b/vendor/latte/latte/readme.md new file mode 100644 index 00000000..3b76fcd5 --- /dev/null +++ b/vendor/latte/latte/readme.md @@ -0,0 +1,47 @@ +[![Latte](https://github.com/nette/latte/assets/194960/76c098ff-427c-4b30-9676-97e2d8fd4a56)](https://latte.nette.org) + +  + +

+ +✅ The [only truly secure](https://latte.nette.org/en/safety-first) templating system for PHP
+✅ [You already know the syntax](https://latte.nette.org/en/syntax)
+✅ Highly mature, fast, and widely used library + +

+ +  + +Latte is the safest templating system for PHP. It is cleverly designed and easy to learn for those familiar with PHP, as they can quickly adopt its basic tags. +A wide range of useful features will significantly simplify your work. It provides top-notch protection against critical vulnerabilities and allows you to focus on creating high-quality applications without worrying about their security. + +🟨 Only 1% of programmers [can pass this quiz](https://blog.nette.org/en/quiz-can-you-defend-against-xss-vulnerability)! + +  + +Getting started +======= + +

+ +1️⃣ First, familiarize yourself with [Latte syntax](https://latte.nette.org/en/syntax) and [try it online](https://fiddle.nette.org/latte/#9cc0cf6d89)
+2️⃣ Take a look at the basic set of [tags](https://latte.nette.org/en/tags) and [filters](https://latte.nette.org/en/filters)
+3️⃣ Render a template with a [few lines of PHP code](https://latte.nette.org/en/develop) + +

+ +  + +Editor Integration +================== + +- PhpStorm ([Latte](https://plugins.jetbrains.com/plugin/24218-latte-support) or [Latte Pro](https://plugins.jetbrains.com/plugin/19661-latte-pro)) +- Visual Studio Code ([Nette Latte + Neon](https://marketplace.visualstudio.com/items?itemName=Kasik96.latte) or [Nette for VS Code](https://marketplace.visualstudio.com/items?itemName=franken-ui.nette-for-vscode)) + + + +Do you like Latte? Are you looking forward to the new features? + +[![Buy me a coffee](https://files.nette.org/icons/donation-3.svg)](https://github.com/sponsors/dg) + +Thank you! diff --git a/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php b/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php new file mode 100644 index 00000000..d1ff73e3 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php @@ -0,0 +1,98 @@ +addPanel(self::renderError(...)); + $blueScreen->addAction(self::renderUnknownMacro(...)); + if ( + version_compare(Tracy\Debugger::VERSION, '2.9.0', '>=') + && version_compare(Tracy\Debugger::VERSION, '3.0', '<') + ) { + Tracy\Debugger::addSourceMapper(self::mapLatteSourceCode(...)); + $blueScreen->addFileGenerator(fn(string $file) => str_ends_with($file, '.latte') + ? "{block content}\n\$END\$" + : null); + } + } + + + /** @return ?array{tab: string, panel: string} */ + public static function renderError(?\Throwable $e): ?array + { + if ($e instanceof Latte\CompileException && $e->sourceName) { + return [ + 'tab' => 'Template', + 'panel' => (preg_match('#[\n?]#', $e->sourceName) + ? '' + : '

' + . (@is_file($e->sourceName) // @ - may trigger error + ? 'File: ' . Helpers::editorLink($e->sourceName, $e->position?->line) + : '' . htmlspecialchars($e->sourceName . ($e->position?->line ? ':' . $e->position->line : '')) . '') + . '

') + . '
' + . BlueScreen::highlightLine(htmlspecialchars($e->sourceCode ?? '', ENT_IGNORE, 'UTF-8'), $e->position->line ?? 0, 15, $e->position->column ?? 0) + . '
', + ]; + } + + return null; + } + + + /** @return ?array{link: string, label: string} */ + public static function renderUnknownMacro(?\Throwable $e): ?array + { + if ( + $e instanceof Latte\CompileException + && $e->sourceName + && @is_file($e->sourceName) // @ - may trigger error + && (preg_match('#Unknown tag (\{\w+)}, did you mean (\{\w+)}\?#A', $e->getMessage(), $m) + || preg_match('#Unknown attribute (n:\w+), did you mean (n:\w+)\?#A', $e->getMessage(), $m)) + ) { + return [ + 'link' => (string) Helpers::editorUri($e->sourceName, $e->position?->line, 'fix', $m[1], $m[2]), + 'label' => 'fix it', + ]; + } + + return null; + } + + + /** @return array{file: string, line: int, label: string, active: bool} */ + public static function mapLatteSourceCode(string $file, int $line): ?array + { + return ($source = Latte\Helpers::mapCompiledToSource($file, $line)) && $source['name'] !== null && @is_file($source['name']) // @ - may trigger error + ? ['file' => $source['name'], 'line' => $source['line'] ?? 0, 'column' => $source['column'] ?? 0, 'label' => 'Latte', 'active' => true] + : null; + } +} diff --git a/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php b/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php new file mode 100644 index 00000000..16e11bb3 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php @@ -0,0 +1,169 @@ + spl_object_id => start time from hrtime() */ + private array $started = []; + + /** @var array spl_object_id => elapsed seconds */ + private array $elapsed = []; + + /** @var \stdClass[] */ + private array $list; + private ?string $name = null; + + + #[\Deprecated('use TracyExtension see https://bit.ly/46flfDi')] + public static function initialize(Engine $latte, ?string $name = null, ?Tracy\Bar $bar = null): void + { + $bar ??= Tracy\Debugger::getBar(); + $bar->addPanel(new self($latte, $name)); + } + + + /** @deprecated use TracyExtension see https://bit.ly/46flfDi */ + public function __construct(?Engine $latte = null, ?string $name = null) + { + $this->name = $name; + if ($latte) { + trigger_error('Replace LattePanel with TracyExtension; see https://bit.ly/46flfDi', E_USER_DEPRECATED); + $latte->addExtension( + new class ($this->templates) extends Extension { + public function __construct( + private array &$templates, + ) { + } + + + public function beforeRender(Template $template): void + { + $this->templates[] = $template; + } + }, + ); + } + } + + + public function addTemplate(Template $template): void + { + $this->templates[] = $template; + $this->started[spl_object_id($template)] = hrtime(true); + } + + + /** + * Records how long the template took to render, including its children. + */ + public function templateRendered(Template $template): void + { + $id = spl_object_id($template); + if (isset($this->started[$id])) { + $this->elapsed[$id] = (hrtime(true) - $this->started[$id]) / 1e9; + unset($this->started[$id]); + } + } + + + /** + * Renders tab. + */ + public function getTab(): ?string + { + if (!$this->templates) { + return null; + } + + return Tracy\Helpers::capture(function () { + $first = reset($this->templates); + $name = $this->name ?? ($first ? basename($first->getName()) : ''); + require __DIR__ . '/dist/tab.phtml'; + }); + } + + + /** + * Renders panel. + */ + public function getPanel(): string + { + $this->list = []; + $children = []; + foreach ($this->templates as $t) { + if ($parent = $t->getReferringTemplate()) { + $children[spl_object_id($parent)][$t->getName()][] = $t; + } + } + $this->buildList($children, $this->templates[0]); + + return Tracy\Helpers::capture(function () { + $list = $this->list; + $dumpParameters = $this->dumpParameters; + require __DIR__ . '/dist/panel.phtml'; + }); + } + + + /** + * @param array> $children + * @param Template[] $instances + */ + private function buildList(array $children, Template $template, int $depth = 0, array $instances = []): void + { + $instances = $instances ?: [$template]; + $groups = []; + foreach ($instances as $instance) { + foreach ($children[spl_object_id($instance)] ?? [] as $name => $templates) { + $groups[$name] = array_merge($groups[$name] ?? [], $templates); + } + } + + $time = array_sum(array_map($this->totalTime(...), $instances)); + $childrenTime = array_sum(array_map($this->totalTime(...), array_merge([], ...array_values($groups)))); + + $this->list[] = (object) [ + 'template' => $template, + 'depth' => $depth, + 'count' => count($instances), + 'phpFile' => (new \ReflectionObject($template))->getFileName(), + 'time' => $time, + 'selfTime' => max($time - $childrenTime, 0.0), + ]; + + foreach ($groups as $group) { + $this->buildList($children, $group[0], $depth + 1, $group); + } + } + + + /** + * Returns the rendering time of the instance including nested templates. + */ + private function totalTime(Template $template): float + { + return $this->elapsed[spl_object_id($template)] ?? 0.0; + } +} diff --git a/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php b/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php new file mode 100644 index 00000000..3cdb1254 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php @@ -0,0 +1,41 @@ +panel = new LattePanel(name: $name); + Tracy\Debugger::getBar()->addPanel($this->panel); + } + + + public function beforeRender(Template $template): void + { + $this->panel->addTemplate($template); + } + + + public function afterRender(Template $template): void + { + $this->panel->templateRendered($template); + } +} diff --git a/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml b/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml new file mode 100644 index 00000000..ee3c3a94 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml @@ -0,0 +1,143 @@ + '#00000052', 'extends' => '#cd1c1c7d', 'import' => '#17c35b8f', 'includeblock' => '#17c35b8f', 'embed' => '#4f1ccd7d', 'sandbox' => 'black'] /* pos 3:1 */; +echo ' + + +

Rendered Templates

+ +
+ + + + + + +'; +foreach ($list as $item) /* pos 78:3 */ { + echo ' + + + + + + +'; + +} + +echo '
Templatetime / self
+'; + if ($item->template->getReferenceType()) /* pos 81:6 */ { + echo ' └  + '; + echo Tracy\Helpers::escapeHtml($item->template->getReferenceType()) /* pos 83:104 */; + echo ' +'; + } + echo ' + '; + echo Tracy\Helpers::editorLink($item->template->getName()) /* pos 86:6 */; + echo ' + + phpFile))) === null ? '' : ' href="' . Tracy\Helpers::escapeHtml($ʟ_tmp) . '"' /* pos 88:16 */; + echo ' class="LattePanel-php">php + '; + echo Tracy\Helpers::escapeHtml($item->count > 1 ? $item->count . '×' : null) /* pos 91:9 */; + echo ' + '; + echo Tracy\Helpers::escapeHtml(number_format($item->time * 1000, 1)) /* pos 94:6 */; + echo ' ms + / '; + echo Tracy\Helpers::escapeHtml(number_format($item->selfTime * 1000, 1)) /* pos 95:15 */; + echo ' ms +
+ +'; +if ($dumpParameters) /* pos 101:2 */ { + echo '

Parameters

+ +
+ +'; + foreach (reset($list)->template->getParameters() as $k => $v) /* pos 106:5 */ { + echo ' + + + +'; + + } + + echo '
'; + echo Tracy\Helpers::escapeHtml($k) /* pos 108:11 */; + echo ''; + echo Tracy\Dumper::toHtml($v, [Tracy\Dumper::LIVE => true]) /* pos 109:11 */; + echo '
+
+'; +} +echo '
+'; diff --git a/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml b/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml new file mode 100644 index 00000000..347cd65a --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml @@ -0,0 +1,13 @@ + + + + + + '; +echo Tracy\Helpers::escapeHtml($name) /* pos 8:29 */; +echo ' + +'; diff --git a/vendor/latte/latte/src/Latte/Compiler/Block.php b/vendor/latte/latte/src/Latte/Compiler/Block.php new file mode 100644 index 00000000..4e5c2394 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Block.php @@ -0,0 +1,39 @@ +name instanceof Scalar\StringNode + && !$this->name instanceof Scalar\IntegerNode; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Dedent.php b/vendor/latte/latte/src/Latte/Compiler/Dedent.php new file mode 100644 index 00000000..642b5818 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Dedent.php @@ -0,0 +1,144 @@ +position->column - 1; + + $textNodes = []; + self::collectTextNodes($fragment, $textNodes); + + $baseIndent = self::detectIndent($textNodes, $startTag); + if ($baseIndent === null || strlen($baseIndent) <= $tagIndentLen) { + return; + } + + self::stripIndent($textNodes, $baseIndent, $tagIndentLen); + } + + + /** @param list $out */ + private static function collectTextNodes(Node $node, array &$out): void + { + if ($node instanceof Nodes\TextNode) { + $out[] = $node; + } elseif ($node instanceof Nodes\Html\ElementNode) { + if ($node->content) { + self::collectTextNodes($node->content, $out); + } + } else { + foreach ($node as $child) { + if ($child instanceof AreaNode) { + self::collectTextNodes($child, $out); + } + } + } + } + + + /** @param list $textNodes */ + private static function detectIndent(array $textNodes, Tag $startTag): ?string + { + $inlineChecked = false; + $lastNonEmpty = -1; + for ($k = count($textNodes) - 1; $k >= 0; $k--) { + if ($textNodes[$k]->content !== '') { + $lastNonEmpty = $k; + break; + } + } + + foreach ($textNodes as $idx => $node) { + if ($node->content === '') { + continue; + } + + if (!$inlineChecked) { + $inlineChecked = true; + if ($node->position?->line === $startTag->position->line) { + return null; + } + } + + $firstLineAtStart = $node->position?->column === 1; + $lines = explode("\n", $node->content); + $lineCount = count($lines); + $lastContinues = !str_ends_with($node->content, "\n") && $idx < $lastNonEmpty; + + foreach ($lines as $j => $line) { + $isLineStart = $j === 0 ? $firstLineAtStart : true; + if (!$isLineStart || $line === '') { + continue; + } + + $hasContent = trim($line) !== ''; + $continuesWithExpr = !$hasContent && $j === $lineCount - 1 && $lastContinues; + + if ($hasContent) { + preg_match('/^(\t+| +)/', $line, $m); + return $m[1] ?? null; + } elseif ($continuesWithExpr) { + return $line; + } + } + } + + return null; + } + + + /** @param list $textNodes */ + private static function stripIndent(array $textNodes, string $baseIndent, int $tagIndentLen): void + { + foreach ($textNodes as $node) { + if ($node->content === '') { + continue; + } + + $firstLineAtStart = $node->position?->column === 1; + $lines = explode("\n", $node->content); + $modified = false; + + foreach ($lines as $j => &$line) { + $isLineStart = $j === 0 ? $firstLineAtStart : true; + if (!$isLineStart || $line === '') { + continue; + } + + if (str_starts_with($line, $baseIndent)) { + $line = substr($line, 0, $tagIndentLen) . substr($line, strlen($baseIndent)); + $modified = true; + } elseif (trim($line) !== '') { + throw new CompileException('Inconsistent indentation.', $node->position ? new Position($node->position->line + $j, 1) : null); + } + } + + unset($line); + if ($modified) { + $node->content = implode("\n", $lines); + } + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Escaper.php b/vendor/latte/latte/src/Latte/Compiler/Escaper.php new file mode 100644 index 00000000..925c912e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Escaper.php @@ -0,0 +1,262 @@ + [ + self::HtmlText => 'HtmlHelpers::escapeText', + self::HtmlAttribute => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::JavaScript => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::Css => 'HtmlHelpers::escapeAttr', + self::HtmlComment => 'HtmlHelpers::escapeComment', + 'xml' => 'XmlHelpers::escapeText', + 'xml/attr' => 'XmlHelpers::escapeAttr', + ], + self::JavaScript => [ + self::HtmlText => 'HtmlHelpers::escapeText', + self::HtmlAttribute => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::JavaScript => 'HtmlHelpers::escapeAttr', + self::HtmlRawText . '/' . self::JavaScript => 'HtmlHelpers::convertJSToRawText', + self::HtmlComment => 'HtmlHelpers::escapeComment', + ], + self::Css => [ + self::HtmlText => 'HtmlHelpers::escapeText', + self::HtmlAttribute => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::Css => 'HtmlHelpers::escapeAttr', + self::HtmlRawText . '/' . self::Css => 'HtmlHelpers::convertJSToRawText', + self::HtmlComment => 'HtmlHelpers::escapeComment', + ], + self::HtmlText => [ + self::Text => 'HtmlHelpers::convertHtmlToText', + self::HtmlAttribute => 'HtmlHelpers::convertHtmlToAttr', + self::HtmlAttribute . '/' . self::JavaScript => 'HtmlHelpers::convertHtmlToAttr', + self::HtmlAttribute . '/' . self::Css => 'HtmlHelpers::convertHtmlToAttr', + self::HtmlComment => 'HtmlHelpers::escapeComment', + self::HtmlRawText . '/' . self::HtmlText => 'HtmlHelpers::convertHtmlToRawText', + ], + self::HtmlAttribute => [ + self::HtmlText => 'HtmlHelpers::convertAttrToHtml', + ], + ]; + + private string $state = ''; + private string $subType = ''; + + + public function __construct( + private string $contentType, + ) { + $this->state = in_array($contentType, [ContentType::Html, ContentType::Xml], strict: true) + ? self::HtmlText + : $contentType; + } + + + public function getContentType(): string + { + return $this->contentType; + } + + + public function getState(): string + { + return $this->state; + } + + + /** + * Returns the current escaping state as a string (e.g. "html/attr/js"). + */ + public function export(): string + { + return $this->state . ($this->subType ? '/' . $this->subType : ''); + } + + + public function enterContentType(string $type): void + { + $this->contentType = $this->state = $type; + } + + + public function enterHtmlText(ElementNode $el): void + { + if ($el->isRawText()) { + $this->state = self::HtmlRawText; + if ($el->is('script')) { + $type = $el->getAttribute('type'); + $this->subType = is_string($type) + ? HtmlHelpers::classifyScriptType($type) + : self::JavaScript; // missing or dynamic type attribute + } elseif ($el->is('style')) { + $this->subType = self::Css; + } + + } else { + $this->state = self::HtmlText; + $this->subType = ''; + } + } + + + public function enterHtmlTag(string $name): void + { + $this->state = self::HtmlTag; + } + + + public function enterHtmlRaw(string $subType): void + { + $this->state = self::HtmlRawText; + $this->subType = $subType; + } + + + public function enterHtmlAttribute(?string $name = null): void + { + $this->state = self::HtmlAttribute; + $this->subType = ''; + + if ($this->contentType === ContentType::Html && is_string($name)) { + $name = strtolower($name); + if (str_starts_with($name, 'on')) { + $this->subType = self::JavaScript; + } elseif ($name === 'style') { + $this->subType = self::Css; + } + } + } + + + public function enterHtmlBogusTag(): void + { + $this->state = self::HtmlBogusTag; + } + + + public function enterHtmlComment(): void + { + $this->state = self::HtmlComment; + } + + + public function escape(string $str): string + { + return match ($this->contentType) { + ContentType::Html => match ($this->state) { + self::HtmlText => 'LR\HtmlHelpers::escapeText(' . $str . ')', + self::HtmlTag => 'LR\HtmlHelpers::escapeTag(' . $str . ')', + self::HtmlAttribute => match ($this->subType) { + '' => 'LR\HtmlHelpers::escapeAttr(' . $str . ')', + self::JavaScript => 'LR\HtmlHelpers::escapeAttr(LR\Helpers::escapeJs(' . $str . '))', + self::Css => 'LR\HtmlHelpers::escapeAttr(LR\Helpers::escapeCss(' . $str . '))', + }, + self::HtmlComment => 'LR\HtmlHelpers::escapeComment(' . $str . ')', + self::HtmlBogusTag => 'LR\HtmlHelpers::escapeTag(' . $str . ')', + self::HtmlRawText => match ($this->subType) { + self::Text => 'LR\HtmlHelpers::convertJSToRawText(' . $str . ')', // sanitization, escaping is not possible + self::HtmlText => 'LR\HtmlHelpers::escapeRawHtml(' . $str . ')', + self::JavaScript => 'LR\Helpers::escapeJs(' . $str . ')', + self::Css => 'LR\Helpers::escapeCss(' . $str . ')', + default => throw new \LogicException("Unknown raw text subtype '$this->subType'."), + }, + default => throw new \LogicException("Unknown context $this->contentType, $this->state."), + }, + ContentType::Xml => match ($this->state) { + self::HtmlText => 'LR\XmlHelpers::escapeText(' . $str . ')', + self::HtmlBogusTag => 'LR\XmlHelpers::escapeTag(' . $str . ')', + self::HtmlAttribute => 'LR\XmlHelpers::escapeAttr(' . $str . ')', + self::HtmlComment => 'LR\HtmlHelpers::escapeComment(' . $str . ')', + self::HtmlTag => 'LR\XmlHelpers::escapeTag(' . $str . ')', + default => throw new \LogicException("Unknown context $this->contentType, $this->state."), + }, + ContentType::JavaScript => 'LR\Helpers::escapeJs(' . $str . ')', + ContentType::Css => 'LR\Helpers::escapeCss(' . $str . ')', + ContentType::ICal => 'LR\Helpers::escapeIcal(' . $str . ')', + ContentType::Text => '($this->filters->escape)(' . $str . ')', + default => throw new \LogicException("Unknown content-type $this->contentType."), + }; + } + + + /** + * Applies mandatory escaping that cannot be suppressed (e.g. quotes in attributes). + */ + public function escapeMandatory(string $str, ?Position $position = null): string + { + return match ($this->contentType) { + ContentType::Html => match ($this->state) { + self::HtmlAttribute => "LR\\HtmlHelpers::escapeQuotes($str)", + self::HtmlRawText => match ($this->subType) { + self::HtmlText => 'LR\HtmlHelpers::convertHtmlToRawText(' . $str . ')', + default => "LR\\HtmlHelpers::convertJSToRawText($str)", + }, + self::HtmlComment => throw new Latte\CompileException('Using |noescape is not allowed in this context.', $position), + default => $str, + }, + ContentType::Xml => match ($this->state) { + self::HtmlAttribute => "LR\\HtmlHelpers::escapeQuotes($str)", + self::HtmlComment => throw new Latte\CompileException('Using |noescape is not allowed in this context.', $position), + default => $str, + }, + default => $str, + }; + } + + + /** + * Generates code that converts content between content types at runtime using FilterInfo. + */ + public function escapeContent(string $str): string + { + return 'LR\Helpers::convertTo($ʟ_fi, ' + . var_export($this->export(), return: true) . ', ' + . $str + . ')'; + } + + + /** + * Returns a callable that converts content from $source type to $dest type, or null if unsupported. + */ + public static function getConvertor(string $source, string $dest): ?callable + { + return match (true) { + $source === $dest => Helpers::nop(...), + isset(self::Convertors[$source][$dest]) => 'Latte\Runtime\\' . self::Convertors[$source][$dest], + default => null, + }; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Node.php b/vendor/latte/latte/src/Latte/Compiler/Node.php new file mode 100644 index 00000000..648230fc --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Node.php @@ -0,0 +1,25 @@ + + */ +abstract class Node implements \IteratorAggregate +{ + public ?Position $position = null; + public ?Position $end = null; + + + abstract public function print(PrintContext $context): string; + + + /** @return \Generator */ + abstract public function &getIterator(): \Generator; +} diff --git a/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php b/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php new file mode 100644 index 00000000..254f0c0c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php @@ -0,0 +1,152 @@ + + */ + public static function find(Node $node, callable $filter): array + { + $found = []; + (new NodeTraverser) + ->traverse($node, enter: function (Node $node) use ($filter, &$found) { + if ($filter($node)) { + $found[] = $node; + } + }); + return $found; + } + + + /** + * Finds the first node matching the filter, or null if none. + * @param callable(Node): bool $filter + */ + public static function findFirst(Node $node, callable $filter): ?Node + { + $found = null; + (new NodeTraverser) + ->traverse($node, enter: function (Node $node) use ($filter, &$found) { + if ($filter($node)) { + $found = $node; + return NodeTraverser::StopTraversal; + } + }); + return $found; + } + + + /** + * Creates a deep clone of the node tree. + */ + public static function clone(Node $node): Node + { + return (new NodeTraverser) + ->traverse($node, enter: fn(Node $node) => clone $node) ?? throw new \LogicException; + } + + + /** + * Evaluates a scalar expression node to a PHP value. Resolves constants when $constants is true. + * Throws InvalidArgumentException if the expression cannot be reduced to a value. + */ + public static function toValue(ExpressionNode $node, bool $constants = false): mixed + { + if ($node instanceof Scalar\BooleanNode + || $node instanceof Scalar\FloatNode + || $node instanceof Scalar\IntegerNode + || $node instanceof Scalar\StringNode + ) { + return $node->value; + + } elseif ($node instanceof Scalar\NullNode) { + return null; + + } elseif ($node instanceof Expression\ArrayNode) { + $res = []; + foreach ($node->items as $item) { + $value = self::toValue($item->value, $constants); + if ($item->key) { + $key = $item->key instanceof Php\IdentifierNode + ? $item->key->name + : self::toValue($item->key, $constants); + $res[$key] = $value; + + } elseif ($item->unpack) { + $res = array_merge($res, $value); + + } else { + $res[] = $value; + } + } + + return $res; + + } elseif ($node instanceof Expression\ConstantFetchNode && $constants) { + $name = $node->name->toCodeString(); + return defined($name) + ? constant($name) + : throw new \InvalidArgumentException("The constant '$name' is not defined."); + + } elseif ( + $node instanceof Expression\ClassConstantFetchNode + && $constants + && $node->name instanceof Php\IdentifierNode + ) { + $class = $node->class instanceof Php\NameNode + ? $node->class->toCodeString() + : self::toValue($node->class, $constants); + $name = $class . '::' . $node->name->name; + return defined($name) + ? constant($name) + : throw new \InvalidArgumentException("The constant '$name' is not defined."); + + } else { + throw new \InvalidArgumentException('The expression cannot be converted to PHP value.'); + } + } + + + /** + * Extracts plain text from a node if it contains only static text, or returns null. + */ + public static function toText(?Node $node): ?string + { + if ($node instanceof Nodes\FragmentNode) { + $res = ''; + foreach ($node->children as $child) { + if (($s = self::toText($child)) === null) { + return null; + } + $res .= $s; + } + + return $res; + } + + return match (true) { + $node instanceof Nodes\TextNode => $node->content, + $node instanceof Nodes\NopNode => '', + default => null, + }; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php b/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php new file mode 100644 index 00000000..9c0b96f7 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php @@ -0,0 +1,101 @@ +enter = $enter ? $enter(...) : null; + $this->leave = $leave ? $leave(...) : null; + $this->stop = false; + return $this->traverseNode($node); + } + + + private function traverseNode(Node $node): ?Node + { + $children = true; + if ($this->enter) { + $res = ($this->enter)($node); + if ($res instanceof Node) { + $node = $res; + + } elseif ($res === self::DontTraverseChildren) { + $children = false; + + } elseif ($res === self::StopTraversal) { + $this->stop = true; + return $node; + + } elseif ($res === self::RemoveNode) { + return null; + } + } + + if ($children) { + foreach ($node as &$subnode) { + $res = $this->traverseNode($subnode); + if ($res !== $subnode) { + try { + $subnode = $res; + } catch (\TypeError $e) { + throw new \LogicException(sprintf( + 'Cannot %s child node of %s during traversal, its slot does not allow that.', + $res === null ? 'remove' : 'replace', + $node::class, + ), 0, $e); + } + } + if ($this->stop) { + break; + } + } + } + + if (!$this->stop && $this->leave) { + $res = ($this->leave)($node); + if ($res instanceof Node) { + $node = $res; + + } elseif ($res === self::StopTraversal) { + $this->stop = true; + + } elseif ($res === self::RemoveNode) { + return null; + } + } + + return $node; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php new file mode 100644 index 00000000..a787b75b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php @@ -0,0 +1,21 @@ +print)($context, ...$this->nodes); + } + + + public function &getIterator(): \Generator + { + foreach ($this->nodes as &$node) { + if ($node) { + yield $node; + } + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php new file mode 100644 index 00000000..f5fa394b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php @@ -0,0 +1,96 @@ +append($child); + } + } + + + /** + * Appends a node. FragmentNode children are merged inline; NopNodes are discarded. + */ + public function append(AreaNode $node): static + { + if ($node instanceof self) { + $this->children = array_merge($this->children, $node->children); + } elseif (!$node instanceof NopNode) { + $this->children[] = $node; + } + return $this; + } + + + /** + * Recomputes the extent to span the children (lowest start, highest end). Called by the + * parser once the tree is built; a fragment has no extent of its own until then. + */ + public function updateExtent(): void + { + $this->position = $this->end = null; + foreach ($this->children as $child) { + if ($child->position && (!$this->position || $child->position->offset < $this->position->offset)) { + $this->position = $child->position; + } + if ($child->end && (!$this->end || $child->end->offset > $this->end->offset)) { + $this->end = $child->end; + } + } + } + + + /** + * Returns null (or self) for an empty fragment, the single child when there is only one, or self otherwise. + */ + public function simplify(bool $allowsNull = true): ?AreaNode + { + return match (true) { + !$this->children => $allowsNull ? null : $this, + count($this->children) === 1 => $this->children[0], + default => $this, + }; + } + + + public function print(PrintContext $context): string + { + $res = ''; + foreach ($this->children as $child) { + $res .= $child->print($context); + } + + return $res; + } + + + public function &getIterator(): \Generator + { + foreach ($this->children as &$item) { + yield $item; + } + Helpers::removeNulls($this->children); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php new file mode 100644 index 00000000..57998e2c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php @@ -0,0 +1,59 @@ +name->print($context); + if (!$this->value) { + return $res; + } + + $res .= "echo '=';"; + $quote = $this->quote ?? ($this->value instanceof TextNode ? null : '"'); + $res .= $quote ? 'echo ' . var_export($quote, return: true) . ';' : ''; + + $escaper = $context->beginEscape(); + $escaper->enterHtmlAttribute(NodeHelpers::toText($this->name)); + $res .= $this->value->print($context); + $context->restoreEscape(); + $res .= $quote ? 'echo ' . var_export($quote, return: true) . ';' : ''; + return $res; + } + + + public function &getIterator(): \Generator + { + yield $this->name; + if ($this->value) { + yield $this->value; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php new file mode 100644 index 00000000..056747f4 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php @@ -0,0 +1,45 @@ +openDelimiter, return: true) . ';'; + $context->beginEscape()->enterHtmlBogusTag(); + $res .= $this->content->print($context); + $context->restoreEscape(); + $res .= 'echo ' . var_export($this->endDelimiter, return: true) . ';'; + return $res; + } + + + public function &getIterator(): \Generator + { + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php new file mode 100644 index 00000000..e7d1f7b1 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php @@ -0,0 +1,41 @@ +). + */ +class CommentNode extends AreaNode +{ + public function __construct( + public AreaNode $content, + public ?Position $position = null, + public ?Position $end = null, + ) { + } + + + public function print(PrintContext $context): string + { + $context->beginEscape()->enterHtmlComment(); + $content = $this->content->print($context); + $context->restoreEscape(); + return "echo '';"; + } + + + public function &getIterator(): \Generator + { + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php new file mode 100644 index 00000000..d3cbf959 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php @@ -0,0 +1,132 @@ +attributes = new FragmentNode; + } + + + /** + * Returns the attribute value: plain string if static, Node if dynamic, true if it is a boolean or n:attribute, null if not found. + */ + public function getAttribute(string $name): string|Node|bool|null + { + foreach ($this->attributes->children as $child) { + if ($child instanceof AttributeNode + && $child->name instanceof Nodes\TextNode + && $this->matchesIdentifier($name, $child->name->content) + ) { + return NodeHelpers::toText($child->value) ?? $child->value ?? true; + } elseif ($child instanceof ExpressionAttributeNode + && $this->matchesIdentifier($name, $child->name) + ) { + return true; + } + } + + return null; + } + + + /** + * Checks whether the element has the given tag name (case-insensitive in HTML, case-sensitive in XML). + */ + public function is(string $name): bool + { + return $this->matchesIdentifier($this->name, $name); + } + + + private function matchesIdentifier(string $a, string $b): bool + { + return $this->contentType === ContentType::Html + ? strcasecmp($a, $b) === 0 + : $a === $b; + } + + + /** + * Checks whether the element contains raw text (i.e., is a '; + echo ''; + echo "
\n"; + } + + + public function printEnd(): void + { + echo "
\n"; + } + + + public function printHeader(string $string): void + { + echo "

", + htmlspecialchars($string), + "

\n"; + } + + + public function printCode(string $code, string $lang = 'php'): void + { + echo '
',
+			htmlspecialchars($code),
+			"
\n"; + } + + + private function getType(mixed $value): string + { + return $value === null ? 'mixed' : get_debug_type($value); + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/CachingIterator.php b/vendor/latte/latte/src/Latte/Essential/CachingIterator.php new file mode 100644 index 00000000..c44474df --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/CachingIterator.php @@ -0,0 +1,222 @@ +> + * @internal + */ +class CachingIterator extends \CachingIterator implements \Countable +{ + private int $counter = 0; + private ?self $parent = null; + + + public function __construct(mixed $iterator, ?self $parent = null) + { + if (is_array($iterator) || $iterator instanceof \stdClass) { + $iterator = new \ArrayIterator((array) $iterator); + + } elseif ($iterator instanceof \IteratorAggregate) { + do { + $iterator = $iterator->getIterator(); + } while (!$iterator instanceof \Iterator); + } elseif ($iterator instanceof \Traversable) { + if (!$iterator instanceof \Iterator) { + $iterator = new \IteratorIterator($iterator); + } + } else { + throw new \InvalidArgumentException(sprintf('Invalid argument passed to foreach; array or Traversable expected, %s given.', get_debug_type($iterator))); + } + + parent::__construct($iterator, 0); + $this->parent = $parent; + } + + + /** + * Is the current element the first one? + */ + public function isFirst(?int $width = null): bool + { + return $this->counter === 1 || ($width && $this->counter !== 0 && (($this->counter - 1) % $width) === 0); + } + + + /** + * Is the current element the last one? + */ + public function isLast(?int $width = null): bool + { + return !$this->hasNext() || ($width && ($this->counter % $width) === 0); + } + + + /** + * Is the iterator empty? + */ + public function isEmpty(): bool + { + return $this->counter === 0; + } + + + /** + * Is the counter odd? + */ + public function isOdd(): bool + { + return $this->counter % 2 === 1; + } + + + /** + * Is the counter even? + */ + public function isEven(): bool + { + return $this->counter % 2 === 0; + } + + + /** + * Returns the 1-indexed counter. + */ + public function getCounter(): int + { + return $this->counter; + } + + + /** + * Returns the 0-indexed counter. + */ + public function getCounter0(): int + { + return max(0, $this->counter - 1); + } + + + /** + * Decrements the counter (minimum 0) to skip the current iteration in counting. + */ + public function skipRound(): void + { + $this->counter = max($this->counter - 1, 0); + } + + + public function __toString(): string + { + return (string) $this->counter; + } + + + public function count(): int + { + $inner = $this->getInnerIterator(); + if ($inner instanceof \Countable) { + return $inner->count(); + + } else { + throw new \LogicException('Iterator is not countable.'); + } + } + + + /** + * Forwards to the next element. + */ + public function next(): void + { + parent::next(); + if (parent::valid()) { + $this->counter++; + } + } + + + /** + * Rewinds the Iterator. + */ + public function rewind(): void + { + parent::rewind(); + $this->counter = parent::valid() ? 1 : 0; + } + + + /** + * Returns the next key or null if position is not valid. + */ + public function getNextKey(): mixed + { + $iterator = $this->getInnerIterator(); + return $iterator->valid() ? $iterator->key() : null; + } + + + /** + * Returns the next element or null if position is not valid. + */ + public function getNextValue(): mixed + { + $iterator = $this->getInnerIterator(); + return $iterator->valid() ? $iterator->current() : null; + } + + + /** + * Returns the iterator surrounding the current one. + */ + public function getParent(): ?self + { + return $this->parent; + } + + + /********************* property accessor ****************d*g**/ + + + /** + * Returns property value. + * @throws \LogicException if the property is not defined. + */ + public function __get(string $name): mixed + { + if (method_exists($this, $m = 'get' . $name) || method_exists($this, $m = 'is' . $name)) { + return $this->$m(); + } + + throw new \LogicException('Attempt to read undeclared property ' . static::class . "::\$$name."); + } + + + /** + * Is property defined? + */ + public function __isset(string $name): bool + { + return method_exists($this, 'get' . $name) || method_exists($this, 'is' . $name); + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/CoreExtension.php b/vendor/latte/latte/src/Latte/Essential/CoreExtension.php new file mode 100644 index 00000000..8d16d0bb --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/CoreExtension.php @@ -0,0 +1,294 @@ +filters = new Filters; + } + + + public function beforeCompile(Latte\Engine $engine): void + { + $this->engine = $engine; + } + + + public function beforeRender(Runtime\Template $template): void + { + $this->engine = $template->getEngine(); + $this->filters->locale = $this->engine->getLocale(); + } + + + public function getTags(): array + { + return [ + 'embed' => Nodes\EmbedNode::create(...), + 'define' => Nodes\DefineNode::create(...), + 'block' => Nodes\BlockNode::create(...), + 'layout' => Nodes\ExtendsNode::create(...), + 'extends' => Nodes\ExtendsNode::create(...), + 'import' => Nodes\ImportNode::create(...), + 'include' => $this->includeSplitter(...), + + 'n:attr' => Nodes\NAttrNode::create(...), + 'n:class' => Nodes\NClassNode::create(...), + 'n:tag' => Nodes\NTagNode::create(...), + + 'parameters' => Nodes\ParametersNode::create(...), + 'varType' => Nodes\VarTypeNode::create(...), + 'varPrint' => Nodes\VarPrintNode::create(...), + 'templateType' => Nodes\TemplateTypeNode::create(...), + 'templatePrint' => Nodes\TemplatePrintNode::create(...), + + '=' => Latte\Compiler\Nodes\PrintNode::create(...), + 'do' => Nodes\DoNode::create(...), + 'php' => Nodes\DoNode::create(...), // obsolete + 'contentType' => Nodes\ContentTypeNode::create(...), + 'spaceless' => Nodes\SpacelessNode::create(...), + 'capture' => Nodes\CaptureNode::create(...), + 'l' => fn(Tag $tag) => new TextNode('{', $tag->position), + 'r' => fn(Tag $tag) => new TextNode('}', $tag->position), + 'syntax' => $this->parseSyntax(...), + + 'dump' => Nodes\DumpNode::create(...), + 'debugbreak' => Nodes\DebugbreakNode::create(...), + 'trace' => Nodes\TraceNode::create(...), + + 'var' => Nodes\VarNode::create(...), + 'default' => Nodes\VarNode::create(...), + + 'try' => Nodes\TryNode::create(...), + 'rollback' => Nodes\RollbackNode::create(...), + + 'foreach' => Nodes\ForeachNode::create(...), + 'for' => Nodes\ForNode::create(...), + 'while' => Nodes\WhileNode::create(...), + 'iterateWhile' => Nodes\IterateWhileNode::create(...), + 'sep' => Nodes\FirstLastSepNode::create(...), + 'last' => Nodes\FirstLastSepNode::create(...), + 'first' => Nodes\FirstLastSepNode::create(...), + 'skipIf' => Nodes\JumpNode::create(...), + 'breakIf' => Nodes\JumpNode::create(...), + 'exitIf' => Nodes\JumpNode::create(...), + 'continueIf' => Nodes\JumpNode::create(...), + + 'if' => Nodes\IfNode::create(...), + 'ifset' => Nodes\IfNode::create(...), + 'ifchanged' => Nodes\IfChangedNode::create(...), + 'n:ifcontent' => Nodes\IfContentNode::create(...), + 'n:else' => Nodes\NElseNode::create(...), + 'n:elseif' => Nodes\NElseNode::create(...), + 'switch' => Nodes\SwitchNode::create(...), + ]; + } + + + public function getFilters(): array + { + return [ + 'batch' => $this->filters->batch(...), + 'breakLines' => $this->filters->breaklines(...), + 'breaklines' => $this->filters->breaklines(...), + 'bytes' => $this->filters->bytes(...), + 'capitalize' => extension_loaded('mbstring') + ? $this->filters->capitalize(...) + : fn() => throw new RuntimeException('Filter |capitalize requires mbstring extension.'), + 'ceil' => $this->filters->ceil(...), + 'checkUrl' => $this->filters->checkUrl(...), + 'clamp' => $this->filters->clamp(...), + 'column' => $this->filters->column(...), + 'commas' => $this->filters->commas(...), + 'dataStream' => $this->filters->dataStream(...), + 'datastream' => $this->filters->dataStream(...), + 'date' => $this->filters->date(...), + 'escape' => Latte\Runtime\Helpers::nop(...), + 'escapeCss' => Latte\Runtime\Helpers::escapeCss(...), + 'escapeHtml' => Latte\Runtime\HtmlHelpers::escapeText(...), + 'escapeHtmlComment' => Latte\Runtime\HtmlHelpers::escapeComment(...), + 'escapeICal' => Latte\Runtime\Helpers::escapeICal(...), + 'escapeJs' => Latte\Runtime\Helpers::escapeJs(...), + 'escapeUrl' => 'rawurlencode', + 'escapeXml' => Latte\Runtime\XmlHelpers::escapeText(...), + 'explode' => $this->filters->explode(...), + 'filter' => $this->filters->filter(...), + 'first' => $this->filters->first(...), + 'firstLower' => extension_loaded('mbstring') + ? $this->filters->firstLower(...) + : fn() => throw new RuntimeException('Filter |firstLower requires mbstring extension.'), + 'firstUpper' => extension_loaded('mbstring') + ? $this->filters->firstUpper(...) + : fn() => throw new RuntimeException('Filter |firstUpper requires mbstring extension.'), + 'floor' => $this->filters->floor(...), + 'group' => $this->filters->group(...), + 'implode' => $this->filters->implode(...), + 'indent' => $this->filters->indent(...), + 'join' => $this->filters->implode(...), + 'last' => $this->filters->last(...), + 'length' => $this->filters->length(...), + 'limit' => fn(string|iterable $value, int $length) => Filters::slice($value, 0, $length, preserveKeys: true), + 'localDate' => $this->filters->localDate(...), + 'lower' => extension_loaded('mbstring') + ? $this->filters->lower(...) + : fn() => throw new RuntimeException('Filter |lower requires mbstring extension.'), + 'map' => $this->filters->map(...), + 'number' => $this->filters->number(...), + 'padLeft' => $this->filters->padLeft(...), + 'padRight' => $this->filters->padRight(...), + 'query' => $this->filters->query(...), + 'random' => $this->filters->random(...), + 'repeat' => $this->filters->repeat(...), + 'replace' => $this->filters->replace(...), + 'replaceRe' => $this->filters->replaceRe(...), + 'replaceRE' => $this->filters->replaceRe(...), + 'reverse' => $this->filters->reverse(...), + 'round' => $this->filters->round(...), + 'slice' => $this->filters->slice(...), + 'sort' => $this->filters->sort(...), + 'spaceless' => $this->filters->spaceless(...), + 'split' => $this->filters->explode(...), + 'strip' => $this->filters->spaceless(...), // obsolete + 'stripHtml' => $this->filters->stripHtml(...), + 'striphtml' => $this->filters->stripHtml(...), + 'stripTags' => $this->filters->stripTags(...), + 'striptags' => $this->filters->stripTags(...), + 'substr' => $this->filters->substring(...), + 'trim' => $this->filters->trim(...), + 'truncate' => $this->filters->truncate(...), + 'upper' => extension_loaded('mbstring') + ? $this->filters->upper(...) + : fn() => throw new RuntimeException('Filter |upper requires mbstring extension.'), + 'webalize' => class_exists(Nette\Utils\Strings::class) + ? Nette\Utils\Strings::webalize(...) + : fn() => throw new RuntimeException('Filter |webalize requires nette/utils package.'), + ]; + } + + + public function getFunctions(): array + { + return [ + 'clamp' => $this->filters->clamp(...), + 'divisibleBy' => $this->filters->divisibleBy(...), + 'even' => $this->filters->even(...), + 'first' => $this->filters->first(...), + 'group' => $this->filters->group(...), + 'last' => $this->filters->last(...), + 'odd' => $this->filters->odd(...), + 'slice' => $this->filters->slice(...), + 'hasBlock' => fn(Runtime\Template $template, string $name): bool => $template->hasBlock($name), + 'hasTemplate' => fn(Runtime\Template $template, string $name): bool => $this->hasTemplate($name, $template->getName()), + ]; + } + + + public function getPasses(): array + { + $passes = new Passes($this->engine); + return [ + 'internalVariables' => $passes->forbiddenVariablesPass(...), + 'checkUrls' => $passes->checkUrlsPass(...), + 'overwrittenVariables' => function (Latte\Compiler\Nodes\TemplateNode $node): void { + if (!$this->engine->hasFeature(Latte\Feature::ScopedLoopVariables)) { + Nodes\ForeachNode::overwrittenVariablesPass($node); + } + }, + 'customFunctions' => $passes->customFunctionsPass(...), + 'firstLastSep' => Nodes\FirstLastSepNode::outsideForeachPass(...), + 'moveTemplatePrintToHead' => Nodes\TemplatePrintNode::moveToHeadPass(...), + 'nElse' => Nodes\NElseNode::processPass(...), + 'scriptTagQuotes' => $passes->scriptTagQuotesPass(...), + ]; + } + + + public function getCacheKey(Latte\Engine $engine): mixed + { + return array_keys($engine->getFunctions()); + } + + + /** + * {include [file] "file" [with blocks] [,] [params]} + * {include [block] name [,] [params]} + */ + private function includeSplitter(Tag $tag, TemplateParser $parser): Nodes\IncludeBlockNode|Nodes\IncludeFileNode + { + $tag->expectArguments(); + $mod = $tag->parser->tryConsumeTokenBeforeUnquotedString('block', 'file'); + if ($mod) { + $block = $mod->text === 'block'; + } elseif ($tag->parser->stream->tryConsume('#')) { + $block = true; + } else { + $name = $tag->parser->parseUnquotedStringOrExpression(); + $block = $name instanceof Scalar\StringNode && preg_match('~[\w-]+$~DA', $name->value); + } + $tag->parser->stream->seek(0); + + return $block + ? Nodes\IncludeBlockNode::create($tag, $parser) + : Nodes\IncludeFileNode::create($tag); + } + + + /** + * {syntax ...} + */ + private function parseSyntax(Tag $tag, TemplateParser $parser): \Generator + { + if ($tag->isNAttribute() && $tag->prefix !== $tag::PrefixNone) { + throw new Latte\CompileException("Use n:syntax instead of {$tag->getNotation()}", $tag->position); + } + $tag->expectArguments(); + $token = $tag->parser->stream->consume(); + $lexer = $parser->getLexer(); + $lexer->setSyntax($token->text, $tag->isNAttribute() ? null : $tag->name); + [$inner] = yield; + if (!$tag->isNAttribute()) { + $lexer->popSyntax(); + } + return $inner; + } + + + /** + * Checks if template exists. + */ + private function hasTemplate(string $name, string $referringName): bool + { + try { + $name = $this->engine->getLoader()->getReferredName($name, $referringName); + $this->engine->createTemplate($name, clearCache: false); + return true; + } catch (Latte\TemplateNotFoundException) { + return false; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Filters.php b/vendor/latte/latte/src/Latte/Essential/Filters.php new file mode 100644 index 00000000..94ad2840 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Filters.php @@ -0,0 +1,845 @@ +validate([null, 'html', 'html/attr', 'xml', 'xml/attr'], __FUNCTION__); + $info->contentType = ContentType::Text; + return Latte\Runtime\HtmlHelpers::convertHtmlToText((string) $s); + } + + + /** + * Removes tags from HTML (but remains HTML entities). + */ + public static function stripTags(FilterInfo $info, string|Stringable|null $s): string + { + $info->contentType ??= ContentType::Html; + $info->validate(['html', 'html/attr', 'xml', 'xml/attr'], __FUNCTION__); + return strip_tags((string) $s); + } + + + /** + * Minifies whitespace: collapses runs to a single space, removes it around whitespace-insensitive tags entirely. + */ + public static function spaceless(FilterInfo $info, string $s): string + { + return (new WhitespaceMinifier($info->contentType ?? ContentType::Text))->minify($s); + } + + + /** + * Indents plain text or HTML the content from the left. + */ + public static function indent(FilterInfo $info, string $s, int $level = 1, string $chars = "\t"): string + { + $indent = str_repeat(addcslashes($chars, '$\\'), max(0, $level)); + if ($level < 1) { + // do nothing + } elseif ($info->contentType === ContentType::Html) { + $s = preg_replace_callback('#<(textarea|pre).*? strtr($m[0], " \t\r\n", "\x1F\x1E\x1D\x1A"), $s); + if (preg_last_error()) { + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + $s = preg_replace('#(?:^|[\r\n]+)(?=[^\r\n])#', '$0' . $indent, $s); + $s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n"); + } else { + $s = preg_replace('#(?:^|[\r\n]+)(?=[^\r\n])#', '$0' . $indent, $s); + } + + return $s; + } + + + /** + * Join iterable of text or HTML elements with a string. + * @param iterable $arr + */ + public static function implode(iterable $arr, string $glue = ''): string + { + return implode($glue, iterator_to_array($arr, preserve_keys: false)); + } + + + /** + * Join iterable elements with a comma and space. + * @param iterable $arr + */ + public static function commas(iterable $arr, ?string $lastGlue = null): string + { + $arr = iterator_to_array($arr, preserve_keys: false); + if ($lastGlue === null || count($arr) < 2) { + return implode(', ', $arr); + } + + $last = array_pop($arr); + return implode(', ', $arr) . $lastGlue . $last; + } + + + /** + * Splits a string by a string. + * @return list + */ + public static function explode(string $value, string $separator = ''): array + { + if ($separator !== '') { + return explode($separator, $value); + } + + $parts = preg_split('//u', $value, -1, PREG_SPLIT_NO_EMPTY); + if (preg_last_error()) { // e.g. malformed UTF-8 + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + return $parts; + } + + + /** + * Repeats text. + */ + public static function repeat(FilterInfo $info, string|Stringable|null $s, int $count): string + { + return str_repeat((string) $s, $count); + } + + + /** + * Date/time formatting. + */ + public static function date( + string|int|\DateTimeInterface|\DateInterval|null $time, + string $format = "j.\u{a0}n.\u{a0}Y", + ): ?string + { + if ($time == null) { // intentionally == + return null; + } elseif ($time instanceof \DateInterval) { + if (func_num_args() < 2) { + throw new Latte\RuntimeException("Filter |date: DateInterval requires an explicit format with %-placeholders like |date:'%d days'."); + } + return $time->format($format); + } elseif (is_numeric($time)) { + $time = (new \DateTime)->setTimestamp((int) $time); + } elseif (!$time instanceof \DateTimeInterface) { + $time = new \DateTime($time); + } + + return $time->format($format); + } + + + /** + * Date/time formatting according to locale. + */ + public function localDate( + string|int|\DateTimeInterface|null $value, + ?string $format = null, + ?string $date = null, + ?string $time = null, + ): ?string + { + if ($this->locale === null) { + throw new Latte\RuntimeException('Filter |localDate requires the locale to be set using Engine::setLocale()'); + } elseif ($value == null) { // intentionally == + return null; + } elseif (is_numeric($value)) { + $value = (new \DateTime)->setTimestamp((int) $value); + } elseif (!$value instanceof \DateTimeInterface) { + $value = new \DateTime($value); + $errors = \DateTime::getLastErrors(); + if (!empty($errors['warnings'])) { + throw new \InvalidArgumentException(reset($errors['warnings'])); + } + } + + if ($format === null) { + $xlt = ['' => \IntlDateFormatter::NONE, 'full' => \IntlDateFormatter::FULL, 'long' => \IntlDateFormatter::LONG, 'medium' => \IntlDateFormatter::MEDIUM, 'short' => \IntlDateFormatter::SHORT, + 'relative-full' => \IntlDateFormatter::RELATIVE_FULL, 'relative-long' => \IntlDateFormatter::RELATIVE_LONG, 'relative-medium' => \IntlDateFormatter::RELATIVE_MEDIUM, 'relative-short' => \IntlDateFormatter::RELATIVE_SHORT]; + $time ??= ''; + $date ??= $time === '' ? 'long' : ''; + $formatter = new \IntlDateFormatter($this->locale, $xlt[$date], $xlt[$time]); + } else { + $formatter = new \IntlDateFormatter($this->locale, pattern: (new \IntlDatePatternGenerator($this->locale))->getBestPattern($format)); + } + + $res = $formatter->format($value); + $res = preg_replace('~(\d\.) ~', "\$1\u{a0}", $res); + return $res; + } + + + /** + * Formats a number with grouped thousands and optionally decimal digits according to locale. + */ + public function number( + float $number, + string|int $patternOrDecimals = 0, + string $decimalSeparator = '.', + string $thousandsSeparator = ',', + ): string + { + if (is_int($patternOrDecimals) && $patternOrDecimals < 0) { + throw new Latte\RuntimeException('Filter |number: the number of decimal must not be negative'); + } elseif ($this->locale === null || func_num_args() > 2) { + if (is_string($patternOrDecimals)) { + throw new Latte\RuntimeException('Filter |number: using a pattern requires setting a locale via Engine::setLocale().'); + } + return number_format($number, $patternOrDecimals, $decimalSeparator, $thousandsSeparator); + } + + $formatter = new \NumberFormatter($this->locale, \NumberFormatter::DECIMAL); + if (is_string($patternOrDecimals)) { + $formatter->setPattern($patternOrDecimals); + } else { + $formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $patternOrDecimals); + } + return $formatter->format($number); + } + + + /** + * Converts to human-readable file size. + */ + public function bytes(float $bytes, int $precision = 2): string + { + $bytes = round($bytes); + $units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB']; + foreach ($units as $unit) { + if (abs($bytes) < 1024 || $unit === end($units)) { + break; + } + + $bytes /= 1024; + } + + if ($this->locale === null) { + $bytes = (string) round($bytes, $precision); + } else { + $formatter = new \NumberFormatter($this->locale, \NumberFormatter::DECIMAL); + $formatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $precision); + $bytes = $formatter->format($bytes); + } + + return $bytes . ' ' . $unit; + } + + + /** + * Performs a search and replace. + * @param string|array|array $search + * @param string|array|null $replace + */ + public static function replace( + FilterInfo $info, + string $subject, + string|array $search, + string|array|null $replace = null, + ): string + { + if (is_array($search)) { + if (is_array($replace)) { + return strtr($subject, array_combine($search, $replace)); + } elseif ($replace === null && is_string(key($search))) { + return strtr($subject, $search); + } else { + return strtr($subject, array_fill_keys($search, $replace)); + } + } + + return str_replace($search, $replace ?? '', $subject); + } + + + /** + * Perform a regular expression search and replace. + */ + public static function replaceRe(string $subject, string $pattern, string $replacement = ''): string + { + $res = preg_replace($pattern, $replacement, $subject); + if (preg_last_error() || $res === null) { + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + return $res; + } + + + /** + * The data: URI generator. + */ + public static function dataStream(string $data, ?string $type = null): string + { + if ($type === null) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + if ($finfo) { + $type = finfo_buffer($finfo, $data) ?: null; + } + } + return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data); + } + + + /** + * Converts newlines to HTML
tags. + */ + public static function breaklines(string|Stringable|null $s): Html + { + $s = htmlspecialchars((string) $s, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8'); + return new Html(nl2br($s, use_xhtml: false)); + } + + + /** + * Returns a part of string. + */ + public static function substring(string|Stringable|null $s, int $start, ?int $length = null): string + { + $s = (string) $s; + return match (true) { + extension_loaded('mbstring') => mb_substr($s, $start, $length, 'UTF-8'), + extension_loaded('iconv') => (string) iconv_substr($s, $start, $length, 'UTF-8'), + default => throw new Latte\RuntimeException("Filter |substr requires 'mbstring' or 'iconv' extension."), + }; + } + + + /** + * Truncates string to maximal length. + */ + public static function truncate(string|Stringable|null $s, int $length, string $append = "\u{2026}"): string + { + $s = (string) $s; + if (self::strLength($s) > $length) { + $length -= self::strLength($append); + if ($length < 1) { + return $append; + + } elseif (preg_match('#^.{1,' . $length . '}(?=[\s\x00-/:-@\[-`{-~])#us', $s, $matches)) { + return $matches[0] . $append; + + } else { + return self::substring($s, 0, $length) . $append; + } + } + + return $s; + } + + + /** + * Convert to lower case. + */ + public static function lower(string|Stringable|null $s): string + { + return mb_strtolower((string) $s, 'UTF-8'); + } + + + /** + * Convert to upper case. + */ + public static function upper(string|Stringable|null $s): string + { + return mb_strtoupper((string) $s, 'UTF-8'); + } + + + /** + * Convert first character to lower case. + */ + public static function firstLower(string|Stringable|null $s): string + { + $s = (string) $s; + return self::lower(self::substring($s, 0, 1)) . self::substring($s, 1); + } + + + /** + * Convert first character to upper case. + */ + public static function firstUpper(string|Stringable|null $s): string + { + $s = (string) $s; + return self::upper(self::substring($s, 0, 1)) . self::substring($s, 1); + } + + + /** + * Capitalize string. + */ + public static function capitalize(string|Stringable|null $s): string + { + return mb_convert_case((string) $s, MB_CASE_TITLE, 'UTF-8'); + } + + + /** + * Returns length of string or iterable. + * @param array|\Countable|\Traversable|string $val + */ + public static function length(array|\Countable|\Traversable|string $val): int + { + if (is_countable($val)) { + return count($val); + } elseif ($val instanceof \Traversable) { + return iterator_count($val); + } else { + return self::strLength($val); + } + } + + + private static function strLength(string $s): int + { + return match (true) { + extension_loaded('mbstring') => mb_strlen($s, 'UTF-8'), + extension_loaded('iconv') => (int) iconv_strlen($s, 'UTF-8'), + default => strlen(@utf8_decode($s)), // deprecated + }; + } + + + /** + * Strips whitespace. + */ + public static function trim(FilterInfo $info, string $s, string $charlist = " \t\n\r\0\x0B\u{A0}"): string + { + $charlist = preg_quote($charlist, '#'); + $s = preg_replace('#^[' . $charlist . ']+|[' . $charlist . ']+$#Du', '', $s); + if (preg_last_error() || $s === null) { + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + return $s; + } + + + /** + * Pad a string to a certain length with another string. + */ + public static function padLeft(string|Stringable|int|float|null $s, int $length, string $append = ' '): string + { + if ($append === '') { + throw new \InvalidArgumentException('Filter |padLeft: pad string cannot be empty.'); + } + + $s = (string) $s; + $length = max(0, $length - self::strLength($s)); + $l = self::strLength($append); + return str_repeat($append, (int) ($length / $l)) . self::substring($append, 0, $length % $l) . $s; + } + + + /** + * Pad a string to a certain length with another string. + */ + public static function padRight(string|Stringable|int|float|null $s, int $length, string $append = ' '): string + { + if ($append === '') { + throw new \InvalidArgumentException('Filter |padRight: pad string cannot be empty.'); + } + + $s = (string) $s; + $length = max(0, $length - self::strLength($s)); + $l = self::strLength($append); + return $s . str_repeat($append, (int) ($length / $l)) . self::substring($append, 0, $length % $l); + } + + + /** + * Reverses string or array. + * @template K + * @template V + * @param iterable|string $val + * @return ($val is string ? string : array) + */ + public static function reverse(string|iterable $val, bool $preserveKeys = false): string|array + { + return is_string($val) + ? (string) iconv('UTF-32LE', 'UTF-8', strrev((string) iconv('UTF-8', 'UTF-32BE', $val))) + : array_reverse(iterator_to_array($val, preserve_keys: $preserveKeys), $preserveKeys); + } + + + /** + * Returns the values from a single column in the input array. + * @param iterable $data + * @return mixed[] + */ + public static function column(iterable $data, string|int|null $columnKey, string|int|null $indexKey = null): array + { + return array_column(iterator_to_array($data, preserve_keys: false), $columnKey, $indexKey); + } + + + /** + * Chunks items by returning an array of arrays with the given number of items. + * @param iterable $list + * @return \Generator> + */ + public static function batch(iterable $list, int $length, mixed $rest = null): \Generator + { + $batch = []; + foreach ($list as $key => $value) { + $batch[$key] = $value; + if (count($batch) >= $length) { + yield $batch; + $batch = []; + } + } + + if ($batch) { + if ($rest !== null) { + while (count($batch) < $length) { + $batch[] = $rest; + } + } + + yield $batch; + } + } + + + /** + * Sorts elements using the comparison function and preserves the key association. + * @template K + * @template V + * @param iterable $data + * @param ?(\Closure(mixed, mixed): int) $comparison + * @param string|int|(\Closure(V): mixed)|null $by + * @param string|int|(\Closure(K): mixed)|bool $byKey + * @return iterable + */ + public function sort( + iterable $data, + ?\Closure $comparison = null, + string|int|\Closure|null $by = null, + string|int|\Closure|bool $byKey = false, + ): iterable + { + if ($byKey !== false) { + if ($by !== null) { + throw new \InvalidArgumentException('Filter |sort cannot use both $by and $byKey.'); + } + $by = $byKey === true ? null : $byKey; + } + + if ($comparison) { + } elseif ($this->locale === null) { + $comparison = fn($a, $b) => $a <=> $b; + } else { + $collator = new \Collator($this->locale); + $comparison = fn($a, $b) => is_string($a) && is_string($b) + ? $collator->compare($a, $b) + : $a <=> $b; + } + + $comparison = match (true) { + $by === null => $comparison, + $by instanceof \Closure => fn($a, $b) => $comparison($by($a), $by($b)), + default => fn($a, $b) => $comparison(is_array($a) ? $a[$by] : $a->$by, is_array($b) ? $b[$by] : $b->$by), + }; + + if (is_array($data)) { + $byKey ? uksort($data, $comparison) : uasort($data, $comparison); + return $data; + } + + $pairs = []; + foreach ($data as $key => $value) { + $pairs[] = [$key, $value]; + } + uasort($pairs, fn($a, $b) => $byKey ? $comparison($a[0], $b[0]) : $comparison($a[1], $b[1])); + + return new AuxiliaryIterator($pairs); + } + + + /** + * Groups elements by the element indices and preserves the key association and order. + * @template K + * @template V + * @param iterable $data + * @param string|int|(\Closure(V, K): mixed) $by + * @return iterable> + */ + public static function group(iterable $data, string|int|\Closure $by): iterable + { + $fn = $by instanceof \Closure ? $by : fn($a) => is_array($a) ? $a[$by] : $a->$by; + $keys = $groups = []; + $index = 0; + $prevKey = null; + + foreach ($data as $k => $v) { + $groupKey = $fn($v, $k); + if (!$groups || $prevKey !== $groupKey) { + $index = array_search($groupKey, $keys, strict: true); + if ($index === false) { + $index = count($keys); + $keys[$index] = $groupKey; + } + $prevKey = $groupKey; + } + $groups[$index][] = [$k, $v]; + } + + return new AuxiliaryIterator(array_map( + fn($key, $group) => [$key, new AuxiliaryIterator($group)], + $keys, + $groups, + )); + } + + + /** + * Filters elements according to a given $predicate. Maintains original keys. + * @template K + * @template V + * @param iterable $iterable + * @param callable(V, K, iterable): bool $predicate + * @return iterable + */ + public static function filter(iterable $iterable, callable $predicate): iterable + { + foreach ($iterable as $k => $v) { + if ($predicate($v, $k, $iterable)) { + yield $k => $v; + } + } + } + + + /** + * Transforms elements using the given $transformer. Maintains original keys. + * @template K + * @template V + * @template R + * @param iterable $iterable + * @param callable(V, K, iterable): R $transformer + * @return iterable + */ + public static function map(iterable $iterable, callable $transformer): iterable + { + foreach ($iterable as $k => $v) { + yield $k => $transformer($v, $k, $iterable); + } + } + + + /** + * Returns value clamped to the inclusive range of min and max. + */ + public static function clamp(int|float $value, int|float $min, int|float $max): int|float + { + if ($min > $max) { + throw new \InvalidArgumentException("Minimum ($min) is not less than maximum ($max)."); + } + + return min(max($value, $min), $max); + } + + + /** + * Generates URL-encoded query string + * @param string|array $data + */ + public static function query(string|array $data): string + { + return is_array($data) + ? http_build_query($data, '', '&') + : urlencode($data); + } + + + /** + * Is divisible by? + */ + public static function divisibleBy(int $value, int $by): bool + { + if ($by === 0) { + throw new \InvalidArgumentException('Cannot check divisibility by zero.'); + } + + return $value % $by === 0; + } + + + /** + * Is odd? + */ + public static function odd(int $value): bool + { + return $value % 2 !== 0; + } + + + /** + * Is even? + */ + public static function even(int $value): bool + { + return $value % 2 === 0; + } + + + /** + * Returns the first element in an array or character in a string, or null if none. + * @param string|iterable $value + * @return ($value is string ? string : mixed) + */ + public static function first(string|iterable $value): mixed + { + if (is_string($value)) { + return self::substring($value, 0, 1); + } + + foreach ($value as $item) { + return $item; + } + + return null; + } + + + /** + * Returns the last element in an iterable or character in a string, or null if none. + * @param string|iterable $value + * @return ($value is string ? string : mixed) + */ + public static function last(string|iterable $value): mixed + { + if (is_string($value)) { + return self::substring($value, -1); + } + + $value = iterator_to_array($value, preserve_keys: false); + return $value ? $value[array_key_last($value)] : null; + } + + + /** + * Extracts a slice of an array, string or iterator. + * @param string|iterable $value + * @return ($value is string ? string : ($value is array ? array : \Generator)) + */ + public static function slice( + string|iterable $value, + int $start, + ?int $length = null, + bool $preserveKeys = false, + ): string|array|\Generator + { + if (is_string($value)) { + return self::substring($value, $start, $length); + } elseif (is_array($value)) { + return array_slice($value, $start, $length, $preserveKeys); + } + + return (function () use ($value, $start, $length, $preserveKeys) { + $i = 0; + $count = 0; + foreach ($value as $key => $val) { + if ($i++ < $start) { + continue; + } + if ($length !== null && $count >= $length) { + break; + } + if ($preserveKeys) { + yield $key => $val; + } else { + yield $val; + } + $count++; + } + })(); + } + + + /** + * Rounds number to specified precision. + */ + public static function round(float $value, int $precision = 0): float + { + return round($value, $precision); + } + + + /** + * Rounds number down to specified precision. + */ + public static function floor(float $value, int $precision = 0): float + { + return floor($value * 10 ** $precision) / 10 ** $precision; + } + + + /** + * Rounds number up to specified precision. + */ + public static function ceil(float $value, int $precision = 0): float + { + return ceil($value * 10 ** $precision) / 10 ** $precision; + } + + + /** + * Picks random element/char. + * @param string|iterable $values + * @return ($values is string ? string : mixed) + */ + public static function random(string|iterable $values): mixed + { + $values = is_string($values) + ? self::explode($values) + : iterator_to_array($values, preserve_keys: false); + + return $values + ? $values[array_rand($values)] + : null; + } + + + /** + * Sanitizes string for use inside href attribute. + */ + public static function checkUrl(mixed $s): string + { + $s = $s instanceof Latte\Runtime\HtmlStringable + ? Latte\Runtime\HtmlHelpers::convertHtmlToText((string) $s) + : (string) $s; + + return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|(?:mailto|tel|sms):.+|[/?#].*|[^:]+)$~Di', $s) ? $s : ''; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php new file mode 100644 index 00000000..bdb59a79 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php @@ -0,0 +1,161 @@ +, array{AreaNode, ?Tag}, static> */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $tag->outputMode = $tag::OutputRemoveIndentation; + $stream = $tag->parser->stream; + $node = $tag->node = new static; + $name = null; + + if (!$stream->is('|', Token::End)) { + $layer = $tag->parser->tryConsumeTokenBeforeUnquotedString('local') + ? Template::LayerLocal + : $parser->blockLayer; + $stream->tryConsume('#'); + $name = $tag->parser->parseUnquotedStringOrExpression(); + $node->block = new Block($name, $layer, $tag); + + if (!$node->block->isDynamic()) { + $parser->checkBlockIsUnique($node->block); + } + } + + $node->modifier = $tag->parser->parseModifier(); + $noEscape = $node->modifier->removeFilter('noescape'); + if ($noEscape && !$node->modifier->filters) { + throw new CompileException('Filter |noescape is not expected here.', $tag->position); + } + $node->modifier->escape = $node->modifier->filters && !$noEscape; + + [$node->content, $endTag] = yield; + + if ($node->block && $endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if (!$this->block) { + return $this->printFilter($context); + + } elseif ($this->block->isDynamic()) { + return $this->printDynamic($context); + } + + return $this->printStatic($context); + } + + + private function printFilter(PrintContext $context): string + { + return $context->format( + <<<'XX' + ob_start(fn() => '') %line; + try { + (function () { extract(func_get_arg(0)); + %node + })(get_defined_vars()); + } finally { + $ʟ_fi = new LR\FilterInfo(%dump); + echo %modifyContent(ob_get_clean()); + } + + XX, + $this->position, + $this->content, + $context->getEscaper()->export(), + $this->modifier, + ); + } + + + private function printStatic(PrintContext $context): string + { + assert($this->block !== null); + $this->modifier->escape = $this->modifier->escape || $context->getEscaper()->getState() === Escaper::HtmlAttribute; + $context->addBlock($this->block); + $this->block->content = $this->content->print($context); // must be compiled after is added + + return $context->format( + '$this->renderBlock(%raw, get_defined_vars()' + . ($this->modifier->filters || $this->modifier->escape + ? ', function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }' + : '') + . ') %2.line;', + $context->ensureString($this->block->name, 'Block name'), + $this->modifier, + $this->position, + ); + } + + + private function printDynamic(PrintContext $context): string + { + assert($this->block !== null); + $context->addBlock($this->block); + $this->block->content = $this->content->print($context); // must be compiled after is added + $escaper = $context->getEscaper(); + $this->modifier->escape = $this->modifier->escape || $escaper->getState() === Escaper::HtmlAttribute; + + return $context->format( + '$this->addBlock($ʟ_nm = %raw, %dump, [$this->%raw(...)], %dump); + $this->renderBlock($ʟ_nm, get_defined_vars()' + . ($this->modifier->filters || $this->modifier->escape + ? ', function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }' + : '') + . ');', + $context->ensureString($this->block->name, 'Block name'), + $escaper->export(), + $this->block->method, + $this->block->layer, + $this->modifier, + ); + } + + + public function &getIterator(): \Generator + { + if ($this->block) { + yield $this->block->name; + } + yield $this->modifier; + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php new file mode 100644 index 00000000..d82afc5e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php @@ -0,0 +1,104 @@ +, array{AreaNode, ?Tag}, static> */ + public static function create(Tag $tag): \Generator + { + $tag->expectArguments(); + $variable = $tag->parser->parseExpression(); + if (!$variable->isWritable()) { + $text = ''; + $i = 0; + while ($token = $tag->parser->stream->tryPeek(--$i)) { + $text = $token->text . $text; + } + + throw new CompileException("It is not possible to write into '$text' in " . $tag->getNotation(), $tag->position); + } + $node = $tag->node = new static; + $node->variable = $variable; + $node->modifier = $tag->parser->parseModifier(); + [$node->content] = yield; + return $node; + } + + + public function print(PrintContext $context): string + { + $escaper = $context->getEscaper(); + $inHtmlText = $escaper->getState() === Escaper::HtmlText; + $res = $context->format( + <<<'XX' + ob_start(fn() => '') %line; + try { + %node + } finally { + $ʟ_tmp = %raw; + } + $ʟ_fi = new LR\FilterInfo(%dump); %node = %modifyContent($ʟ_tmp); + + XX, + $this->position, + $this->content, + $inHtmlText + ? 'ob_get_length() ? new LR\Html(ob_get_clean()) : ob_get_clean()' + : 'ob_get_clean()', + $escaper->export(), + $this->variable, + $this->modifier, + ); + + if ($inHtmlText && $this->modifier->filters) { + // filters returned a plain string, wrap it back unless they changed the content type, + // empty string stays plain like in the unfiltered branch + $res .= $context->format( + <<<'XX' + if ($ʟ_fi->contentType === %dump && %node !== '') %node = new LR\Html(%node); + + XX, + ContentType::Html, + $this->variable, + $this->variable, + $this->variable, + ); + } + + return $res . "\n"; + } + + + public function &getIterator(): \Generator + { + yield $this->variable; + yield $this->modifier; + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php new file mode 100644 index 00000000..2dac4309 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php @@ -0,0 +1,88 @@ +expectArguments(); + while (!$tag->parser->stream->consume()->isEnd()); + $type = trim($tag->parser->text); + + if (!$tag->isInHead() && !($tag->htmlElement?->is('script') && str_contains($type, 'html'))) { + throw new CompileException('{contentType} is allowed only in template header.', $tag->position); + } + + $node = new static; + $node->inScript = (bool) $tag->htmlElement; + $node->contentType = match (true) { + str_contains($type, 'html') => ContentType::Html, + str_contains($type, 'xml') => ContentType::Xml, + str_contains($type, 'javascript') => ContentType::JavaScript, + str_contains($type, 'css') => ContentType::Css, + str_contains($type, 'calendar') => ContentType::ICal, + default => ContentType::Text + }; + $parser->setContentType($node->contentType); + + if (strpos($type, '/') && !$tag->htmlElement) { + $node->mimeType = $type; + } + return $node; + } + + + public function print(PrintContext $context): string + { + if ($this->inScript) { + // replaces the context installed by the enclosing + + + +<?= $message[0] ?> + + + +
+
+

+ +

+ +

error

+
+
+ + diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php b/vendor/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php new file mode 100644 index 00000000..714b7f20 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php @@ -0,0 +1,309 @@ +>|null, + * aliases: array, + * scanDirs: list|false, + * scanComposer: bool, + * scanFilter: string, + * silentLinks: bool|null, + * } $config + */ +final class ApplicationExtension extends Nette\DI\CompilerExtension +{ + /** @var string[] */ + private readonly array $scanDirs; + private int $invalidLinkMode; + + /** @var array */ + private array $checked = []; + + + /** @param ?list $scanDirs */ + public function __construct( + private readonly bool $debugMode = false, + ?array $scanDirs = null, + private readonly ?string $tempDir = null, + private readonly ?Nette\Loaders\RobotLoader $robotLoader = null, + ) { + $this->scanDirs = (array) $scanDirs; + } + + + public function getConfigSchema(): Nette\Schema\Schema + { + return Expect::structure([ + 'debugger' => Expect::bool(), + 'errorPresenter' => Expect::anyOf( + Expect::structure([ + '4xx' => Expect::string('Nette:Error')->dynamic(), + '5xx' => Expect::string('Nette:Error')->dynamic(), + ])->castTo('array'), + Expect::string()->dynamic(), + )->firstIsDefault(), + 'catchExceptions' => Expect::bool(false)->dynamic(), + 'mapping' => Expect::anyOf( + Expect::string(), + Expect::arrayOf('string|array'), + ), + 'aliases' => Expect::arrayOf('string'), + 'scanDirs' => Expect::anyOf( + Expect::arrayOf('string')->default($this->scanDirs)->mergeDefaults(), + false, + )->firstIsDefault(), + 'scanComposer' => Expect::bool(class_exists(ClassLoader::class)), + 'scanFilter' => Expect::string('*Presenter'), + 'silentLinks' => Expect::bool(), + ]); + } + + + public function loadConfiguration(): void + { + $config = $this->config; + $builder = $this->getContainerBuilder(); + $builder->addExcludedClasses([UI\Presenter::class]); + + $this->invalidLinkMode = $this->debugMode + ? UI\Presenter::InvalidLinkTextual | ($config->silentLinks ? 0 : UI\Presenter::InvalidLinkWarning) + : UI\Presenter::InvalidLinkWarning; + + $application = $builder->addDefinition($this->prefix('application')) + ->setFactory(Nette\Application\Application::class); + if ($config->catchExceptions || !$this->debugMode) { + $application->addSetup('$error4xxPresenter', [is_array($config->errorPresenter) ? $config->errorPresenter['4xx'] : $config->errorPresenter]); + $application->addSetup('$errorPresenter', [is_array($config->errorPresenter) ? $config->errorPresenter['5xx'] : $config->errorPresenter]); + } + + $this->compiler->addExportedType(Nette\Application\Application::class); + + if ($this->debugMode && ($config->scanDirs || $this->robotLoader) && $this->tempDir) { + $touch = $this->tempDir . '/touch'; + Nette\Utils\FileSystem::createDir($this->tempDir); + $this->getContainerBuilder()->addDependency($touch); + } + + $presenterFactory = $builder->addDefinition($this->prefix('presenterFactory')) + ->setType(Nette\Application\IPresenterFactory::class) + ->setFactory(Nette\Application\PresenterFactory::class, [new Definitions\Statement( + Nette\Bridges\ApplicationDI\PresenterFactoryCallback::class, + [1 => $touch ?? null], + )]); + + if ($config->mapping) { + $presenterFactory->addSetup('setMapping', [ + is_string($config->mapping) ? ['*' => $config->mapping] : $config->mapping, + ]); + } + + if ($config->aliases) { + $presenterFactory->addSetup('setAliases', [$config->aliases]); + } + + $builder->addDefinition($this->prefix('linkGenerator')) + ->setFactory(Nette\Application\LinkGenerator::class, [ + 1 => new Definitions\Statement([new Definitions\Statement('@Nette\Http\IRequest::getUrl'), 'withoutUserInfo']), + ]); + + if ($this->name === 'application') { + $builder->addAlias('application', $this->prefix('application')); + $builder->addAlias('nette.presenterFactory', $this->prefix('presenterFactory')); + } + } + + + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + + if ($this->config->debugger ?? $builder->getByType(Tracy\BlueScreen::class)) { + $builder->getDefinition($this->prefix('application')) + ->addSetup([self::class, 'initializeBlueScreenPanel']); + } + + $all = []; + + foreach ($builder->findByType(Nette\Application\IPresenter::class) as $def) { + $all[(string) $def->getType()] = $def; + } + + $counter = 0; + foreach ($this->findPresenters() as $class) { + $this->checkPresenter($class); + if (empty($all[$class])) { + $all[$class] = $builder->addDefinition($this->prefix((string) ++$counter)) + ->setType($class); + } + } + + foreach ($all as $def) { + $def->addTag(Nette\DI\Extensions\InjectExtension::TagInject) + ->setAutowired(false); + + $type = $def->getType(); + assert($type !== null); + if (is_subclass_of($type, UI\Presenter::class) && $def instanceof Definitions\ServiceDefinition) { + $def->addSetup('$invalidLinkMode', [$this->invalidLinkMode]); + } + + $this->compiler->addExportedType($type); + } + } + + + /** @return list> */ + private function findPresenters(): array + { + $config = $this->getConfig(); + + if ($config->scanDirs) { + if (!class_exists(Nette\Loaders\RobotLoader::class)) { + throw new Nette\NotSupportedException("RobotLoader is required to find presenters, install package `nette/robot-loader` or disable option {$this->prefix('scanDirs')}: false"); + } + + $robot = new Nette\Loaders\RobotLoader; + $robot->addDirectory(...$config->scanDirs); + $robot->acceptFiles = [$config->scanFilter . '.php']; + if ($this->tempDir) { + $robot->setTempDirectory($this->tempDir); + $robot->refresh(); + } else { + $robot->rebuild(); + } + } elseif ($this->robotLoader && $config->scanDirs !== false) { + $robot = $this->robotLoader; + $robot->refresh(); + } + + $classes = []; + if (isset($robot)) { + $classes = array_keys($robot->getIndexedClasses()); + } + + if ($config->scanComposer) { + $rc = new \ReflectionClass(ClassLoader::class); + $classFile = dirname((string) $rc->getFileName()) . '/autoload_classmap.php'; + if (is_file($classFile)) { + $this->getContainerBuilder()->addDependency($classFile); + $classes = array_merge($classes, array_keys((fn($path) => require $path)($classFile))); + } + } + + $presenters = []; + foreach (array_unique($classes) as $class) { + if ( + is_string($class) + && fnmatch($config->scanFilter, $class) + && class_exists($class) + && is_subclass_of($class, Nette\Application\IPresenter::class) + && !(new \ReflectionClass($class))->isAbstract() + ) { + $presenters[] = $class; + } + } + + return $presenters; + } + + + /** @internal */ + public static function initializeBlueScreenPanel( + Tracy\BlueScreen $blueScreen, + Nette\Application\Application $application, + ): void + { + $blueScreen->addPanel(function (?\Throwable $e) use ($application, $blueScreen): ?array { + $dumper = $blueScreen->getDumper(); + return $e ? null : [ + 'tab' => 'Nette Application', + 'panel' => '

Requests

' . $dumper($application->getRequests()) + . '

Presenter

' . $dumper($application->getPresenter()), + ]; + }); + if ( + version_compare(Tracy\Debugger::Version, '2.9.0', '>=') + && version_compare(Tracy\Debugger::Version, '3.0', '<') + ) { + $blueScreen->addFileGenerator(self::generateNewPresenterFileContents(...)); + } + } + + + public static function generateNewPresenterFileContents(string $file, ?string $class = null): ?string + { + if (!$class || !str_ends_with($file, 'Presenter.php')) { + return null; + } + + $res = "checked[$class])) { + return; + } + $this->checked[$class] = true; + + $rc = new \ReflectionClass($class); + if ($rc->getParentClass()) { + $this->checkPresenter($rc->getParentClass()->getName()); + } + + foreach ($rc->getProperties() as $rp) { + if (($rp->getAttributes($attr = Attributes\Parameter::class) || $rp->getAttributes($attr = Attributes\Persistent::class)) + && (!$rp->isPublic() || $rp->isStatic() || $rp->isReadOnly()) + ) { + throw new Nette\InvalidStateException(sprintf('Property %s: attribute %s can be used only with public non-static property.', Reflection::toString($rp), $attr)); + } + } + + $re = $class::formatActionMethod('') . '.|' . $class::formatRenderMethod('') . '.|' . $class::formatSignalMethod('') . '.'; + foreach ($rc->getMethods() as $rm) { + if (preg_match("#^(?!handleInvalidLink)($re)#", $rm->getName()) && (!$rm->isPublic() || $rm->isStatic())) { + throw new Nette\InvalidStateException(sprintf('Method %s: this method must be public non-static.', Reflection::toString($rm))); + } elseif (preg_match('#^createComponent.#', $rm->getName()) && ($rm->isPrivate() || $rm->isStatic())) { + throw new Nette\InvalidStateException(sprintf('Method %s: this method must be non-private non-static.', Reflection::toString($rm))); + } elseif ($rm->getAttributes(Attributes\Requires::class, \ReflectionAttribute::IS_INSTANCEOF) + && !preg_match("#^$re|createComponent.#", $rm->getName()) + ) { + throw new Nette\InvalidStateException(sprintf('Method %s: attribute %s can be used only with action, render, handle or createComponent methods.', Reflection::toString($rm), Attributes\Requires::class)); + } elseif ($rm->getAttributes(Attributes\Deprecated::class) && !preg_match("#^$re#", $rm->getName())) { + throw new Nette\InvalidStateException(sprintf('Method %s: attribute %s can be used only with action, render or handle methods.', Reflection::toString($rm), Attributes\Deprecated::class)); + } + } + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php b/vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php new file mode 100644 index 00000000..3799bd58 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php @@ -0,0 +1,154 @@ +, + * extensions: array, + * templateClass: string|null, + * strictTypes: bool, + * strictParsing: bool, + * scopedLoopVariables: bool, + * dedent: bool, + * phpLinter: string|null, + * locale: string|null, + * } $config + */ +final class LatteExtension extends Nette\DI\CompilerExtension +{ + public function __construct( + private readonly string $tempDir, + private readonly bool $debugMode = false, + ) { + } + + + public function getConfigSchema(): Nette\Schema\Schema + { + return Expect::structure([ + 'debugger' => Expect::anyOf(true, false, 'all'), + 'extensions' => Expect::arrayOf('string|Nette\DI\Definitions\Statement'), + 'templateClass' => Expect::string(), + 'strictTypes' => Expect::bool(false), + 'strictParsing' => Expect::bool(false), + 'scopedLoopVariables' => Expect::bool(false), + 'dedent' => Expect::bool(false), + 'phpLinter' => Expect::string(), + 'locale' => Expect::string(), + ]); + } + + + public function loadConfiguration(): void + { + if (!class_exists(Latte\Engine::class)) { + return; + } + + $config = $this->config; + $builder = $this->getContainerBuilder(); + + $builder->addFactoryDefinition($this->prefix('latteFactory')) + ->setImplement(ApplicationLatte\LatteFactory::class) + ->getResultDefinition() + ->setFactory(Latte\Engine::class) + ->addSetup('setCacheDirectory', [$this->tempDir]) + ->addSetup('setAutoRefresh', [$this->debugMode]) + ->addSetup('setFeature', [Latte\Feature::StrictTypes, $config->strictTypes]) + ->addSetup('setFeature', [Latte\Feature::StrictParsing, $config->strictParsing]) + ->addSetup('setFeature', [Latte\Feature::ScopedLoopVariables, $config->scopedLoopVariables]) + ->addSetup('setFeature', [Latte\Feature::Dedent, $config->dedent]) + ->addSetup('enablePhpLinter', [$config->phpLinter]) + ->addSetup('setLocale', [$config->locale]) + ->addSetup('addExtension', [new Statement(ApplicationLatte\UIExtension::class, [$builder::literal('$control')])]); + + if ($builder->getByType(Nette\Caching\Storage::class)) { + $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class)); + } + if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) { + $this->addExtension(new Statement(Nette\Bridges\FormsLatte\FormsExtension::class)); + } + + foreach ($config->extensions as $extension) { + if ($extension === Latte\Essential\TranslatorExtension::class) { + $extension = new Statement($extension, [new Nette\DI\Definitions\Reference(Nette\Localization\Translator::class)]); + } + $this->addExtension($extension); + } + + $builder->addDefinition($this->prefix('templateFactory')) + ->setFactory(ApplicationLatte\TemplateFactory::class) + ->setArguments(['templateClass' => $config->templateClass]); + + if ($this->name === 'latte') { + $builder->addAlias('nette.latteFactory', $this->prefix('latteFactory')); + $builder->addAlias('nette.templateFactory', $this->prefix('templateFactory')); + } + } + + + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + + if ( + $this->debugMode + && ($this->config->debugger ?? $builder->getByType(Tracy\Bar::class)) + && class_exists(Latte\Bridges\Tracy\LattePanel::class) + ) { + $factory = $builder->getDefinition($this->prefix('templateFactory')); + $factory->addSetup([self::class, 'initLattePanel'], [$factory, 'all' => $this->config->debugger === 'all']); + } + } + + + public static function initLattePanel( + Nette\Application\UI\TemplateFactory $factory, + Tracy\Bar $bar, + bool $all = false, + ): void + { + if (!$factory instanceof ApplicationLatte\TemplateFactory) { + return; + } + + $factory->onCreate[] = function (ApplicationLatte\Template $template) use ($all) { + $control = $template->getLatte()->getProviders()['uiControl'] ?? null; + if ($all || $control instanceof Nette\Application\UI\Presenter) { + $name = $all && $control ? (new \ReflectionObject($control))->getShortName() : ''; + $template->getLatte()->addExtension(new Latte\Bridges\Tracy\TracyExtension($name)); + } + }; + } + + + public function addExtension(Statement|string $extension): void + { + $extension = is_string($extension) + ? new Statement($extension) + : $extension; + + $builder = $this->getContainerBuilder(); + $builder->getDefinition($this->prefix('latteFactory')) + ->getResultDefinition() + ->addSetup('addExtension', [$extension]); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php b/vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php new file mode 100644 index 00000000..be17e63f --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php @@ -0,0 +1,53 @@ + $class */ + public function __invoke(string $class): Nette\Application\IPresenter + { + $services = $this->container->findByType($class); + if (count($services) > 1) { + $services = array_values(array_filter($services, fn($service) => $this->container->getServiceType($service) === $class)); + if (count($services) > 1) { + throw new Nette\Application\InvalidPresenterException("Multiple services of type $class found: " . implode(', ', $services) . '.'); + } + } + + if (count($services) === 1) { + $presenter = $this->container->createService($services[0]); + assert($presenter instanceof Nette\Application\IPresenter); + return $presenter; + } + + if ($this->touchToRefresh && class_exists($class)) { + touch($this->touchToRefresh); + echo 'Class ' . htmlspecialchars($class) . ' was not found in DI container.

If you just created this presenter, it should be enough to refresh the page. It will happen automatically in 5 seconds.

Otherwise, please check the configuration of your DI container.'; + header('Refresh: 5'); + exit; + } + + throw new Nette\Application\InvalidPresenterException("No services of type $class found."); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php b/vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php new file mode 100644 index 00000000..7ceae3a0 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php @@ -0,0 +1,108 @@ +, + * cache: bool, + * } $config + */ +final class RoutingExtension extends Nette\DI\CompilerExtension +{ + public function __construct( + private readonly bool $debugMode = false, + ) { + } + + + public function getConfigSchema(): Nette\Schema\Schema + { + return Expect::structure([ + 'debugger' => Expect::bool(), + 'routes' => Expect::arrayOf('string'), + 'cache' => Expect::bool(false), + ]); + } + + + public function loadConfiguration(): void + { + if (!$this->config->routes) { + return; + } + + $builder = $this->getContainerBuilder(); + + $router = $builder->addDefinition($this->prefix('router')) + ->setFactory(Nette\Application\Routers\RouteList::class); + + foreach ($this->config->routes as $mask => $action) { + $router->addSetup('$service->addRoute(?, ?)', [$mask, $action]); + } + + if ($this->name === 'routing') { + $builder->addAlias('router', $this->prefix('router')); + } + } + + + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + + if ( + $this->debugMode && + ($this->config->debugger ?? $builder->getByType(Tracy\Bar::class)) && + ($name = $builder->getByType(Nette\Application\Application::class)) && + ($application = $builder->getDefinition($name)) instanceof Definitions\ServiceDefinition + ) { + $application->addSetup('@Tracy\Bar::addPanel', [ + new Definitions\Statement(Nette\Bridges\ApplicationTracy\RoutingPanel::class), + ]); + } + + if (!$builder->getByType(Nette\Routing\Router::class)) { + $builder->addDefinition($this->prefix('router')) + ->setType(Nette\Routing\Router::class) + ->setFactory(Nette\Routing\SimpleRouter::class); + $builder->addAlias('router', $this->prefix('router')); + } + } + + + public function afterCompile(Nette\PhpGenerator\ClassType $class): void + { + if ($this->config->cache) { + $builder = $this->getContainerBuilder(); + $def = $builder->getDefinitionByType(Nette\Routing\Router::class); + $method = $class->getMethod(Nette\DI\Container::getMethodName((string) $def->getName())); + try { + $router = eval($method->getBody()); + if ($router instanceof Nette\Application\Routers\RouteList) { + $router->warmupCache(); + } + + $s = serialize($router); + } catch (\Throwable $e) { + throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e); + } + + $method->setBody('return unserialize(?);', [$s]); + } + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php b/vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php new file mode 100644 index 00000000..88948e5a --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php @@ -0,0 +1,51 @@ +$name = $value; + return $this; + } + + + /** + * Sets all parameters. + * @param array $params + */ + public function setParameters(array $params): static + { + return Nette\Utils\Arrays::toObject($params, $this); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php b/vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php new file mode 100644 index 00000000..c020f876 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php @@ -0,0 +1,20 @@ +outputMode = $tag::OutputRemoveIndentation; + $tag->expectArguments(); + $stream = $tag->parser->stream; + $node = new static; + $node->name = $tag->parser->parseUnquotedStringOrExpression(colon: false); + if ($stream->tryConsume(':')) { + $node->method = $tag->parser->parseExpression(); + } + + $stream->tryConsume(','); + $start = $stream->getIndex(); + $node->args = $tag->parser->parseArguments(); + $start -= $stream->getIndex(); + $depth = 0; + $wrap = null; + for (; $start < 0; $start++) { + $token = $stream->peek($start); + match (true) { + $token->is('[') => $depth++, + $token->is(']') => $depth--, + $token->is('=>') && !$depth => $wrap = true, + default => null, + }; + } + + if ($wrap) { + $node->args = new ArrayNode([new ArrayItemNode($node->args)]); + } + + $modifier = $tag->parser->parseModifier(); + $node->escape = $modifier->removeFilter('noescape') ? false : null; + if ($modifier->filters) { + throw new Latte\CompileException('Only modifier |noescape is allowed here.', reset($modifier->filters)->position); + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if ($this->escape === null && $context->getEscaper()->getState() !== Escaper::HtmlText) { + $this->escape = true; + } + + $method = match (true) { + !$this->method => 'render', + $this->method instanceof StringNode && Strings::match($this->method->value, '#^\w*$#D') => 'render' . ucfirst($this->method->value), + default => "{'render' . " . $this->method->print($context) . '}', + }; + + $fetchCode = $context->format( + $this->name instanceof StringNode + ? '$ʟ_tmp = $this->global->uiControl->getComponent(%node);' + : 'if (!is_object($ʟ_tmp = %node)) $ʟ_tmp = $this->global->uiControl->getComponent($ʟ_tmp);', + $this->name, + ); + + if ($this->escape) { + return $context->format( + <<<'XX' + %raw + if ($ʟ_tmp instanceof Nette\Application\UI\Renderable) $ʟ_tmp->redrawControl(null, false); + ob_start(fn() => ''); + $ʟ_tmp->%raw(%args) %line; + $ʟ_fi = new LR\FilterInfo(%dump); echo %modifyContent(ob_get_clean()); + + + XX, + $fetchCode, + $method, + $this->args, + $this->position, + Latte\ContentType::Html, + new ModifierNode([], $this->escape), + ); + + } else { + return $context->format( + <<<'XX' + %raw + if ($ʟ_tmp instanceof Nette\Application\UI\Renderable) $ʟ_tmp->redrawControl(null, false); + $ʟ_tmp->%raw(%args) %line; + + + XX, + $fetchCode, + $method, + $this->args, + $this->position, + ); + } + } + + + public function &getIterator(): \Generator + { + yield $this->name; + if ($this->method) { + yield $this->method; + } + yield $this->args; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php new file mode 100644 index 00000000..7e8c4828 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php @@ -0,0 +1,83 @@ +expectArguments(); + if (!$tag->isInHead()) { + throw new CompileException("{{$tag->name}} must be placed in template head.", $tag->position); + } + + $node = new static; + $node->base = $tag->parser->parseUnquotedStringOrExpression(); + return $node; + } + + + public function print(PrintContext $context): string + { + return ''; + } + + + public function &getIterator(): \Generator + { + yield $this->base; + } + + + public static function applyLinkBasePass(TemplateNode $node): void + { + $found = NodeHelpers::findFirst($node, fn(Node $node) => $node instanceof self); + if (!$found instanceof self) { + return; + } + + $base = $found->base; + (new NodeTraverser)->traverse($node, function (Node $link) use ($base) { + if ($link instanceof LinkNode) { + if ($link->destination instanceof StringNode && $base instanceof StringNode) { + $link->destination->value = LinkGenerator::applyBase($link->destination->value, $base->value); + } else { + $origDestination = $link->destination; + $link->destination = new AuxiliaryNode( + fn(PrintContext $context) => $context->format( + LinkGenerator::class . '::applyBase(%node, %node)', + $origDestination, + $base, + ), + ); + } + } + }); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php new file mode 100644 index 00000000..212dea42 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php @@ -0,0 +1,91 @@ +outputMode = $tag::OutputKeepIndentation; + $tag->expectArguments(); + $node = new static; + $node->destination = $tag->parser->parseUnquotedStringOrExpression(); + $tag->parser->stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + $node->modifier = $tag->parser->parseModifier(); + $node->modifier->escape = true; + $node->mode = $tag->name; + + if ($tag->isNAttribute()) { + assert($tag->htmlElement !== null); + // move at the beginning + $node->position = $tag->position; + array_unshift($tag->htmlElement->attributes->children, $node); + return null; + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if ($this->mode === 'href') { + $context->beginEscape()->enterHtmlAttribute(); + $res = $context->format( + <<<'XX' + echo ' href="'; echo %modify($this->global->uiControl->link(%node, %node?)) %line; echo '"'; + XX, + $this->modifier, + $this->destination, + $this->args, + $this->position, + ); + $context->restoreEscape(); + return $res; + } + + return $context->format( + 'echo %modify(' + . ($this->mode === 'plink' ? '$this->global->uiPresenter' : '$this->global->uiControl') + . '->link(%node, %node?)) %line;', + $this->modifier, + $this->destination, + $this->args, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->destination; + yield $this->args; + yield $this->modifier; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php new file mode 100644 index 00000000..2c00167d --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php @@ -0,0 +1,36 @@ + + * Outputs CSP nonce attribute for inline scripts and styles. + */ +class NNonceNode extends StatementNode +{ + public static function create(): static + { + return new static; + } + + + public function print(PrintContext $context): string + { + return 'echo $this->global->uiNonce ? " nonce=\"{$this->global->uiNonce}\"" : "";'; + } + + + public function &getIterator(): \Generator + { + false && yield; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php new file mode 100644 index 00000000..6dd36228 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php @@ -0,0 +1,87 @@ +, array{AreaNode, ?Tag}, static> */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $node = $tag->node = new static; + $name = $tag->parser->parseUnquotedStringOrExpression(); + if ( + $name instanceof Expression\ClassConstantFetchNode + && $name->class instanceof Php\NameNode + && $name->name instanceof Php\IdentifierNode + ) { + $name = new Scalar\StringNode(constant($name->class . '::' . $name->name), $name->position); + } + $node->block = new Block($name, Template::LayerSnippet, $tag); + $parser->checkBlockIsUnique($node->block); + [$node->content, $endTag] = yield; + if ($endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + return $node; + } + + + public function print(PrintContext $context): string + { + $context->addBlock($this->block); + $this->block->content = $context->format( + <<<'XX' + $this->global->snippetDriver->enter(%node, %dump); + try { + %node + } finally { + $this->global->snippetDriver->leave(); + } + + XX, + $this->block->name, + SnippetRuntime::TypeArea, + $this->content, + ); + + return $context->format( + '$this->renderBlock(%node, [], null, %dump) %line;', + $this->block->name, + Template::LayerSnippet, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->block->name; + yield $this->content; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php new file mode 100644 index 00000000..3adbd140 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php @@ -0,0 +1,169 @@ +, array{AreaNode, ?Tag}, static> */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $tag->outputMode = $tag::OutputKeepIndentation; + + $node = $tag->node = new static; + $node->htmlElement = $tag->isNAttribute() ? $tag->htmlElement : null; + + if ($tag->parser->isEnd()) { + $name = null; + $node->block = new Block(new Scalar\StringNode(''), Template::LayerSnippet, $tag); + } else { + $name = $tag->parser->parseUnquotedStringOrExpression(); + if ( + $name instanceof Expression\ClassConstantFetchNode + && $name->class instanceof Php\NameNode + && $name->name instanceof Php\IdentifierNode + ) { + $name = new Scalar\StringNode(constant($name->class . '::' . $name->name), $name->position); + } + $node->block = new Block($name, Template::LayerSnippet, $tag); + if (!$node->block->isDynamic()) { + $parser->checkBlockIsUnique($node->block); + } + } + + if ($tag->isNAttribute()) { + assert($tag->htmlElement !== null); + if ($tag->prefix !== $tag::PrefixNone) { + throw new CompileException("Use n:snippet instead of {$tag->getNotation()}", $tag->position); + + } elseif ($tag->htmlElement->getAttribute(self::$snippetAttribute)) { + throw new CompileException('Cannot combine HTML attribute ' . self::$snippetAttribute . ' with n:snippet.', $tag->position); + + } elseif (isset($tag->htmlElement->nAttributes['ifcontent'])) { + throw new CompileException('Cannot combine n:ifcontent with n:snippet.', $tag->position); + + } elseif (isset($tag->htmlElement->nAttributes['foreach'])) { + throw new CompileException('Combination of n:snippet with n:foreach is invalid, use n:inner-foreach.', $tag->position); + } + + $tag->replaceNAttribute(new AuxiliaryNode( + fn(PrintContext $context) => "echo ' " . $node->printAttribute($context) . "';", + )); + } + + [$node->content, $endTag] = yield; + if ($endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if (!$this->block->isDynamic()) { + $context->addBlock($this->block); + } + + if ($this->htmlElement) { + $inner = $this->htmlElement->content; + try { + $this->htmlElement->content = new AuxiliaryNode(fn() => $this->printContent($context, $inner)); + return $this->content->print($context); + } finally { + $this->htmlElement->content = $inner; + } + } else { + return <<printAttribute($context)}>'; + {$this->printContent($context, $this->content)} + echo ''; + XX; + } + } + + + private function printContent(PrintContext $context, AreaNode $inner): string + { + $dynamic = $this->block->isDynamic(); + $res = $context->format( + <<<'XX' + $this->global->snippetDriver->enter(%node, %dump) %line; + try { + %node + } finally { + $this->global->snippetDriver->leave(); + } + + XX, + $dynamic ? new AuxiliaryNode(fn() => '$ʟ_nm') : $this->block->name, + $dynamic ? SnippetRuntime::TypeDynamic : SnippetRuntime::TypeStatic, + $this->position, + $inner, + ); + + if ($dynamic) { + return $res; + } + + $this->block->content = $res; + return $context->format( + '$this->renderBlock(%node, [], null, %dump) %line;', + $this->block->name, + Template::LayerSnippet, + $this->position, + ); + } + + + private function printAttribute(PrintContext $context): string + { + return $context->format( + <<<'XX' + %raw="', htmlspecialchars($this->global->snippetDriver->getHtmlId(%node)), '" + XX, + self::$snippetAttribute, + $this->block->isDynamic() + ? new Expression\AssignNode(new Expression\VariableNode('ʟ_nm'), $this->block->name) + : $this->block->name, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->block->name; + yield $this->content; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php new file mode 100644 index 00000000..6958684e --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php @@ -0,0 +1,59 @@ +getParameters(), ' . PhpHelpers::dump($this->template ?? Template::class) . '); exit;'; + } + + + /** @param array $params */ + public static function printClass(array $params, string $parentClass): void + { + $bp = new Latte\Essential\Blueprint; + $control = $params['control'] ?? $params['presenter'] ?? null; + $name = 'Template'; + if ($control instanceof UI\Control) { + $name = preg_replace('#(Control|Presenter)$#', '', $control::class) . 'Template'; + unset($params[$control instanceof UI\Presenter ? 'control' : 'presenter']); + } + $class = $bp->generateTemplateClass($params, $name, $parentClass); + $code = (string) $class->getNamespace(); + + $bp->printBegin(); + $bp->printCode($code); + + if ($control instanceof UI\Control) { + $controlFile = (new \ReflectionClass($control))->getFileName() + ?: throw new \LogicException('Cannot determine file of class ' . $control::class . '.'); + $file = dirname($controlFile) . '/' . $class->getName() . '.php'; + if (file_exists($file)) { + echo "unsaved, file {$bp->clickableFile($file)} already exists"; + } else { + echo "saved to file {$bp->clickableFile($file)}"; + file_put_contents($file, "printEnd(); + exit; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php b/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php new file mode 100644 index 00000000..c1c51d90 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php @@ -0,0 +1,141 @@ + */ + private array $stack = []; + private int $nestingLevel = 0; + private bool $renderingSnippets = false; + private \stdClass $payload; + + + public function __construct( + private readonly Control $control, + ) { + } + + + public function enter(string $name, string $type): void + { + if (!$this->renderingSnippets) { + if ($type === self::TypeDynamic && $this->nestingLevel === 0) { + trigger_error('Dynamic snippets are allowed only inside static snippet/snippetArea.', E_USER_WARNING); + } + + $this->nestingLevel++; + return; + } + + $obStarted = false; + if ( + ($this->nestingLevel === 0 && $this->control->isControlInvalid($name)) + || ($type === self::TypeDynamic && ($previous = end($this->stack)) && $previous[1] === true) + ) { + ob_start(fn() => ''); + $this->nestingLevel = $type === self::TypeArea ? 0 : 1; + $obStarted = true; + } elseif ($this->nestingLevel > 0) { + $this->nestingLevel++; + } + + $this->stack[] = [$name, $obStarted]; + if ($name !== '') { + $this->control->redrawControl($name, redraw: false); + } + } + + + public function leave(): void + { + if (!$this->renderingSnippets) { + $this->nestingLevel--; + return; + } + + [$name, $obStarted] = array_pop($this->stack); + if ($this->nestingLevel > 0 && --$this->nestingLevel === 0) { + $content = ob_get_clean(); + $this->payload ??= $this->control->getPresenter()->getPayload(); + $this->payload->snippets[$this->control->getSnippetId($name)] = $content; + + } elseif ($obStarted) { // dynamic snippet wrapper or snippet area + ob_end_clean(); + } + } + + + public function getHtmlId(string $name): string + { + return $this->control->getSnippetId($name); + } + + + /** + * @param array $blocks + * @param mixed[] $params + */ + public function renderSnippets(array $blocks, array $params): bool + { + if ($this->renderingSnippets || !$this->control->snippetMode) { + return false; + } + + $this->renderingSnippets = true; + $this->control->snippetMode = false; + foreach ($blocks as $name => $block) { + if (!$this->control->isControlInvalid($name)) { + continue; + } + + $function = reset($block->functions); + $function($params); + } + + $this->control->snippetMode = true; + $this->renderChildren(); + + $this->renderingSnippets = false; + return true; + } + + + private function renderChildren(): void + { + $queue = [$this->control]; + do { + foreach (array_shift($queue)->getComponents() as $child) { + if ($child instanceof Control) { + if ($child->isControlInvalid()) { + $child->snippetMode = true; + $child->render(); + $child->snippetMode = false; + } + } elseif ($child instanceof Nette\ComponentModel\IContainer) { + $queue[] = $child; + } + } + } while ($queue); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Template.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Template.php new file mode 100644 index 00000000..32378c9e --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Template.php @@ -0,0 +1,145 @@ +latte; + } + + + /** + * Renders template to output. + * @param array $params + */ + public function render(?string $file = null, array $params = []): void + { + Nette\Utils\Arrays::toObject($params, $this); + $file ??= $this->file ?? throw new Nette\InvalidStateException('Template file name was not set.'); + $this->latte->render($file, $this); + } + + + /** + * Renders template to string. + * @param array $params + */ + public function renderToString(?string $file = null, array $params = []): string + { + Nette\Utils\Arrays::toObject($params, $this); + $file ??= $this->file ?? throw new Nette\InvalidStateException('Template file name was not set.'); + return $this->latte->renderToString($file, $this); + } + + + /** + * Renders template to string. + */ + public function __toString(): string + { + $file = $this->file ?? throw new Nette\InvalidStateException('Template file name was not set.'); + return $this->latte->renderToString($file, $this->getParameters()); + } + + + /********************* template filters & helpers ****************d*g**/ + + + /** + * Registers run-time filter. + */ + public function addFilter(string $name, callable $callback): static + { + $this->latte->addFilter($name, $callback); + return $this; + } + + + /** + * Registers run-time function. + */ + public function addFunction(string $name, callable $callback): static + { + $this->latte->addFunction($name, $callback); + return $this; + } + + + /** + * Sets translate adapter. + */ + public function setTranslator(?Nette\Localization\Translator $translator, ?string $language = null): static + { + $this->latte->addExtension(new Latte\Essential\TranslatorExtension($translator, $language)); + return $this; + } + + + /********************* template parameters ****************d*g**/ + + + /** + * Sets the path to the template file. + */ + public function setFile(string $file): static + { + $this->file = $file; + return $this; + } + + + final public function getFile(): ?string + { + return $this->file; + } + + + /** + * Returns array of all parameters. + * @return array + */ + final public function getParameters(): array + { + $res = []; + foreach ((new \ReflectionObject($this))->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { + if ($prop->isInitialized($this)) { + $res[$prop->getName()] = $prop->getValue($this); + } + } + + return $res; + } + + + /** + * Prevents unserialization. + * @param array $_ + */ + final public function __unserialize(array $_) + { + throw new Nette\NotImplementedException('Object unserialization is not supported by class ' . static::class); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php b/vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php new file mode 100644 index 00000000..e51ba4db --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -0,0 +1,90 @@ + Occurs when a new template is created */ + public array $onCreate = []; + private string $templateClass; + + + /** @param ?string $templateClass */ + public function __construct( + private readonly LatteFactory $latteFactory, + private readonly ?Nette\Http\IRequest $httpRequest = null, + private readonly ?Nette\Security\User $user = null, + $templateClass = null, + ) { + if ($templateClass && (!class_exists($templateClass) || !is_a($templateClass, Template::class, allow_string: true))) { + throw new Nette\InvalidArgumentException("Class $templateClass does not implement " . Template::class . ' or it does not exist.'); + } + + $this->templateClass = $templateClass ?? DefaultTemplate::class; + } + + + /** + * @template T of Template + * @param ?class-string $class + * @return ($class is null ? Template : T) + */ + public function createTemplate(?UI\Control $control = null, ?string $class = null): UI\Template + { + $class ??= $this->templateClass; + if (!is_a($class, Template::class, allow_string: true)) { + throw new Nette\InvalidArgumentException("Class $class does not implement " . Template::class . ' or it does not exist.'); + } + + $latte = $this->latteFactory->create($control); + $template = new $class($latte); + $this->injectDefaultVariables($template, $control); + + Nette\Utils\Arrays::invoke($this->onCreate, $template); + + return $template; + } + + + private function injectDefaultVariables(Template $template, ?UI\Control $control): void + { + $presenter = $control?->getPresenter(throw: false); + $baseUrl = $this->httpRequest + ? rtrim($this->httpRequest->getUrl()->withoutUserInfo()->getBaseUrl(), '/') + : null; + $flashes = $presenter instanceof UI\Presenter && $presenter->hasFlashSession() + ? (array) $presenter->getFlashSession()->get($control->getParameterId('flash')) + : []; + + $vars = [ + 'user' => $this->user, + 'baseUrl' => $baseUrl, + 'basePath' => $baseUrl ? preg_replace('#https?://[^/]+#A', '', $baseUrl) : null, + 'flashes' => $flashes, + 'control' => $control, + 'presenter' => $presenter, + ]; + + foreach ($vars as $key => $value) { + if ($value !== null && property_exists($template, $key)) { + try { + $template->$key = $value; + } catch (\TypeError) { + } + } + } + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php b/vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php new file mode 100644 index 00000000..f8d19776 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php @@ -0,0 +1,138 @@ +control?->getPresenter(throw: false); + return [ + 'modifyDate' => fn($time, $delta, $unit = null) => $time + ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) + : null, + ] + ($presenter ? [ + 'absoluteUrl' => fn(\Stringable|string|null $link): ?string => $link === null + ? null + : $presenter->getHttpRequest()->getUrl()->resolve((string) $link)->getAbsoluteUrl(), + ] : []); + } + + + public function getFunctions(): array + { + if ($presenter = $this->control?->getPresenter(throw: false)) { + return [ + 'isLinkCurrent' => $presenter->isLinkCurrent(...), + 'isModuleCurrent' => $presenter->isModuleCurrent(...), + ]; + } + return []; + } + + + public function getProviders(): array + { + $presenter = $this->control?->getPresenter(throw: false); + $httpResponse = $presenter?->getHttpResponse(); + return [ + 'coreParentFinder' => $this->findLayoutTemplate(...), + 'uiControl' => $this->control, + 'uiPresenter' => $presenter, + 'snippetDriver' => $this->control ? new SnippetRuntime($this->control) : null, + 'uiNonce' => $httpResponse ? $this->findNonce($httpResponse) : null, + ]; + } + + + public function getTags(): array + { + return [ + 'n:href' => Nodes\LinkNode::create(...), + 'n:nonce' => Nodes\NNonceNode::create(...), + 'control' => Nodes\ControlNode::create(...), + 'plink' => Nodes\LinkNode::create(...), + 'link' => Nodes\LinkNode::create(...), + 'linkBase' => Nodes\LinkBaseNode::create(...), + 'templatePrint' => Nodes\TemplatePrintNode::create(...), + 'snippet' => Nodes\SnippetNode::create(...), + 'snippetArea' => Nodes\SnippetAreaNode::create(...), + 'layout' => $this->createExtendsNode(...), + 'extends' => $this->createExtendsNode(...), + ]; + } + + + public function getPasses(): array + { + return [ + 'snippetRendering' => $this->snippetRenderingPass(...), + 'applyLinkBase' => Nodes\LinkBaseNode::applyLinkBasePass(...), + ]; + } + + + /** + * Render snippets instead of template in snippet-mode. + */ + public function snippetRenderingPass(TemplateNode $templateNode): void + { + array_unshift($templateNode->main->children, new Latte\Compiler\Nodes\AuxiliaryNode(fn() => <<<'XX' + if ($this->global->snippetDriver?->renderSnippets($this->blocks[self::LayerSnippet], $this->params)) { return; } + + + XX)); + } + + + public static function findLayoutTemplate(Latte\Runtime\Template $template): ?string + { + $presenter = $template->global->uiControl ?? null; + return $presenter instanceof UI\Presenter && !empty($template::Blocks[$template::LayerTop]) + ? $presenter->findLayoutTemplateFile() + : null; + } + + + private function findNonce(Nette\Http\IResponse $httpResponse): ?string + { + $header = $httpResponse->getHeader('Content-Security-Policy') + ?: $httpResponse->getHeader('Content-Security-Policy-Report-Only'); + return preg_match('#\s\'nonce-([\w+/]+=*)\'#', (string) $header, $m) ? $m[1] : null; + } + + + public static function createExtendsNode(Tag $tag): ExtendsNode + { + $auto = $tag->parser->stream->is('auto'); + $node = ExtendsNode::create($tag); + if ($auto) { + $node->extends = new AuxiliaryNode(fn() => '($this->getReferringTemplate() ? null : $this->global->uiPresenter->findLayoutTemplateFile())'); + } + return $node; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php b/vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php new file mode 100644 index 00000000..6ada0036 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php @@ -0,0 +1,153 @@ +} */ + private array $routes; + + /** @var ?array */ + private ?array $matched = null; + + + public function __construct( + private readonly Routing\Router $router, + private readonly Nette\Http\IRequest $httpRequest, + private readonly Nette\Application\IPresenterFactory $presenterFactory, + ) { + } + + + /** + * Renders tab. + */ + public function getTab(): string + { + $this->routes = $this->analyse( + $this->router instanceof Routing\RouteList + ? $this->router + : (new Routing\RouteList)->add($this->router), + $this->httpRequest, + ); + return Nette\Utils\Helpers::capture(function () { + $matched = $this->matched; + require __DIR__ . '/dist/tab.phtml'; + }); + } + + + /** + * Renders panel. + */ + public function getPanel(): string + { + return Nette\Utils\Helpers::capture(function () { + $matched = $this->matched; + $routes = $this->routes; + $source = $this->matched ? $this->findSource() : null; + $url = $this->httpRequest->getUrl(); + $method = $this->httpRequest->getMethod(); + require __DIR__ . '/dist/panel.phtml'; + }); + } + + + /** @return array{path: string, domain: ?string, module: string, routes: array} */ + private function analyse(Routing\RouteList $router, ?Nette\Http\IRequest $httpRequest): array + { + $res = [ + 'path' => $router->getPath(), + 'domain' => $router->getDomain(), + 'module' => ($router instanceof Nette\Application\Routers\RouteList ? $router->getModule() : ''), + 'routes' => [], + ]; + $httpRequest = $httpRequest + ? (fn() => $this->prepareRequest($httpRequest))->bindTo($router, Routing\RouteList::class)() + : null; + $flags = $router->getFlags(); + + foreach ($router->getRouters() as $i => $innerRouter) { + if ($innerRouter instanceof Routing\RouteList) { + $res['routes'][] = $this->analyse($innerRouter, $httpRequest); + continue; + } + + $matched = $flags[$i] & $router::ONE_WAY ? 'oneway' : 'no'; + $params = $e = null; + try { + if ( + $httpRequest + && ($params = $innerRouter->match($httpRequest)) !== null + && ($params = (fn() => $this->completeParameters($params))->bindTo($router, Routing\RouteList::class)()) !== null + ) { + $matched = 'may'; + if ($this->matched === null) { + $this->matched = $params; + $matched = 'yes'; + } + } + } catch (\Throwable $e) { + $matched = 'error'; + } + + $res['routes'][] = (object) [ + 'matched' => $matched, + 'class' => $innerRouter::class, + 'defaults' => $innerRouter instanceof Routing\Route || $innerRouter instanceof Routing\SimpleRouter ? $innerRouter->getDefaults() : [], + 'mask' => $innerRouter instanceof Routing\Route ? $innerRouter->getMask() : null, + 'params' => $params, + 'error' => $e, + ]; + } + return $res; + } + + + /** @return \ReflectionClass|\ReflectionMethod|string|null */ + private function findSource(): \ReflectionClass|\ReflectionMethod|string|null + { + $params = $this->matched; + $presenter = $params['presenter'] ?? ''; + if (!is_string($presenter)) { + return null; + } + try { + $class = $this->presenterFactory->getPresenterClass($presenter); + } catch (Nette\Application\InvalidPresenterException) { + if ($this->presenterFactory instanceof Nette\Application\PresenterFactory) { + return $this->presenterFactory->formatPresenterClass($presenter); + } + return null; + } + + if (is_a($class, Nette\Application\UI\Presenter::class, allow_string: true)) { + $rc = $class::getReflection(); + if (isset($params[Presenter::SignalKey]) && is_string($params[Presenter::SignalKey])) { + return $rc->getSignalMethod($params[Presenter::SignalKey]); + } elseif (isset($params[Presenter::ActionKey]) + && is_string($params[Presenter::ActionKey]) + && ($method = $rc->getActionRenderMethod($params[Presenter::ActionKey])) + ) { + return $method; + } + } + + return new \ReflectionClass($class); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml new file mode 100644 index 00000000..724c4db4 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml @@ -0,0 +1,286 @@ + $matched */ +/** @var array{path:string,domain:?string,module:string,routes:array} $routes */ +/** @var \ReflectionClass|\ReflectionMethod|string|null $source */ +/** @var Nette\Http\UrlScript $url */ +/** @var string $method */ +use Nette\Application\UI\Presenter; +use Tracy\Dumper; +echo ' + + +

+'; +if ($matched === null) /* pos 88:2 */ { + echo ' no route +'; +} elseif (isset($matched[Presenter::PresenterKey])) /* pos 90:2 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($matched[Presenter::PresenterKey]) /* pos 91:3 */; + echo ':'; + echo Tracy\Helpers::escapeHtml($matched[Presenter::ActionKey] ?? Presenter::DefaultAction) /* pos 91:39 */; + echo ' + '; + if (isset($matched[Presenter::SignalKey])) /* pos 92:3 */ { + echo Tracy\Helpers::escapeHtml($matched[Presenter::SignalKey]) /* pos 92:45 */; + echo '!'; + } + echo "\n"; +} + +echo '

+ +
+
+

+ '; +echo Tracy\Helpers::escapeHtml($method) /* pos 99:9 */; +echo ' + '; +echo Tracy\Helpers::escapeHtml($url->getBaseUrl()) /* pos 100:9 */; +echo ''; +echo str_replace(['&', '?'], ['&', '?'], htmlspecialchars($url->getRelativeUrl())) /* pos 100:71 */; +echo ' +

+ +'; +if (is_string($source)) /* pos 103:2 */ { + echo '

'; + echo Tracy\Helpers::escapeHtml($source) /* pos 104:6 */; + echo ' (class not found)

+'; +} elseif ($source) /* pos 105:2 */ { + echo '

getFileName(), $source->getStartLine()))) === null ? '' : ' href="' . Tracy\Helpers::escapeHtml($ʟ_tmp) . '"' /* pos 106:16 */; + echo '>'; + echo Tracy\Helpers::escapeHtml($source instanceof ReflectionClass ? $source->getName() : $source->getDeclaringClass()->getName() . '::' . $source->getName() . '()') /* pos 106:92 */; + echo '

+'; +} + +echo '
+ +
+'; +if (empty($routes['routes'])) /* pos 111:2 */ { + echo '

No routes defined.

+'; +} else /* pos 113:2 */ { + echo '
+
+
+
Mask / Class
+
Defaults
+
Matched as
+
+ +'; + $_blocks['routeList'] = function ($list,$path='') use (&$_blocks) { + echo '
+'; + if ($list['domain'] || $list['module']) /* pos 124:11 */ { + echo '
+ '; + if ($list['domain']) /* pos 125:7 */ { + echo 'domain = '; + echo Tracy\Helpers::escapeHtml($list['domain']) /* pos 125:34 */; + } + echo ' + '; + if ($list['module']) /* pos 126:7 */ { + echo 'module = '; + echo Tracy\Helpers::escapeHtml($list['module']) /* pos 126:34 */; + } + echo ' +
+'; + } + $path .= $list['path'] /* pos 128:6 */; + foreach ($list['routes'] as $router) /* pos 129:6 */ { + if (is_array($router)) /* pos 130:7 */ { + $_blocks['routeList']($router,$path); + } else /* pos 132:7 */ { + $_blocks['route']($router,$path); + } + + } + + echo '
+'; + }; + echo "\n"; + $_blocks['route'] = function ($route,$path) use (&$_blocks) { + echo '
+
'matched as first', 'may' => 'suitable but not matched as first', 'no' => '', 'oneway' => 'one-way', 'error' => 'error'][$route->matched])) === null ? '' : ' title="' . Tracy\Helpers::escapeHtml($ʟ_tmp) . '"' /* pos 141:54 */; + echo '> + '; + echo Tracy\Helpers::escapeHtml(['yes' => '✓', 'may' => '≈', 'no' => '', 'oneway' => '⛔', 'error' => '❌'][$route->matched]) /* pos 142:7 */; + echo ' +
+ +
+ class)) === null ? '' : ' title="' . Tracy\Helpers::escapeHtml($ʟ_tmp) . '"' /* pos 146:21 */; + echo '> +'; + if ($path !== '') /* pos 147:15 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($path) /* pos 147:35 */; + echo ' +'; + } + echo ' '; + echo isset($route->mask) ? str_replace(['/', '-'], ['/', '-'], htmlspecialchars($route->mask)) : str_replace('\\', '\\', htmlspecialchars($route->class)) /* pos 148:8 */; + echo ' + +
+ +
+ +'; + foreach ($route->defaults as $key => $value) /* pos 154:8 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($key) /* pos 155:9 */; + echo ' = '; + if (is_string($value)) /* pos 155:28 */ { + echo Tracy\Helpers::escapeHtml($value) /* pos 155:50 */; + echo '
'; + echo Dumper::toHtml($value, [Dumper::COLLAPSE => true, Dumper::LIVE => true]) /* pos 155:62 */; + } + echo "\n"; + + } + + echo '
+
+ +
+'; + if ($route->params) /* pos 161:7 */ { + echo ' +'; + $params = $route->params /* pos 163:9 */; + if (isset($params[Presenter::PresenterKey])) /* pos 164:9 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($params['presenter']) /* pos 165:18 */; + echo ':'; + echo Tracy\Helpers::escapeHtml($params[Presenter::ActionKey] ?? Presenter::DefaultAction) /* pos 165:39 */; + echo ' +
+'; + $params = array_diff_key($params, [Presenter::PresenterKey => 1, Presenter::ActionKey => 1]) /* pos 167:10 */; + } + foreach ($params as $key => $value) /* pos 169:9 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($key) /* pos 170:10 */; + echo ' = '; + if (is_string($value)) /* pos 170:29 */ { + echo Tracy\Helpers::escapeHtml($value) /* pos 170:51 */; + echo '
'; + echo Dumper::toHtml($value, [Dumper::COLLAPSE => true, Dumper::LIVE => true]) /* pos 170:63 */; + } + echo "\n"; + + } + + echo '
+'; + } elseif ($route->error) /* pos 173:7 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($route->error->getMessage()) /* pos 174:16 */; + echo ' +'; + } + + echo '
+
+'; + }; + echo "\n"; + $_blocks['routeList']($routes); + echo '
+'; +} +echo '
+
+'; diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml new file mode 100644 index 00000000..7f66097f --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml @@ -0,0 +1,29 @@ + $matched */ +use Nette\Application\UI\Presenter; +echo ' + + + + + +'; +if ($matched === null) /* pos 10:3 */ { + echo ' no route +'; +} elseif (isset($matched[Presenter::PresenterKey])) /* pos 12:3 */ { + echo ' '; + echo Tracy\Helpers::escapeHtml($matched[Presenter::PresenterKey]) /* pos 13:4 */; + echo ':'; + echo Tracy\Helpers::escapeHtml($matched[Presenter::ActionKey] ?? Presenter::DefaultAction) /* pos 13:40 */; + if (isset($matched[Presenter::SignalKey])) /* pos 13:100 */ { + echo Tracy\Helpers::escapeHtml($matched[Presenter::SignalKey]) /* pos 13:142 */; + echo '!'; + } + echo "\n"; +} + +echo ' + +'; diff --git a/vendor/nette/application/src/compatibility-intf.php b/vendor/nette/application/src/compatibility-intf.php new file mode 100644 index 00000000..75d90e25 --- /dev/null +++ b/vendor/nette/application/src/compatibility-intf.php @@ -0,0 +1,75 @@ + +✅ seamless [Vite](https://vite.dev) integration with HMR support
+✅ lazy loading of file properties
+✅ clean API for PHP and [Latte](https://latte.nette.org) templates
+✅ multiple file sources support
+ + +Working with static files (images, CSS, JavaScript) in web applications often involves repetitive tasks: generating correct URLs, handling cache invalidation, managing file versions, and dealing with different environments. Nette Assets simplifies all of this. + +Without Nette Assets: +```latte +{* You need to manually handle paths and versioning *} + + +``` + +With Nette Assets: +```latte +{* Everything is handled automatically *} +{asset 'images/logo.png'} +{asset 'css/style.css'} +``` + +  + + +Installation +============ + +Install via Composer: + +```shell +composer require nette/assets +``` + +Requirements: PHP 8.1 or higher. + +  + + +Quick Start +=========== + +Let's start with the simplest possible example. You want to display an image in your application: + +```latte +{* In your Latte template *} +{asset 'images/logo.png'} +``` + +This single line: +- Finds your image file +- Generates the correct URL with automatic versioning +- Outputs a complete `` tag with proper dimensions + +That's it! No configuration needed for basic usage. The library uses sensible defaults and works out of the box. + + +Custom HTML +----------- + +Sometimes you need more control over the HTML: + +```latte +{* Use n:asset when you want to control HTML attributes *} + +``` + +You can also get just the URL using the `asset()` function: + +```latte +{* Get just the URL without HTML *} + +``` + + +Using in PHP +------------ + +In your presenters or services: + +```php +public function __construct( + private Nette\Assets\Registry $assets +) {} + +public function renderDefault(): void +{ + $logo = $this->assets->getAsset('images/logo.png'); + $this->template->logo = $logo; +} +``` + +Then in your template: + +```latte +{asset $logo} +{* or *} + +{* or *} +width} height={$logo->height} alt="Logo"> +``` + +  + + +Basic Concepts +============== + +Before diving deeper, let's understand three simple concepts that make Nette Assets powerful yet easy to use. + + +What is an Asset? +----------------- + +An asset is any static file in your application - images, stylesheets, scripts, fonts, etc. In Nette Assets, each file becomes an `Asset` object with useful properties: + +```php +$image = $assets->getAsset('photo.jpg'); +echo $image->url; // '/assets/photo.jpg?v=1699123456' +echo $image->width; // 800 +echo $image->height; // 600 +``` + +Different file types have different properties. The library automatically detects the file type and creates the appropriate asset: + +- **ImageAsset** - Images with width, height, alternative text, and lazy loading support +- **ScriptAsset** - JavaScript files with types and integrity hashes +- **StyleAsset** - CSS files with media queries +- **AudioAsset** - Audio files with duration information +- **VideoAsset** - Video files with dimensions, duration, poster image, and autoplay settings +- **EntryAsset** - Entry points with imports of styles and preloads of scripts +- **GenericAsset** - Generic files with mime types + + +Where Assets Come From (Mappers) +-------------------------------- + +A mapper is a service that knows how to find files and create URLs for them. The built-in `FilesystemMapper` does two things: +1. Looks for files in a specified directory +2. Generates public URLs for those files + +You can have multiple mappers for different purposes: + + +The Registry - Your Main Entry Point +------------------------------------ + +The Registry manages all your mappers and provides a simple API to get assets: + +```php +// Inject the registry +public function __construct( + private Nette\Assets\Registry $assets +) {} + +// Use it to get assets +$logo = $this->assets->getAsset('images/logo.png'); +``` + +The registry is smart about which mapper to use: + +```php +// Uses the 'default' mapper +$css = $assets->getAsset('style.css'); + +// Uses the 'images' mapper (using prefix) +$photo = $assets->getAsset('images:photo.jpg'); + +// Uses the 'images' mapper (using array) +$photo = $assets->getAsset(['images', 'photo.jpg']); +``` + +  + + +Configuration +============= + +While Nette Assets works with zero configuration, you can customize it to match your project structure. + + +Zero Configuration +------------------ + +Without any configuration, Nette Assets expects all your static files to be in the `assets` folder within your public directory: + +``` +www/ +├── assets/ +│ └── logo.png +└── index.php +``` + +This creates a default mapper that: +- Looks for files in `%wwwDir%/assets` +- Generates URLs like `/assets/file.ext` + + +Minimal Configuration +--------------------- + +The simplest [configuration](https://doc.nette.org/en/configuring) just tells the library where to find files: + +```neon +assets: + mapping: + # This creates a filesystem mapper that: + # - looks for files in %wwwDir%/assets + # - generates URLs like /assets/file.ext + default: assets +``` + +This is equivalent to the zero configuration setup but makes it explicit. + + +Setting Base Paths +------------------ + +By default, if you don't specify base paths: +- `basePath` defaults to `%wwwDir%` (your public directory) +- `baseUrl` defaults to your project's base URL (e.g., `https://example.com/`) + +You can customize these to organize your static files under a common directory: + +```neon +assets: + # All mappers will resolve paths relative to this directory + basePath: %wwwDir%/static + + # All mappers will resolve URL relative to this + baseUrl: /static + + mapping: + # Files in %wwwDir%/static/img, URLs like /static/img/photo.jpg + default: img + + # Files in %wwwDir%/static/js, URLs like /static/js/app.js + scripts: js +``` + + +Advanced Configuration +---------------------- + +For more control, you can configure each mapper in detail: + +```neon +assets: + mapping: + # Simple format - creates FilesystemMapper looking in 'img' folder + images: img + + # Detailed format with additional options + styles: + path: css # Directory to search for files + extension: css # Always add .css extension to requests + + # Different URL and directory path + audio: + path: audio # Files stored in 'audio' directory + url: https://static.example.com/audio # But served from CDN + + # Custom mapper service (dependency injection) + cdn: @cdnMapper +``` + +The `path` and `url` can be: +- **Relative**: resolved from `%wwwDir%` (or `basePath`) and project base URL (or `baseUrl`) +- **Absolute**: used as-is (`/var/www/shared/assets`, `https://cdn.example.com`) + + +Manual Configuration (Without Nette Framework) +---------------------------------------------- + +If you're not using the Nette Framework or prefer to configure everything manually in PHP: + +```php +use Nette\Assets\Registry; +use Nette\Assets\FilesystemMapper; + +// Create registry +$registry = new Registry; + +// Add mappers manually +$registry->addMapper('default', new FilesystemMapper( + baseUrl: 'https://example.com/assets', // URL prefix + basePath: __DIR__ . '/assets', // Filesystem path + extensions: ['webp', 'jpg', 'png'], // Try WebP first, fallback to JPG/PNG + versioning: true +)); + +// Use the registry +$logo = $registry->getAsset('logo'); // Finds logo.webp, logo.jpg, or logo.png +echo $logo->url; +``` + +For more advanced configuration options using NEON format without the full Nette Framework, install the configuration component: + +```shell +composer require nette/bootstrap +``` + +Then you can use NEON configuration files as described in the [Nette Bootstrap documentation](https://doc.nette.org/en/bootstrap). + +  + + +Working with Assets +=================== + +Let's explore how to work with assets in your PHP code. + + +Basic Retrieval +--------------- + +The Registry provides two methods for getting assets: + +```php +// This throws Nette\Assets\AssetNotFoundException if file doesn't exist +try { + $logo = $assets->getAsset('images/logo.png'); + echo $logo->url; +} catch (AssetNotFoundException $e) { + // Handle missing asset +} + +// This returns null if file doesn't exist +$banner = $assets->tryGetAsset('images/banner.jpg'); +if ($banner) { + echo $banner->url; +} +``` + + +Specifying Mappers +------------------ + +You can explicitly choose which mapper to use: + +```php +// Use default mapper +$asset = $assets->getAsset('document.pdf'); + +// Use specific mapper using prefix with colon +$asset = $assets->getAsset('images:logo.png'); + +// Use specific mapper using array syntax +$asset = $assets->getAsset(['images', 'logo.png']); +``` + + +Asset Types and Properties +-------------------------- + +The library automatically detects file types and provides relevant properties: + +```php +// Images +$image = $assets->getAsset('photo.jpg'); +echo $image->width; // 1920 +echo $image->height; // 1080 +echo $image->url; // '/assets/photo.jpg?v=1699123456' + +// All assets can be cast to string (returns URL) +$url = (string) $assets->getAsset('document.pdf'); +``` + + +Lazy Loading of Properties +-------------------------- + +Properties like image dimensions, audio duration, or MIME types are retrieved only when accessed. This keeps the library fast: + +```php +$image = $assets->getAsset('photo.jpg'); +// No file operations yet + +echo $image->url; // Just returns URL, no file reading + +echo $image->width; // NOW it reads the file header to get dimensions +echo $image->height; // Already loaded, no additional file reading + +// For MP3 files, duration is estimated (most accurate for Constant Bitrate files) +$audio = asset('audio:episode-01.mp3'); +echo $audio->duration; // in seconds + +// Even generic assets lazy-load their MIME type +$file = $assets->getAsset('document.pdf'); +echo $file->mimeType; // Now it detects: 'application/pdf' +``` + + +Working with Options +-------------------- + +Mappers can support additional options to control their behavior. For example, the `FilesystemMapper` supports the `version` option: + +```php +// Disable versioning for specific asset +$asset = $assets->getAsset('style.css', ['version' => false]); +echo $asset->url; // '/assets/style.css' (no ?v=... parameter) +``` + +Different mappers may support different options. Custom mappers can define their own options to provide additional functionality. + +  + + +Latte Integration +================= + +Nette Assets shines in [Latte templates](https://latte.nette.org) with intuitive tags and functions. + + +Basic Usage with `{asset}` Tag +------------------------------ + +The `{asset}` tag renders complete HTML elements: + +```latte +{* Renders: *} +{asset 'images/hero.jpg'} + +{* Renders: *} +{asset 'scripts/app.js'} + +{* Renders: *} +{asset 'styles/style.css'} + +{* Any additional parameters are passed as asset options *} +{asset 'style.css', version: false} +``` + +The tag automatically: +- Detects the asset type from file extension +- Generates the appropriate HTML element +- Adds versioning for cache busting +- Includes dimensions for images + + +However, if you use the `{asset}` tag inside an HTML attribute, it will only output the URL: + +```latte +
+ Content +
+ + +``` + + +Using Specific Mappers +---------------------- + +Just like in PHP, you can specify which mapper to use: + +```latte +{* Uses the 'images' mapper (via prefix) *} +{asset 'images:product-photo.jpg'} + +{* Uses the 'images' mapper (via array syntax) *} +{asset ['images', 'product-photo.jpg']} +``` + + +Custom HTML with `n:asset` Attribute +------------------------------------ + +When you need control over the HTML attributes: + +```latte +{* The n:asset attribute fills in the appropriate attributes *} +Product Photo + +{* Works with any relevant HTML element *} +link to image + + + + +``` + +The `n:asset` attribute: +- Sets `src` for images, scripts, and audio/video +- Sets `href` for stylesheets and preload links +- Adds dimensions for images and other attributes +- Preserves all your custom attributes + +How to use a variable in `n:asset`? + +```latte +{* The variable can be written quite simply *} + + +{* Use curly brackets when specifying the mapper *} + + +{* Or you can use array notation *} + + +{* You can pass options for assets *} + +``` + + +Getting Just URLs with Functions +-------------------------------- + +For maximum flexibility, use the `asset()` function: + +```latte +{var $logo = asset('images/logo.png')} +width} height={$logo->height}> +``` + + +Handling Optional Assets +------------------------ + +You can use optional tags that won't throw exceptions if the asset is missing: + +```latte +{* Optional asset tag - renders nothing if asset not found *} +{asset? 'images/optional-banner.jpg'} + +{* Optional n:asset attribute - skips the attribute if asset not found *} +User Photo +``` + +The optional variants (`{asset?}` and `n:asset?`) silently skip rendering when the asset doesn't exist, making them perfect for optional images, dynamic content, or situations where missing assets shouldn't break your layout. + +For maximum flexibility, use the `tryAsset()` function: + +```latte +{var $banner = tryAsset('images/summer-sale.jpg')} +{if $banner} + +{/if} + +{* Or with a fallback *} +Avatar +``` + + +Performance Optimization with Preloading +---------------------------------------- + + +Improve page load performance by preloading critical assets: + +```latte +{* In your section *} +{preload 'styles/critical.css'} +{preload 'fonts/heading.woff2'} +``` + +Generates: + +```html + + +``` + +The `{preload}` tag automatically: +- Determines the correct `as` attribute +- Adds `crossorigin` for fonts +- Uses `modulepreload` for ES modules + +  + + +Advanced Features +================= + + +Extension Autodetection +----------------------- + +When you have multiple formats of the same asset, the built-in `FilesystemMapper` can automatically find the right one: + +```neon +assets: + mapping: + images: + path: img + extension: [webp, jpg, png] # Check for each extension in order +``` + +Now when you request an asset without extension: + +```latte +{* Automatically finds: logo.webp, logo.jpg, or logo.png *} +{asset 'images:logo'} +``` + +This is useful for: +- Progressive enhancement (WebP with JPEG fallback) +- Flexible asset management +- Simplified templates + +You can also make extension optional: + +```neon +assets: + mapping: + scripts: + path: js + extension: [js, ''] # Try with .js first, then without +``` + + +Asset Versioning +---------------- + +Browser caching is great for performance, but it can prevent users from seeing updates. Asset versioning solves this problem. + +The `FilesystemMapper` automatically adds version parameters based on file modification time: + +```latte +{asset 'css/style.css'} +{* Output: *} +``` + +When you update the CSS file, the timestamp changes, forcing browsers to download the new version. + +You can disable versioning at multiple levels: + +```neon +assets: + # Global versioning setting (defaults to true) + versioning: false + + mapping: + default: + path: assets + # Enable versioning for this mapper only + versioning: true +``` + +Or per asset using asset options: + +```php +// In PHP +$asset = $assets->getAsset('style.css', ['version' => false]); + +// In Latte +{asset 'style.css', version: false} +``` + + +Working with Fonts +------------------ + +Font assets support preloading with proper CORS attributes: + +```latte +{* Generates proper preload with crossorigin attribute *} +{preload 'fonts:OpenSans-Regular.woff2'} + +{* In your CSS *} + +``` + +  + + +Vite Integration +================ + +For modern JavaScript applications, Nette Assets includes a specialized `ViteMapper` that integrates with [Vite](https://vite.dev)'s build process. + + +Basic Setup +----------- + +Create a `vite.config.ts` file in your project root. This file tells Vite where to find your source files and where to put the compiled ones. + +```js +import { defineConfig } from 'vite'; +import nette from '@nette/vite-plugin'; + +export default defineConfig({ + build: { + rollupOptions: { + input: 'assets/app.js', // entry point + }, + }, + plugins: [nette()], +}); +``` + +Configure the ViteMapper in your NEON file by setting `type: vite`: + +```neon +assets: + mapping: + default: + type: vite + path: assets +``` + + +Development Mode +---------------- + +The Vite dev server provides instant updates without page reload: + +```shell +npm run dev +``` + +Assets are automatically served from the Vite dev server when: +- Your app is in debug mode +- The dev server is running (auto-detected) + +No configuration needed - it just works! + + +Production Mode +--------------- + +```shell +npm run build +``` + +Vite creates optimized, versioned bundles that Nette Assets serves automatically. + + +Understanding Entry Points and Dependencies +------------------------------------------- + +When you build a modern JavaScript application, your bundler (like Vite) often splits code into multiple files for better performance. An "entry point" is your main JavaScript file that imports other modules. + +For example, your `src/main.js` might: +- Import a CSS file +- Import vendor libraries (like Vue or React) +- Import your application components + +Vite processes this and generates: +- The main JavaScript file +- Extracted CSS file(s) +- Vendor chunks for better caching +- Dynamic imports for code splitting + +The `EntryAsset` class handles this complexity. + + +Rendering Entry Points +---------------------- + +The `{asset}` tag automatically handles all dependencies. + +```latte +{asset 'vite:src/main.js'} +``` + +Single tag renders everything needed for that entry point: + +```html + + + + + + + + +``` + +Large applications often have multiple entry points with shared dependencies. Vite automatically deduplicates shared chunks. + + +Development vs Production Example +--------------------------------- + +The ViteMapper automatically switches between development and production modes: + +**During Development:** + +```latte +{* Serves from Vite dev server with hot module replacement *} +{asset 'vite:src/main.js'} +{* Output for example: + + +*} +``` + +**In Production:** + +```latte +{* Serves built files with hashed names from manifest *} +{asset 'vite:src/main.js'} +{* Output for example: + + +*} +``` + + +Versioning in Vite +------------------ + +Vite handles the entry point versioning itself and can be set in its configuration file. Unlike `FilesystemMapper`, Vite by default includes a hash in the filename (`main-4a8f9c7.js`). This approach works better with JavaScript module imports. + + +Fallback to Filesystem +---------------------- + +If a file isn't found in the Vite manifest, `ViteMapper` will attempt to find it directly on the filesystem, similar to how `FilesystemMapper` works. This is particularly useful for files in Vite's `publicDir` (default: `public/`), which are copied as-is to the output directory without being processed or included in the manifest. + + +Code Splitting and Dynamic Imports +---------------------------------- + +When your application uses dynamic imports: + +```js +// In your JavaScript +if (condition) { + import('./features/special-feature.js').then(module => { + module.init(); + }); +} +``` + +Nette Assets does **not** automatically preload dynamic imports - this is intentional as preloading all possible dynamic imports could hurt performance. + +If you want to preload specific dynamic imports, you can do so explicitly: + +```latte +{* Manually preload critical dynamic imports *} +{preload 'vite:features/special-feature.js'} +``` + +This gives you fine-grained control over which resources are preloaded based on your application's needs. + +  + + +Creating Custom Mappers +======================= + +While the built-in `FilesystemMapper` and `ViteMapper` handle most use cases, you might need custom asset resolution for: +- Cloud storage (S3, Google Cloud) +- Database-stored files +- Dynamic asset generation +- Third-party CDN integration + + +The Mapper Interface +-------------------- + +All mappers implement a simple interface: + +```php +interface Mapper +{ + /** + * @throws Nette\Assets\AssetNotFoundException + */ + public function getAsset(string $reference, array $options = []): Nette\Assets\Asset; +} +``` + +The contract is straightforward: +- Take a reference (like "logo.png" or "reports/annual-2024.pdf") +- Return an Asset object +- Throw `AssetNotFoundException` if the asset doesn't exist + + +Creating Assets with Helper +--------------------------- + +The `Nette\Assets\Helpers::createAssetFromUrl()` method is your primary tool for creating Asset objects in custom mappers. This helper automatically chooses the appropriate asset class based on the file's extension: + +```php +public static function createAssetFromUrl( + string $url, // The public URL of the asset + ?string $path = null, // Optional local file path (for reading properties) + array $args = [] // Additional constructor arguments +): Asset +``` + +The helper automatically creates the appropriate asset class: +- **ScriptAsset** for JavaScript files (`application/javascript`) +- **StyleAsset** for CSS files (`text/css`) +- **ImageAsset** for image files (`image/*`) +- **AudioAsset** for audio files (`audio/*`) +- **VideoAsset** for video files (`video/*`) +- **FontAsset** for font files (`font/woff`, `font/woff2`, `font/ttf`) +- **GenericAsset** for everything else + + +Database Mapper Example +----------------------- + +For applications storing file metadata in a database: + +```php +class DatabaseMapper implements Mapper +{ + public function __construct( + private Connection $db, + private string $baseUrl, + private Storage $storage, + ) {} + + public function getAsset(string $reference, array $options = []): Asset + { + // Find asset in database + $row = $this->db->fetchRow('SELECT * FROM assets WHERE id = ?', $reference); + if (!$row) { + throw new AssetNotFoundException("Asset '$reference' not found in database"); + } + + $url = $this->baseUrl . '/file/' . $row->storage_path; + $localPath = $this->storage->getLocalPath($row->storage_path); + + return Helpers::createAssetFromUrl( + url: $url, + path: $localPath, + args: [ + 'mimeType' => $row->mime_type, + 'width' => $row->width, + 'height' => $row->height, + ] + ); + } +} +``` + +Register in configuration: + +```neon +assets: + mapping: + db: DatabaseMapper(...) +``` + + +Cloud Storage Mapper +-------------------- + +For S3 or Google Cloud Storage: + +```php +class S3Mapper implements Mapper +{ + public function __construct( + private S3Client $s3, + private string $bucket, + private string $region, + private bool $private = false + ) {} + + public function getAsset(string $reference, array $options = []): Asset + { + try { + // Check if object exists + $this->s3->headObject([ + 'Bucket' => $this->bucket, + 'Key' => $reference, + ]); + + if ($this->private) { + // Generate presigned URL for private files + $url = $this->s3->createPresignedRequest( + $this->s3->getCommand('GetObject', [ + 'Bucket' => $this->bucket, + 'Key' => $reference, + ]), + '+10 minutes' + )->getUri(); + } else { + // Public URL + $url = "https://s3.{$this->region}.amazonaws.com/{$this->bucket}/{$reference}"; + } + + return Helpers::createAssetFromUrl($url); + + } catch (S3Exception $e) { + throw new AssetNotFoundException("Asset '$reference' not found in S3"); + } + } +} +``` + + +Using Options +------------- + +Options allow users to modify mapper behavior on a per-asset basis. This is useful when you need different transformations, sizes, or processing for the same asset: + +```php +public function getAsset(string $reference, array $options = []): Asset +{ + $thumbnail = $options['thumbnail'] ?? null; + + $url = $thumbnail + ? $this->cdnUrl . '/thumb/' . $reference + : $this->cdnUrl . '/' . $reference; + + return Helpers::createAssetFromUrl($url); +} +``` + +Usage: + +```php +// Get normal image +$photo = $assets->getAsset('cdn:photo.jpg'); + +// Get thumbnail version +$thumbnail = $assets->getAsset('cdn:photo.jpg', ['thumbnail' => true]); + +// In Latte: {asset 'cdn:photo.jpg', thumbnail: true} +``` + +This pattern is useful for: +- Image transformations (thumbnails, different sizes) +- CDN parameters (quality, format conversion) +- Access control (signed URLs, expiration times) + + +Handle Multiple Sources +----------------------- + +Sometimes you need to check multiple locations for an asset. A fallback mapper can try different sources in order: + +```php +class FallbackMapper implements Mapper +{ + public function __construct( + private array $mappers + ) {} + + public function getAsset(string $reference, array $options = []): Asset + { + foreach ($this->mappers as $mapper) { + try { + return $mapper->getAsset($reference, $options); + } catch (AssetNotFoundException) { + // continue + } + } + + throw new AssetNotFoundException("Asset '$reference' not found in any source"); + } +} +``` + +This is useful for: +- **Progressive migration**: Check new storage first, fall back to old +- **Multi-tier storage**: Fast cache → slower database → external API +- **Redundancy**: Primary CDN → backup CDN → local files +- **Environment-specific sources**: Local files in development, S3 in production + +Example configuration: + +```neon +assets: + mapping: + fallback: FallbackMapper([ + @cacheMapper, # Try fast cache first + @databaseMapper, # Then database + @filesystemMapper # Finally, local files + ]) +``` + +These advanced features make custom mappers extremely flexible and capable of handling complex asset management scenarios while maintaining the simple, consistent API that Nette Assets provides. + + +Best Practices for Custom Mappers +--------------------------------- + +1. **Always throw `Nette\Assets\AssetNotFoundException`** with a descriptive message when an asset can't be found +2. **Use `Helpers::createAssetFromUrl()`** to create the correct asset type based on file extension +3. **Support the `$options` parameter** for flexibility, even if you don't use it initially +4. **Document reference formats** clearly (e.g., "Use 'folder/file.ext' or 'uuid'") +5. **Consider caching** if asset resolution involves network requests or database queries +6. **Handle errors gracefully** and provide meaningful error messages +7. **Test edge cases** like missing files, network errors, and invalid references + +With custom mappers, Nette Assets can integrate with any storage system while maintaining a consistent API across your application. + + +[Support Me](https://github.com/sponsors/dg) +============================================ + +Do you like Nette Caching? Are you looking forward to the new features? + +[![Buy me a coffee](https://files.nette.org/icons/donation-3.svg)](https://github.com/sponsors/dg) + +Thank you! diff --git a/vendor/nette/assets/src/Assets/Asset.php b/vendor/nette/assets/src/Assets/Asset.php new file mode 100644 index 00000000..bd7b76ab --- /dev/null +++ b/vendor/nette/assets/src/Assets/Asset.php @@ -0,0 +1,20 @@ +mimeType = $mimeType ?? Helpers::guessMimeTypeFromExtension($file ?? $url); + $this->lazyLoad(compact('duration'), function () { + $this->duration = $this->file ? Helpers::guessMP3Duration($this->file) : null; + }); + } + + + public function __toString(): string + { + return $this->url; + } + + + public function getImportElement(): Html + { + return Html::el('audio', [ + 'src' => $this->url, + 'type' => $this->mimeType, + ]); + } + + + public function getPreloadElement(): Html + { + return Html::el('link', array_filter([ + 'rel' => 'preload', + 'href' => $this->url, + 'as' => 'audio', + 'type' => $this->mimeType, + ], fn($value) => $value !== null)); + } +} diff --git a/vendor/nette/assets/src/Assets/EntryAsset.php b/vendor/nette/assets/src/Assets/EntryAsset.php new file mode 100644 index 00000000..e7f71bac --- /dev/null +++ b/vendor/nette/assets/src/Assets/EntryAsset.php @@ -0,0 +1,23 @@ + */ + public array $imports = [], + /** @var list */ + public array $preloads = [], + public readonly ?string $type = 'module', + public readonly ?string $file = null, + public readonly ?string $integrity = null, + public readonly string|bool|null $crossorigin = null, + ) { + } +} diff --git a/vendor/nette/assets/src/Assets/FilesystemMapper.php b/vendor/nette/assets/src/Assets/FilesystemMapper.php new file mode 100644 index 00000000..de5175b6 --- /dev/null +++ b/vendor/nette/assets/src/Assets/FilesystemMapper.php @@ -0,0 +1,94 @@ + file extensions to try (without dot) */ + protected readonly array $extensions = [], + protected readonly bool $versioning = true, + ) { + } + + + /** + * Returns the asset for the given relative reference. + * Tries configured extensions in order and appends a version query parameter if enabled. + * Supported option: 'version' => bool (overrides the mapper-level versioning setting) + */ + public function getAsset(string $reference, array $options = []): Asset + { + Helpers::checkOptions($options, [self::OptionVersion]); + $path = $this->basePath . '/' . $reference; + $path .= $ext = $this->findExtension($path); + + if (!is_file($path)) { + throw new AssetNotFoundException("Asset file '$reference' not found at path: '$path'"); + } + + $url = $this->baseUrl . '/' . $reference . $ext; + if ($options[self::OptionVersion] ?? $this->versioning) { + $url = $this->applyVersion($url, $path); + } + return Helpers::createAssetFromUrl($url, $path); + } + + + /** + * Appends a ?v={filemtime} version parameter to the URL. + */ + protected function applyVersion(string $url, string $path): string + { + if (is_int($version = filemtime($path))) { + $url .= (str_contains($url, '?') ? '&' : '?') . 'v=' . $version; + } + return $url; + } + + + /** + * Returns the first matching file extension (with dot) from the configured list, or '' if none match. + */ + private function findExtension(string $basePath): string + { + $defaultExt = null; + foreach ($this->extensions as $ext) { + if ($ext === '') { + $defaultExt = ''; + } else { + $ext = '.' . $ext; + $defaultExt ??= $ext; + } + if (is_file($basePath . $ext)) { + return $ext; + } + } + + return $defaultExt ?? ''; + } + + + public function getBaseUrl(): string + { + return $this->baseUrl; + } + + + public function getBasePath(): string + { + return $this->basePath; + } +} diff --git a/vendor/nette/assets/src/Assets/FontAsset.php b/vendor/nette/assets/src/Assets/FontAsset.php new file mode 100644 index 00000000..4e19c79b --- /dev/null +++ b/vendor/nette/assets/src/Assets/FontAsset.php @@ -0,0 +1,51 @@ +mimeType = $mimeType ?? Helpers::guessMimeTypeFromExtension($file ?? $url); + } + + + public function __toString(): string + { + return $this->url; + } + + + public function getImportElement(): Html + { + return Html::el('link', array_filter([ + 'rel' => 'preload', + 'href' => $this->url, + 'as' => 'font', + 'type' => $this->mimeType, + 'crossorigin' => $this->crossorigin ?? true, + 'integrity' => $this->integrity, + ], fn($value) => $value !== null)); + } + + + public function getPreloadElement(): Html + { + return $this->getImportElement(); + } +} diff --git a/vendor/nette/assets/src/Assets/GenericAsset.php b/vendor/nette/assets/src/Assets/GenericAsset.php new file mode 100644 index 00000000..f301f011 --- /dev/null +++ b/vendor/nette/assets/src/Assets/GenericAsset.php @@ -0,0 +1,33 @@ +lazyLoad(compact('mimeType'), function () { + $this->mimeType = $this->file ? (mime_content_type($this->file) ?: null) : null; + }); + } + + + public function __toString(): string + { + return $this->url; + } +} diff --git a/vendor/nette/assets/src/Assets/Helpers.php b/vendor/nette/assets/src/Assets/Helpers.php new file mode 100644 index 00000000..a957ccdc --- /dev/null +++ b/vendor/nette/assets/src/Assets/Helpers.php @@ -0,0 +1,139 @@ + 'image/avif', 'gif' => 'image/gif', 'ico' => 'image/vnd.microsoft.icon', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'png' => 'image/png', 'svg' => 'image/svg+xml', 'webp' => 'image/webp', + 'js' => 'application/javascript', 'mjs' => 'application/javascript', + 'css' => 'text/css', + 'aac' => 'audio/aac', 'flac' => 'audio/flac', 'm4a' => 'audio/mp4', 'mp3' => 'audio/mpeg', 'ogg' => 'audio/ogg', 'wav' => 'audio/wav', + 'avi' => 'video/x-msvideo', 'mkv' => 'video/x-matroska', 'mov' => 'video/quicktime', 'mp4' => 'video/mp4', 'ogv' => 'video/ogg', 'webm' => 'video/webm', + 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'ttf' => 'font/ttf', + ]; + + + /** + * Creates an Asset of the appropriate type for the given URL. + * The type is determined from the 'mimeType' key in $args if provided, + * otherwise guessed from the file extension of $path or $url. + * @param array $args additional constructor arguments for the asset + */ + public static function createAssetFromUrl(string $url, ?string $path = null, array $args = []): Asset + { + $args['url'] = $url; + $args['file'] = $path; + $argsMime = $args; + $mimeType = (string) $argsMime['mimeType'] ??= self::guessMimeTypeFromExtension($path ?? $url); + $primary = explode('/', $mimeType, 2)[0]; + return match (true) { + $mimeType === 'application/javascript' => new ScriptAsset(...$args), + $mimeType === 'text/css' => new StyleAsset(...$args), + $primary === 'image' => new ImageAsset(...$args), + $primary === 'audio' => new AudioAsset(...$argsMime), + $primary === 'video' => new VideoAsset(...$argsMime), + $primary === 'font' => new FontAsset(...$argsMime), + default => new GenericAsset(...$argsMime), + }; + } + + + /** + * Guesses the MIME type from the file extension in the given URL or path, or null if unknown. + */ + public static function guessMimeTypeFromExtension(string $url): ?string + { + return preg_match('~\.([a-z0-9]{1,5})([?#]|$)~i', $url, $m) + ? self::ExtensionToMime[strtolower($m[1])] ?? null + : null; + } + + + /** + * Splits a potentially qualified reference 'mapper:reference' into a [mapper, reference] array. + * @return array{?string, string} + */ + public static function parseReference(string $qualifiedRef): array + { + $parts = explode(':', $qualifiedRef, 2); + return count($parts) === 1 + ? [null, $parts[0]] + : [$parts[0], $parts[1]]; + } + + + /** + * Validates an array of options against allowed optional and required keys. + * @param array $array + * @param list $optional + * @param list $required + * @throws \InvalidArgumentException if there are unsupported or missing options + */ + public static function checkOptions(array $array, array $optional = [], array $required = []): void + { + if ($keys = array_diff(array_keys($array), $optional, $required)) { + throw new \InvalidArgumentException('Unsupported asset options: ' . implode(', ', $keys)); + } + if ($keys = array_diff($required, array_keys($array))) { + throw new \InvalidArgumentException('Missing asset options: ' . implode(', ', $keys)); + } + } + + + /** + * Estimates the duration (in seconds) of an MP3 file, assuming constant bitrate (CBR). + * @throws \RuntimeException If the file cannot be opened, MP3 sync bits aren't found, or the bitrate is invalid/unsupported. + */ + public static function guessMP3Duration(string $path): float + { + if ( + ($header = @file_get_contents($path, length: 10000)) === false // @ - file may not exist + || ($fileSize = @filesize($path)) === false + ) { + throw new \RuntimeException(sprintf("Failed to open file '%s'. %s", $path, Nette\Utils\Helpers::getLastError())); + } + + $frameOffset = strpos($header, "\xFF\xFB"); // 0xFB indicates MPEG Version 1, Layer III, no protection bit. + if ($frameOffset === false) { + throw new \RuntimeException('Failed to find MP3 frame sync bits.'); + } + + $frameHeader = substr($header, $frameOffset, 4); + $headerBits = unpack('N', $frameHeader); + if ($headerBits === false) { + throw new \RuntimeException('Failed to unpack MP3 frame header.'); + } + $headerBits = $headerBits[1]; + $bitrateIndex = ($headerBits >> 12) & 0xF; + $bitrate = [null, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320][$bitrateIndex] ?? null; + if ($bitrate === null) { + throw new \RuntimeException('Invalid or unsupported bitrate index.'); + } + + return $fileSize * 8 / $bitrate / 1000; + } + + + /** + * Reads the Vite dev server URL from the given info file, or returns null if unavailable. + */ + public static function detectDevServer(string $infoFile): ?string + { + return ($info = @file_get_contents($infoFile)) // @ file may not exists + && ($info = json_decode($info, associative: true)) + && isset($info['devServer']) + && ($url = parse_url($info['devServer'])) + ? $info['devServer'] + : null; + } +} diff --git a/vendor/nette/assets/src/Assets/HtmlRenderable.php b/vendor/nette/assets/src/Assets/HtmlRenderable.php new file mode 100644 index 00000000..95117226 --- /dev/null +++ b/vendor/nette/assets/src/Assets/HtmlRenderable.php @@ -0,0 +1,22 @@ +lazyLoad(compact('width', 'height', 'mimeType'), $this->getSize(...)); + } + + + public function __toString(): string + { + return $this->url; + } + + + /** + * Retrieves image dimensions. + */ + private function getSize(): void + { + $info = $this->file ? getimagesize($this->file) : null; + if (!isset($this->mimeType)) { + $this->mimeType = $info['mime'] ?? null; + } + // If only one dimension is provided, the other is set to null + $info = isset($this->width) || isset($this->height) ? null : $info; + if (!isset($this->width)) { + $this->width = $info ? (int) round($info[0] / $this->density) : null; + } + if (!isset($this->height)) { + $this->height = $info ? (int) round($info[1] / $this->density) : null; + } + } + + + public function getImportElement(): Html + { + return Html::el('img', array_filter([ + 'src' => $this->url, + 'width' => $this->width ? (string) $this->width : null, + 'height' => $this->height ? (string) $this->height : null, + 'alt' => $this->alternative, + 'loading' => $this->lazyLoad ? 'lazy' : null, + 'crossorigin' => $this->crossorigin, + ], fn($value) => $value !== null)); + } + + + public function getPreloadElement(): Html + { + return Html::el('link', array_filter([ + 'rel' => 'preload', + 'href' => $this->url, + 'as' => 'image', + 'type' => $this->mimeType, + 'crossorigin' => $this->crossorigin, + ], fn($value) => $value !== null)); + } +} diff --git a/vendor/nette/assets/src/Assets/LazyLoad.php b/vendor/nette/assets/src/Assets/LazyLoad.php new file mode 100644 index 00000000..89a55934 --- /dev/null +++ b/vendor/nette/assets/src/Assets/LazyLoad.php @@ -0,0 +1,41 @@ + */ + private array $lazyLoaders = []; + + + /** + * Sets up lazy loading for specified properties. + * @param array $props property name => initial value + * @param \Closure(): void $loader + */ + private function lazyLoad(array $props, \Closure $loader): void + { + foreach ($props as $name => $value) { + if ($value === null) { + unset($this->$name); + $this->lazyLoaders[$name] = $loader; + } else { + $this->$name = $value; + } + } + } + + + public function __get(string $name): mixed + { + if ($loader = $this->lazyLoaders[$name] ?? null) { + $loader(); + } + return $this->$name; + } +} diff --git a/vendor/nette/assets/src/Assets/Mapper.php b/vendor/nette/assets/src/Assets/Mapper.php new file mode 100644 index 00000000..7d4d8b17 --- /dev/null +++ b/vendor/nette/assets/src/Assets/Mapper.php @@ -0,0 +1,17 @@ + $options mapper-specific options + * @throws AssetNotFoundException when the asset cannot be found + */ + public function getAsset(string $reference, array $options = []): Asset; +} diff --git a/vendor/nette/assets/src/Assets/Registry.php b/vendor/nette/assets/src/Assets/Registry.php new file mode 100644 index 00000000..84f1f499 --- /dev/null +++ b/vendor/nette/assets/src/Assets/Registry.php @@ -0,0 +1,113 @@ + */ + private array $mappers = []; + + /** @var array */ + private array $cache = []; + + + /** + * Registers an asset mapper under the given identifier. + * @throws \InvalidArgumentException if the identifier is already in use + */ + public function addMapper(string $id, Mapper $mapper): void + { + if (isset($this->mappers[$id])) { + throw new \InvalidArgumentException("Asset mapper '$id' is already registered"); + } + $this->mappers[$id] = $mapper; + } + + + /** + * Returns the mapper registered under the given identifier. + * @throws \InvalidArgumentException if the identifier is unknown + */ + public function getMapper(string $id = self::DefaultScope): Mapper + { + return $this->mappers[$id] ?? throw new \InvalidArgumentException("Unknown asset mapper '$id'."); + } + + + /** + * Returns an Asset for the given qualified reference ('mapper:reference' or ['mapper', 'reference']). + * @param string|array{?string, string} $qualifiedRef + * @param array $options passed to the mapper + * @throws AssetNotFoundException when the asset cannot be found + */ + public function getAsset(string|array $qualifiedRef, array $options = []): Asset + { + [$mapper, $reference] = is_string($qualifiedRef) + ? Helpers::parseReference($qualifiedRef) + : $qualifiedRef; + + $mapperDef = $mapper ?? self::DefaultScope; + $reference = (string) $reference; + $cacheKey = $this->generateCacheKey($mapperDef, $reference, $options); + if ($cacheKey !== null && array_key_exists($cacheKey, $this->cache)) { + return $this->cache[$cacheKey]; + } + + try { + $asset = $this->getMapper($mapperDef)->getAsset($reference, $options); + + if (count($this->cache) >= self::MaxCacheSize) { + array_shift($this->cache); // remove the oldest entry + } + + if ($cacheKey !== null) { + $this->cache[$cacheKey] = $asset; + } + return $asset; + + } catch (AssetNotFoundException $e) { + throw $mapper ? $e->qualifyReference($mapperDef, $reference) : $e; + } + } + + + /** + * Returns an Asset for the given qualified reference, or null if not found. + * @param string|array{string|null, string} $qualifiedRef + * @param array $options passed to the mapper + */ + public function tryGetAsset(string|array $qualifiedRef, array $options = []): ?Asset + { + try { + return $this->getAsset($qualifiedRef, $options); + } catch (AssetNotFoundException) { + return null; + } + } + + + /** + * Returns null when options contain non-scalar values (caching is disabled for such options). + * @param array $options + */ + private function generateCacheKey(string $mapper, string $reference, array $options): ?string + { + foreach ($options as $item) { + if ($item !== null && !is_scalar($item)) { + return null; + } + } + return $mapper . ':' . $reference . ($options ? ':' . hash('xxh128', serialize($options)) : ''); + } +} diff --git a/vendor/nette/assets/src/Assets/ScriptAsset.php b/vendor/nette/assets/src/Assets/ScriptAsset.php new file mode 100644 index 00000000..cf4f2b60 --- /dev/null +++ b/vendor/nette/assets/src/Assets/ScriptAsset.php @@ -0,0 +1,56 @@ +url; + } + + + public function getImportElement(): Html + { + return Html::el('script', array_filter([ + 'src' => $this->url, + 'type' => $this->type, + 'integrity' => $this->integrity, + 'crossorigin' => $this->crossorigin ?? (bool) $this->integrity, + ], fn($value) => $value !== null)); + } + + + public function getPreloadElement(): Html + { + return Html::el('link', array_filter($this->type === 'module' + ? [ + 'rel' => 'modulepreload', + 'href' => $this->url, + 'crossorigin' => $this->crossorigin, + ] + : [ + 'rel' => 'preload', + 'href' => $this->url, + 'as' => 'script', + 'crossorigin' => $this->crossorigin, + ])); + } +} diff --git a/vendor/nette/assets/src/Assets/StyleAsset.php b/vendor/nette/assets/src/Assets/StyleAsset.php new file mode 100644 index 00000000..6e0446f0 --- /dev/null +++ b/vendor/nette/assets/src/Assets/StyleAsset.php @@ -0,0 +1,52 @@ +url; + } + + + public function getImportElement(): Html + { + return Html::el('link', array_filter([ + 'rel' => 'stylesheet', + 'href' => $this->url, + 'media' => $this->media, + 'integrity' => $this->integrity, + 'crossorigin' => $this->crossorigin ?? (bool) $this->integrity, + ], fn($value) => $value !== null)); + } + + + public function getPreloadElement(): Html + { + return Html::el('link', [ + 'rel' => 'preload', + 'href' => $this->url, + 'as' => 'style', + 'crossorigin' => $this->crossorigin ?? (bool) $this->integrity, + ]); + } +} diff --git a/vendor/nette/assets/src/Assets/VideoAsset.php b/vendor/nette/assets/src/Assets/VideoAsset.php new file mode 100644 index 00000000..adc08ce8 --- /dev/null +++ b/vendor/nette/assets/src/Assets/VideoAsset.php @@ -0,0 +1,56 @@ +url; + } + + + public function getImportElement(): Html + { + return Html::el('video', array_filter([ + 'src' => $this->url, + 'width' => $this->width ? (string) $this->width : null, + 'height' => $this->height ? (string) $this->height : null, + 'type' => $this->mimeType, + 'poster' => $this->poster, + 'autoplay' => $this->autoPlay ? true : null, + ], fn($value) => $value !== null)); + } + + + public function getPreloadElement(): Html + { + return Html::el('link', array_filter([ + 'rel' => 'preload', + 'href' => $this->url, + 'as' => 'video', + 'type' => $this->mimeType, + ], fn($value) => $value !== null)); + } +} diff --git a/vendor/nette/assets/src/Assets/ViteMapper.php b/vendor/nette/assets/src/Assets/ViteMapper.php new file mode 100644 index 00000000..610e7b9c --- /dev/null +++ b/vendor/nette/assets/src/Assets/ViteMapper.php @@ -0,0 +1,162 @@ +, imports?: list}> */ + private array $chunks; + + /** @var array> dependencies cache keyed by chunk ID; null = not yet computed */ + private array $dependencies = []; + + + public function __construct( + private readonly string $baseUrl, + private readonly string $basePath, + private readonly ?string $manifestPath = null, + private readonly ?string $devServer = null, + private readonly ?Mapper $publicMapper = null, + ) { + if ($devServer !== null && !str_starts_with($devServer, 'http')) { + throw new \InvalidArgumentException("Vite devServer must be absolute URL, '$devServer' given"); + } + } + + + /** + * Returns an Asset for the given Vite entry point or public directory file. + * @throws AssetNotFoundException when the asset is not found in the manifest or public directory + */ + public function getAsset(string $reference, array $options = []): Asset + { + Helpers::checkOptions($options); + + if ($this->devServer) { + return $this->createDevelopmentAsset($reference); + } + + $this->chunks ??= $this->readChunks(); + + if (isset($this->chunks[$reference])) { + return $this->createProductionAsset($reference); + + } elseif ($this->publicMapper) { + return $this->publicMapper->getAsset($reference); + + } else { + throw new AssetNotFoundException("File '$reference' not found in Vite manifest"); + } + } + + + private function createProductionAsset(string $reference): Asset + { + $chunk = $this->chunks[$reference]; + $entry = isset($chunk['isEntry']) || isset($chunk['isDynamicEntry']); + if (str_starts_with($reference, '_') && !$entry) { + throw new AssetNotFoundException("Cannot directly access internal chunk '$reference'"); + } + + $dependencies = $this->collectDependencies($reference); + unset($dependencies[$chunk['file']]); + + return $dependencies + ? new EntryAsset( + url: $this->baseUrl . '/' . $chunk['file'], + file: $this->basePath . '/' . $chunk['file'], + imports: array_values(array_filter($dependencies, fn($asset) => $asset instanceof StyleAsset)), + preloads: array_values(array_filter($dependencies, fn($asset) => $asset instanceof ScriptAsset)), + crossorigin: true, + ) + : Helpers::createAssetFromUrl( + $this->baseUrl . '/' . $chunk['file'], + $this->basePath . '/' . $chunk['file'], + ['crossorigin' => true], + ); + } + + + private function createDevelopmentAsset(string $reference): Asset + { + $url = $this->devServer . '/' . $reference; + return match (1) { + preg_match('~\.(jsx?|mjs|tsx?)$~i', $reference) => new EntryAsset( + url: $url, + imports: [new ScriptAsset($this->devServer . '/@vite/client', type: 'module')], + ), + preg_match('~\.(sass|scss)$~i', $reference) => new StyleAsset($url), + default => Helpers::createAssetFromUrl($url), + }; + } + + + /** + * Recursively collects all imports (including nested) from a chunk. + * @return array + */ + private function collectDependencies(string $chunkId): array + { + $deps = &$this->dependencies[$chunkId]; + if ($deps === null) { + $deps = []; + $chunk = $this->chunks[$chunkId] ?? []; + foreach ($chunk['css'] ?? [] as $file) { + $deps[$file] = Helpers::createAssetFromUrl( + $this->baseUrl . '/' . $file, + $this->basePath . '/' . $file, + ['crossorigin' => true], + ); + } + foreach ($chunk['imports'] ?? [] as $id) { + $file = $this->chunks[$id]['file']; + $deps[$file] = Helpers::createAssetFromUrl( + $this->baseUrl . '/' . $file, + $this->basePath . '/' . $file, + ['type' => 'module', 'crossorigin' => true], + ); + $deps += $this->collectDependencies($id); + } + } + return $deps; + } + + + /** + * @return array, imports?: list}> + */ + private function readChunks(): array + { + $path = $this->manifestPath ?? $this->basePath . '/.vite/manifest.json'; + try { + $res = Json::decode(FileSystem::read($path), forceArrays: true); + } catch (\Throwable $e) { + throw new \RuntimeException("Failed to read Vite manifest from '$path'. Did you run 'npm run build'?", 0, $e); + } + if (!is_array($res)) { + throw new \RuntimeException("Invalid Vite manifest format in '$path'"); + } + return $res; + } + + + public function getBaseUrl(): string + { + return $this->baseUrl; + } + + + public function getBasePath(): string + { + return $this->basePath; + } +} diff --git a/vendor/nette/assets/src/Assets/exceptions.php b/vendor/nette/assets/src/Assets/exceptions.php new file mode 100644 index 00000000..d1bfc21a --- /dev/null +++ b/vendor/nette/assets/src/Assets/exceptions.php @@ -0,0 +1,22 @@ +message = str_replace("'$reference'", "'$mapper:$reference'", $this->message); + } + return $this; + } +} diff --git a/vendor/nette/assets/src/Bridges/AssetsDI/DIExtension.php b/vendor/nette/assets/src/Bridges/AssetsDI/DIExtension.php new file mode 100644 index 00000000..c6ee99b1 --- /dev/null +++ b/vendor/nette/assets/src/Bridges/AssetsDI/DIExtension.php @@ -0,0 +1,152 @@ + Expect::string()->dynamic(), + 'baseUrl' => Expect::string()->dynamic(), + 'versioning' => Expect::bool(), + 'mapping' => Expect::arrayOf( + Expect::anyOf( + Expect::string(), + Expect::structure([ + 'type' => Expect::string(), + 'path' => Expect::string()->dynamic(), + 'url' => Expect::string()->dynamic(), + 'extension' => Expect::anyOf(Expect::string(), Expect::arrayOf('string')), + 'versioning' => Expect::bool(), + 'manifest' => Expect::string()->dynamic(), + 'devServer' => Expect::anyOf(Expect::string(), Expect::bool())->default(true), + ]), + Expect::type(Statement::class), + ), + )->default(['default' => 'assets']), + ]); + } + + + public function loadConfiguration(): void + { + $builder = $this->getContainerBuilder(); + $registry = $builder->addDefinition($this->prefix('registry')) + ->setFactory(Registry::class); + + $this->needVariable = 0; + assert($this->config instanceof \stdClass); + $this->basePath = $this->config->basePath ?? $this->basePath ?? null; + + foreach ($this->config->mapping as $scope => $item) { + if (is_string($item)) { + $mapper = str_contains($item, '\\') + ? new Statement($item) + : $this->createFileMapper((object) ['path' => $item]); + + } elseif (!$item instanceof \stdClass) { + $mapper = $item; + + } elseif (($item->type ?? null) === 'vite') { + $mapper = $this->createViteMapper($item); + + } else { + $mapper = $this->createFileMapper($item); + } + + if ($this->needVariable === 1) { + $baseUrl = $this->config->baseUrl ?? $this->baseUrl ?? throw new \LogicException("Assets: 'baseUrl' is not defined"); + $registry->addSetup('$baseUrl = new Nette\Http\UrlImmutable(?)', [new Statement("rtrim(?, '/') . '/'", [$baseUrl])]); + } + + $registry->addSetup('addMapper', [$scope, $mapper]); + } + } + + + private function createFileMapper(\stdClass $config): Statement + { + $this->needVariable++; + return new Statement(FilesystemMapper::class, [ + 'baseUrl' => $this->resolveUrl($config), + 'basePath' => $this->resolvePath($config), + 'extensions' => (array) ($config->extension ?? null), + 'versioning' => $config->versioning ?? $this->config->versioning ?? true, + ]); + } + + + private function createViteMapper(\stdClass $config): Statement + { + return new Statement(ViteMapper::class, [ + 'baseUrl' => $this->resolveUrl($config), + 'basePath' => new Statement('$path = ?', [$this->resolvePath($config)]), + 'manifestPath' => $config->manifest ? new Statement('Nette\Utils\FileSystem::resolvePath($path, ?)', [$config->manifest]) : null, + 'devServer' => $this->resolveDevServer($config), + 'publicMapper' => $this->createFileMapper($config), + ]); + } + + + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + if ($name = $builder->getByType(Nette\Bridges\ApplicationLatte\LatteFactory::class)) { + $def = $builder->getDefinition($name); + assert($def instanceof Nette\DI\Definitions\FactoryDefinition); + $def->getResultDefinition() + ->addSetup('addExtension', [new Statement(LatteExtension::class)]); + } + } + + + private function resolvePath(\stdClass $config): Statement + { + $path = isset($this->basePath, $config->path) + ? new Statement('Nette\Utils\FileSystem::resolvePath(?, ?)', [$this->basePath, $config->path]) + : $config->path ?? $this->basePath ?? throw new \LogicException("Assets: 'basePath' is not defined"); + return new Statement("rtrim(?, '\\/')", [$path]); + } + + + private function resolveUrl(\stdClass $config): Statement + { + $url = new Statement('$baseUrl->resolve(?)->getAbsoluteUrl()', [$config->url ?? $config->path ?? '']); + return new Statement("rtrim(?, '/')", [$url]); + } + + + private function resolveDevServer(\stdClass $config): Statement|string|null + { + return match (true) { + !$this->debugMode || !$config->devServer => null, + $config->devServer === true => new Statement('Nette\Assets\Helpers::detectDevServer(? . "/.vite/nette.json")', [$this->resolvePath($config)]), + default => rtrim($config->devServer, '/'), + }; + } +} diff --git a/vendor/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php b/vendor/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php new file mode 100644 index 00000000..e67217d8 --- /dev/null +++ b/vendor/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php @@ -0,0 +1,55 @@ +runtime = new Runtime($registry); + } + + + public function getTags(): array + { + return [ + 'asset' => Nodes\AssetNode::create(...), + 'preload' => Nodes\AssetNode::create(...), + 'n:asset' => Nodes\NAssetNode::create(...), + 'n:asset?' => Nodes\NAssetNode::create(...), + ]; + } + + + public function getFunctions(): array + { + return [ + 'asset' => fn(string|array|Asset $reference, ...$options): Asset => $this->runtime->resolve($reference, $options, try: false), + 'tryAsset' => fn(string|array|Asset|null $reference, ...$options): ?Asset => $this->runtime->resolve($reference, $options, try: true), + ]; + } + + + public function getProviders(): array + { + return [ + 'assets' => $this->runtime, + ]; + } +} diff --git a/vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php b/vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php new file mode 100644 index 00000000..0cc9e8e3 --- /dev/null +++ b/vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php @@ -0,0 +1,70 @@ +outputMode = $tag::OutputKeepIndentation; + $tag->expectArguments(); + + $node = new static; + $node->optional = str_starts_with($tag->parser->text, '?') && $tag->parser->stream->tryConsume('?'); + $node->name = $tag->parser->parseExpression(); + $node->attributes = $tag->parser->stream->tryConsume(',') + ? $tag->parser->parseArguments() + : new ArrayNode; + $node->preload = str_starts_with($tag->name, 'preload'); + return $node; + } + + + public function print(PrintContext $context): string + { + $escaper = $context->getEscaper(); + $inAttr = $escaper->getState() === $escaper::HtmlAttribute; + return $context->format( + <<<'XX' + if ($ʟ_tmp = $this->global->assets->resolve(%node, %node, %dump)) %line { + echo %raw($ʟ_tmp); + } + XX, + $this->name, + $this->attributes, + $this->optional, + $this->position, + $inAttr ? '' : ('$this->global->assets->' . ($this->preload ? 'renderAssetPreload' : 'renderAsset')), + ); + } + + + public function &getIterator(): \Generator + { + yield $this->name; + yield $this->attributes; + } +} diff --git a/vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php b/vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php new file mode 100644 index 00000000..639df4fe --- /dev/null +++ b/vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php @@ -0,0 +1,113 @@ + + * + +

Nette Forms basic example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/bootstrap4-rendering.php b/vendor/nette/forms/examples/bootstrap4-rendering.php new file mode 100644 index 00000000..a674674a --- /dev/null +++ b/vendor/nette/forms/examples/bootstrap4-rendering.php @@ -0,0 +1,105 @@ +getRenderer(); + $renderer->wrappers['controls']['container'] = null; + $renderer->wrappers['pair']['container'] = 'div class="form-group row"'; + $renderer->wrappers['label']['container'] = 'div class="col-sm-3 col-form-label"'; + $renderer->wrappers['control']['container'] = 'div class=col-sm-9'; + $renderer->wrappers['control']['description'] = 'span class=form-text'; + $renderer->wrappers['control']['errorcontainer'] = 'span class=invalid-feedback'; + $renderer->wrappers['control']['.error'] = 'is-invalid'; + $renderer->wrappers['error']['container'] = 'div class="alert alert-danger"'; + + foreach ($form->getControls() as $control) { + $type = $control->getOption('type'); + if ($type === 'button') { + $control->getControlPrototype()->addClass(empty($usedPrimary) ? 'btn btn-primary' : 'btn btn-secondary'); + $usedPrimary = true; + + } elseif (in_array($type, ['text', 'textarea', 'select', 'datetime'], true)) { + $control->getControlPrototype()->addClass('form-control'); + + } elseif ($type === 'file') { + $control->getControlPrototype()->addClass('form-control-file'); + + } elseif (in_array($type, ['checkbox', 'radio'], true)) { + if ($control instanceof Nette\Forms\Controls\Checkbox) { + $control->getLabelPrototype()->addClass('form-check-label'); + } else { + $control->getItemLabelPrototype()->addClass('form-check-label'); + } + $control->getControlPrototype()->addClass('form-check-input'); + $control->getContainerPrototype()->setName('div')->addClass('form-check'); + } + } +} + + +$form = new Form; +$form->onRender[] = 'makeBootstrap4'; + +$form->addGroup('Personal data'); +$form->addText('name', 'Your name') + ->setRequired('Enter your name'); + +$form->addRadioList('gender', 'Your gender', [ + 'male', 'female', +]); + +$form->addCheckboxList('colors', 'Favorite colors', [ + 'red', 'green', 'blue', +]); + +$form->addSelect('country', 'Country', [ + 'Buranda', 'Qumran', 'Saint Georges Island', +]); + +$form->addCheckbox('send', 'Ship to address'); + +$form->addGroup('Your account'); +$form->addPassword('password', 'Choose password'); +$form->addUpload('avatar', 'Picture'); +$form->addTextArea('note', 'Comment'); + +$form->addGroup(); +$form->addSubmit('submit', 'Send'); +$form->addSubmit('cancel', 'Cancel'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms & Bootstrap v4 rendering example + + + +
+

Nette Forms & Bootstrap v4 rendering example

+ + render() ?> +
diff --git a/vendor/nette/forms/examples/bootstrap5-rendering.php b/vendor/nette/forms/examples/bootstrap5-rendering.php new file mode 100644 index 00000000..22065e22 --- /dev/null +++ b/vendor/nette/forms/examples/bootstrap5-rendering.php @@ -0,0 +1,110 @@ +getRenderer(); + $renderer->wrappers['controls']['container'] = null; + $renderer->wrappers['pair']['container'] = 'div class="mb-3 row"'; + $renderer->wrappers['label']['container'] = 'div class="col-sm-3 col-form-label"'; + $renderer->wrappers['control']['container'] = 'div class=col-sm-9'; + $renderer->wrappers['control']['description'] = 'span class=form-text'; + $renderer->wrappers['control']['errorcontainer'] = 'span class=invalid-feedback'; + $renderer->wrappers['control']['.error'] = 'is-invalid'; + $renderer->wrappers['error']['container'] = 'div class="alert alert-danger"'; + + foreach ($form->getControls() as $control) { + $type = $control->getOption('type'); + if ($type === 'button') { + $control->getControlPrototype()->addClass(empty($usedPrimary) ? 'btn btn-primary' : 'btn btn-secondary'); + $usedPrimary = true; + + } elseif (in_array($type, ['text', 'textarea', 'select', 'datetime', 'file'], true)) { + $control->getControlPrototype()->addClass('form-control'); + + } elseif (in_array($type, ['checkbox', 'radio'], true)) { + if ($control instanceof Nette\Forms\Controls\Checkbox) { + $control->getLabelPrototype()->addClass('form-check-label'); + } else { + $control->getItemLabelPrototype()->addClass('form-check-label'); + } + $control->getControlPrototype()->addClass('form-check-input'); + $control->getContainerPrototype()->setName('div')->addClass('form-check'); + + } elseif ($type === 'color') { + $control->getControlPrototype()->addClass('form-control form-control-color'); + } + } +} + + +$form = new Form; +$form->onRender[] = 'makeBootstrap5'; + +$form->addGroup('Personal data'); +$form->addText('name', 'Your name') + ->setRequired('Enter your name') + ->setOption('description', 'Name and surname'); + +$form->addDate('birth', 'Date of birth'); + +$form->addRadioList('gender', 'Your gender', [ + 'male', 'female', +]); + +$form->addCheckboxList('colors', 'Favorite colors', [ + 'red', 'green', 'blue', +]); + +$form->addSelect('country', 'Country', [ + 'Buranda', 'Qumran', 'Saint Georges Island', +]); + +$form->addCheckbox('send', 'Ship to address'); + +$form->addColor('color', 'Favourite colour'); + +$form->addGroup('Your account'); +$form->addPassword('password', 'Choose password'); +$form->addUpload('avatar', 'Picture'); +$form->addTextArea('note', 'Comment'); + +$form->addGroup(); +$form->addSubmit('submit', 'Send'); +$form->addSubmit('cancel', 'Cancel'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms & Bootstrap v5 rendering example + + + +
+

Nette Forms & Bootstrap v5 rendering example

+ + render() ?> +
diff --git a/vendor/nette/forms/examples/containers.php b/vendor/nette/forms/examples/containers.php new file mode 100644 index 00000000..6537cb6e --- /dev/null +++ b/vendor/nette/forms/examples/containers.php @@ -0,0 +1,62 @@ +addGroup('First person'); + +$first = $form->addContainer('first'); +$first->addText('name', 'Your name:'); +$first->addText('email', 'Email:'); +$first->addText('street', 'Street:'); +$first->addText('city', 'City:'); + +// group Second person +$form->addGroup('Second person'); + +$second = $form->addContainer('second'); +$second->addText('name', 'Your name:'); +$second->addText('email', 'Email:'); +$second->addText('street', 'Street:'); +$second->addText('city', 'City:'); + +// group for button +$form->addGroup(); + +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms containers example + + +

Nette Forms containers example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/custom-control.php b/vendor/nette/forms/examples/custom-control.php new file mode 100644 index 00000000..c02fc696 --- /dev/null +++ b/vendor/nette/forms/examples/custom-control.php @@ -0,0 +1,135 @@ +addRule(self::validateDate(...), 'Date is invalid.'); + } + + + public function setValue($value) + { + if ($value === null) { + $this->day = $this->month = $this->year = ''; + } else { + $date = Nette\Utils\DateTime::from($value); + $this->day = $date->format('j'); + $this->month = $date->format('n'); + $this->year = $date->format('Y'); + } + return $this; + } + + + public function getValue(): ?DateTimeImmutable + { + return self::validateDate($this) + ? (new DateTimeImmutable)->setDate((int) $this->year, (int) $this->month, (int) $this->day)->setTime(0, 0) + : null; + } + + + public function isFilled(): bool + { + return $this->day !== '' || $this->year !== ''; + } + + + public function loadHttpData(): void + { + $this->day = $this->getHttpData(Form::DataLine, '[day]'); + $this->month = $this->getHttpData(Form::DataLine, '[month]'); + $this->year = $this->getHttpData(Form::DataLine, '[year]'); + } + + + /** + * Generates control's HTML element. + */ + public function getControl() + { + $name = $this->getHtmlName(); + return Html::el('input', [ + 'name' => $name . '[day]', + 'id' => $this->getHtmlId(), + 'value' => $this->day, + 'type' => 'number', + 'min' => 1, + 'max' => 31, + 'data-nette-rules' => Helpers::exportRules($this->getRules()) ?: null, + ]) + + . Helpers::createSelectBox( + [1 => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], + [], + $this->month, + )->name($name . '[month]') + + . Html::el('input', [ + 'name' => $name . '[year]', + 'value' => $this->year, + 'type' => 'number', + ]); + } + + + public static function validateDate(Nette\Forms\Control $control): bool + { + return ctype_digit($control->day) + && ctype_digit($control->month) + && ctype_digit($control->year) + && checkdate((int) $control->month, (int) $control->day, (int) $control->year); + } +} + + +Tracy\Debugger::enable(); + +$form = new Form; + +$form['date'] = new DateInput('Date:'); +$form['date']->setDefaultValue(new DateTime); + +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Tracy\Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms custom control example + + + +

Nette Forms custom control example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/custom-rendering.php b/vendor/nette/forms/examples/custom-rendering.php new file mode 100644 index 00000000..8ae60f8e --- /dev/null +++ b/vendor/nette/forms/examples/custom-rendering.php @@ -0,0 +1,125 @@ +getRenderer(); +$renderer->wrappers['form']['container'] = Html::el('div')->id('form'); +$renderer->wrappers['group']['container'] = null; +$renderer->wrappers['group']['label'] = 'h3'; +$renderer->wrappers['pair']['container'] = null; +$renderer->wrappers['controls']['container'] = 'dl'; +$renderer->wrappers['control']['container'] = 'dd'; +$renderer->wrappers['control']['.odd'] = 'odd'; +$renderer->wrappers['label']['container'] = 'dt'; +$renderer->wrappers['label']['suffix'] = ':'; +$renderer->wrappers['control']['requiredsuffix'] = " \u{2022}"; + + +$form->addGroup('Personal data'); +$form->addText('name', 'Your name') + ->setRequired('Enter your name'); + +$form->addRadioList('gender', 'Your gender', [ + 'm' => Html::el('span', 'male')->style('color: #248bd3'), + 'f' => Html::el('span', 'female')->style('color: #e948d4'), +]); + +$form->addSelect('country', 'Country', [ + 'Buranda', 'Qumran', 'Saint Georges Island', +]); + +$form->addCheckbox('send', 'Ship to address'); + +$form->addGroup('Your account'); +$form->addPassword('password', 'Choose password'); +$form->addUpload('avatar', 'Picture'); +$form->addTextArea('note', 'Comment'); + +$form->addGroup(); +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms custom rendering example + + + + + +

Nette Forms custom rendering example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/custom-validator.php b/vendor/nette/forms/examples/custom-validator.php new file mode 100644 index 00000000..d27df2f8 --- /dev/null +++ b/vendor/nette/forms/examples/custom-validator.php @@ -0,0 +1,62 @@ +value % $arg === 0; + } +} + + +$form = new Form; + +$form->addText('num1', 'Multiple of 8:') + ->setDefaultValue(5) + ->addRule('MyValidators::divisibilityValidator', 'First number must be %d multiple', 8); + +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms custom validator example + + + + + +

Nette Forms custom validator example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/html5.php b/vendor/nette/forms/examples/html5.php new file mode 100644 index 00000000..2c8f4362 --- /dev/null +++ b/vendor/nette/forms/examples/html5.php @@ -0,0 +1,61 @@ +addGroup(); + +$form->addText('query', 'Search:') + ->setHtmlType('search') + ->setHtmlAttribute('autofocus'); + +$form->addInteger('count', 'Number of results:') + ->setDefaultValue(10) + ->addRule($form::Range, 'Must be in range from %d to %d', [1, 100]); + +$form->addFloat('precision', 'Precision:') + ->setHtmlType('range') + ->setDefaultValue(50) + ->addRule($form::Range, 'Precision must be in range from %d to %d', [0, 100]); + +$form->addEmail('email', 'Send to email:') + ->setHtmlAttribute('autocomplete', 'off') + ->setHtmlAttribute('placeholder', 'Optional, but Recommended'); + +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms and HTML5 + + + +

Nette Forms and HTML5

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/latte.php b/vendor/nette/forms/examples/latte.php new file mode 100644 index 00000000..256e4e4f --- /dev/null +++ b/vendor/nette/forms/examples/latte.php @@ -0,0 +1,60 @@ +addText('name', 'Your name') + ->setRequired('Enter your name') + ->setOption('description', 'Name and surname'); + +$form->addDate('birth', 'Date of birth'); + +$form->addRadioList('gender', 'Your gender', [ + 'male', 'female', +]); + +$form->addCheckboxList('colors', 'Favorite colors', [ + 'red', 'green', 'blue', +]); + +$form->addSelect('country', 'Country', [ + 'Buranda', 'Qumran', 'Saint Georges Island', +]); + +$form->addCheckbox('send', 'Ship to address'); + +$form->addColor('color', 'Favourite colour'); + +$form->addPassword('password', 'Choose password'); +$form->addUpload('avatar', 'Picture'); +$form->addTextArea('note', 'Comment'); + +$form->addSubmit('submit', 'Send'); +$form->addSubmit('cancel', 'Cancel'); + + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + +$latte = new Latte\Engine; +$latte->addExtension(new Nette\Bridges\FormsLatte\FormsExtension); + +$latte->render(__DIR__ . '/latte/page.latte', ['form' => $form]); diff --git a/vendor/nette/forms/examples/latte/form-bootstrap5.latte b/vendor/nette/forms/examples/latte/form-bootstrap5.latte new file mode 100644 index 00000000..6d7bcae9 --- /dev/null +++ b/vendor/nette/forms/examples/latte/form-bootstrap5.latte @@ -0,0 +1,66 @@ +{* Generic form template for Bootstrap v5 *} + +{define bootstrap-form, $name} +
+ {* List for form-level error messages *} +
    +
  • {$error}
  • +
+ +
+ + {include controls $group->getControls()} +
+ + {include controls $form->getControls()} +
+{/define} + + +{define local controls, array $controls} + {* Loop over form controls and render each one *} +
+ + {* Label for the control *} +
{label $control /}
+ +
+ {include control $control} + {if $control->getOption(type) === button} + {while $iterator->nextValue?->getOption(type) === button} + {input $iterator->nextValue class => "btn btn-secondary"} + {do $iterator->next()} + {/while} + {/if} + + {* Display control-level errors or descriptions, if present *} + {$control->error} + {$control->getOption(description)} +
+
+{/define} + + +{define local control, Nette\Forms\Controls\BaseControl $control} + {* Conditionally render controls based on their type with appropriate Bootstrap classes *} + {if $control->getOption(type) in [text, select, textarea, datetime, file]} + {input $control class => form-control} + + {elseif $control->getOption(type) === button} + {input $control class => "btn btn-primary"} + + {elseif $control->getOption(type) in [checkbox, radio]} + {var $items = $control instanceof Nette\Forms\Controls\Checkbox ? [''] : $control->getItems()} +
+ {input $control:$key class => form-check-input}{label $control:$key class => form-check-label /} +
+ + {elseif $control->getOption(type) === color} + {input $control class => "form-control form-control-color"} + + {else} + {input $control} + {/if} +{/define} diff --git a/vendor/nette/forms/examples/latte/form.latte b/vendor/nette/forms/examples/latte/form.latte new file mode 100644 index 00000000..f0230cd6 --- /dev/null +++ b/vendor/nette/forms/examples/latte/form.latte @@ -0,0 +1,37 @@ +{* Generic form template *} + +{define form, $name} +
+ {* List for form-level error messages *} +
    +
  • {$error}
  • +
+ +
+ + {include controls $group->getControls()} +
+ + {include controls $form->getControls()} +
+{/define} + + +{define local controls, array $controls} + {* Loop over form controls and render each one *} + + + + + + + +
{label $control /} + {input $control} + + {$control->getOption(description)} + {$control->error} +
+{/define} diff --git a/vendor/nette/forms/examples/latte/page.latte b/vendor/nette/forms/examples/latte/page.latte new file mode 100644 index 00000000..f55ad5d0 --- /dev/null +++ b/vendor/nette/forms/examples/latte/page.latte @@ -0,0 +1,19 @@ +{import 'form-bootstrap5.latte'} + + + + + + Nette Forms rendering using Latte + + + + + +
+

Nette Forms & Bootstrap v5 rendering example

+ + {include bootstrap-form, $form} +
+ + diff --git a/vendor/nette/forms/examples/live-validation.php b/vendor/nette/forms/examples/live-validation.php new file mode 100644 index 00000000..8ebd3a51 --- /dev/null +++ b/vendor/nette/forms/examples/live-validation.php @@ -0,0 +1,104 @@ +addText('name', 'Your name:') + ->setRequired('Enter your name'); + +$form->addText('age', 'Your age:') + ->setRequired('Enter your age') + ->addRule($form::Integer, 'Age must be numeric value') + ->addRule($form::Range, 'Age must be in range from %d to %d', [10, 100]); + +$form->addPassword('password', 'Choose password:') + ->setRequired('Choose your password') + ->addRule($form::MinLength, 'The password is too short: it must be at least %d characters', 3); + +$form->addPassword('password2', 'Reenter password:') + ->setRequired('Reenter your password') + ->addRule($form::Equal, 'Passwords do not match', $form['password']); + +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + +$renderer = $form->getRenderer(); +$renderer->wrappers['pair']['.error'] = 'has-error'; + +?> + + +Nette Forms live validation example + + + + + + +

Nette Forms live validation example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/localization.ini b/vendor/nette/forms/examples/localization.ini new file mode 100644 index 00000000..f03ef275 --- /dev/null +++ b/vendor/nette/forms/examples/localization.ini @@ -0,0 +1,12 @@ +Personal data = Osobní údaje +Your name: = Jméno: +Enter your name = Zadejte jméno +Your age: = Věk: +Enter your age = Zadejte váš věk +Age must be numeric value = Věk musí být číslo +Age must be in range from %d to %d = Věk musí být v rozmezí %d až %d +Country: = Země: +Select your country = Vyberte zemi +World = Svět +other = jiná +Send = Odeslat diff --git a/vendor/nette/forms/examples/localization.php b/vendor/nette/forms/examples/localization.php new file mode 100644 index 00000000..876f64f5 --- /dev/null +++ b/vendor/nette/forms/examples/localization.php @@ -0,0 +1,87 @@ +table = $table; + } + + + /** + * Translates the given string. + */ + public function translate($message, ...$parameters): string + { + return $this->table[$message] ?? $message; + } +} + + +$form = new Form; + +$translator = new MyTranslator(parse_ini_file(__DIR__ . '/localization.ini')); +$form->setTranslator($translator); + +$form->addGroup('Personal data'); +$form->addText('name', 'Your name:') + ->setRequired('Enter your name'); + +$form->addText('age', 'Your age:') + ->setRequired('Enter your age') + ->addRule($form::Integer, 'Age must be numeric value') + ->addRule($form::Range, 'Age must be in range from %d to %d', [10, 100]); + +$countries = [ + 'World' => [ + 'bu' => 'Buranda', + 'qu' => 'Qumran', + 'st' => 'Saint Georges Island', + ], + '?' => 'other', +]; +$form->addSelect('country', 'Country:', $countries) + ->setPrompt('Select your country'); + +$form->addSubmit('submit', 'Send'); + + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + +Nette Forms localization example + + + +

Nette Forms localization example

+ +render() ?> + + diff --git a/vendor/nette/forms/examples/manual-rendering.php b/vendor/nette/forms/examples/manual-rendering.php new file mode 100644 index 00000000..6c54f7cf --- /dev/null +++ b/vendor/nette/forms/examples/manual-rendering.php @@ -0,0 +1,93 @@ +addText('name') + ->setRequired('Enter your name'); + +$form->addText('age') + ->setRequired('Enter your age'); + +$form->addRadioList('gender', null, [ + 'm' => 'male', + 'f' => 'female', +]); + +$form->addEmail('email'); + +$form->addSubmit('submit'); + +if ($form->isSuccess()) { + echo '

Form was submitted and successfully validated

'; + Dumper::dump($form->getValues()); + exit; +} + + +?> + + + + + Nette Forms manual form rendering + + + + + +

Nette Forms manual form rendering

+ + render('begin') ?> + + errors): ?> +
    + errors as $error): ?> +
  • + +
+ + +
+ Personal data + + + + + + + + + + + + + + + + + +
getLabel('Your name:') ?>control->cols(35) ?> error ?>
getLabel('Your age:') ?>control->cols(5) ?> error ?>
getLabel('Your gender:') ?>control ?> error ?>
getLabel('Email:') ?>control->cols(35) ?> error ?>
+
+ +
+ getControl('Send') ?> +
+ + render('end'); ?> + + diff --git a/vendor/nette/forms/license.md b/vendor/nette/forms/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/forms/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as is" and +any express or implied warranties, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose are +disclaimed. In no event shall the copyright owner or contributors be liable for +any direct, indirect, incidental, special, exemplary, or consequential damages +(including, but not limited to, procurement of substitute goods or services; +loss of use, data, or profits; or business interruption) however caused and on +any theory of liability, whether in contract, strict liability, or tort +(including negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/forms/package.json b/vendor/nette/forms/package.json new file mode 100644 index 00000000..80897b18 --- /dev/null +++ b/vendor/nette/forms/package.json @@ -0,0 +1,30 @@ +{ + "type": "module", + "devDependencies": { + "@nette/eslint-plugin": "^0.1.2", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^16.0.1", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^12.1.2", + "@vitest/ui": "^4.1.9", + "eslint": "^9.26.0", + "globals": "^15.3.0", + "jsdom": "^27.3.0", + "rollup": "^4.40.2", + "rollup-plugin-dts": "^6.2.1", + "terser": "^5.39.1", + "typescript": "^5.8.3", + "typescript-eslint": "^8.32.1", + "vitest": "^4.1.9" + }, + "scripts": { + "typecheck": "tsc -noemit", + "lint": "eslint --cache", + "lint:fix": "eslint --cache --fix", + "test": "vitest run", + "test:watch": "vitest", + "test:ui": "vitest --ui", + "build": "rollup -c", + "postbuild": "npm run test" + } +} diff --git a/vendor/nette/forms/readme.md b/vendor/nette/forms/readme.md new file mode 100644 index 00000000..bb555244 --- /dev/null +++ b/vendor/nette/forms/readme.md @@ -0,0 +1,93 @@ +Nette Forms: greatly facilitates web forms +========================================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/forms.svg)](https://packagist.org/packages/nette/forms) +[![Tests](https://github.com/nette/forms/actions/workflows/tests.yml/badge.svg?branch=v3.3)](https://github.com/nette/forms/actions) +[![Coverage Status](https://coveralls.io/repos/github/nette/forms/badge.svg?branch=v3.3)](https://coveralls.io/github/nette/forms?branch=v3.3) +[![Latest Stable Version](https://poser.pugx.org/nette/forms/v/stable)](https://github.com/nette/forms/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/forms/blob/v3.3/license.md) + + +Introduction +------------ + +Nette\Forms greatly facilitates creating and processing web forms. What it can really do? + +- validate sent data both client-side (JavaScript) and server-side +- provide high level of security +- multiple render modes +- translations, i18n + +Why should you bother setting up framework for a simple web form? You won't have to take care about routine tasks such as writing two validation scripts (client and server) and your code will be safe against security breaches. + +Nette Framework puts a great effort to be safe and since forms are the most common user input, Nette forms are as good as impenetrable. All is maintained dynamically and transparently, nothing has to be set manually. Well known vulnerabilities such as Cross Site Scripting (XSS) and Cross-Site Request Forgery (CSRF) are filtered, as well as special control characters. All inputs are checked for UTF-8 validity. Every multiple-choice, select box and similar are checked for forged values upon validating. Sounds good? Let's try it out. + +Documentation can be found on the [website](https://doc.nette.org/forms). + + +[Support Me](https://github.com/sponsors/dg) +-------------------------------------------- + +Do you like Nette Forms? Are you looking forward to the new features? + +[![Buy me a coffee](https://files.nette.org/icons/donation-3.svg)](https://github.com/sponsors/dg) + +Thank you! + + +Installation +------------ + +The recommended way to install is via Composer: + +``` +composer require nette/forms +``` + +It requires PHP version 8.3 and supports PHP up to 8.5. + + +Client-side support can be installed with npm or yarn: + +``` +npm install nette-forms +``` + +Usage +----- + +Let's create a simple registration form: + +```php +use Nette\Forms\Form; + +$form = new Form; + +$form->addText('name', 'Name:'); +$form->addPassword('password', 'Password:'); +$form->addSubmit('send', 'Register'); + +echo $form; // renders the form +``` +Though we mentioned validation, yet our form has none. Let's fix it. We require users to tell us their name, so we should call a `setRequired()` method, which optional argument is an error message to show, if user does not fill his name in: + +```php +$form->addText('name', 'Name:') + ->setRequired('Please fill your name.'); +``` + +Try submitting a form without the name - you will keep seeing this message until you meet the validation rules. All that is left for us is setting up JavaScript rules. Luckily it's a piece of cake. We only have to link `netteForms.js`, which is located at `/client-side/forms` in the distribution package. + +```html + +``` + +Nette Framework adds `required` class to all mandatory elements. Adding the following style will turn label of *name* input to red. + +```html + +``` + +[Continue…](https://doc.nette.org/en/forms). diff --git a/vendor/nette/forms/rollup.config.js b/vendor/nette/forms/rollup.config.js new file mode 100644 index 00000000..8a369754 --- /dev/null +++ b/vendor/nette/forms/rollup.config.js @@ -0,0 +1,78 @@ +import json from '@rollup/plugin-json'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import typescript from '@rollup/plugin-typescript'; +import terser from '@rollup/plugin-terser'; +import dts from 'rollup-plugin-dts'; + + +// adds a header and calls initOnLoad() in the browser +function fix() { + return { + renderChunk(code) { + code = `/*! + * NetteForms - simple form validation. + * + * This file is part of the Nette Framework (https://nette.org) + * Copyright (c) 2004 David Grudl (https://davidgrudl.com) + */ +` + + code; + code = code.replace('global.Nette = factory()', 'global.Nette?.noInit ? (global.Nette = factory()) : (global.Nette = factory()).initOnLoad()'); + code = code.replace(/\/\*\*.*\* \*\//s, ''); + return code; + }, + }; +} + +function spaces2tabs() { + return { + renderChunk(code) { + return code.replaceAll(' ', '\t'); + }, + }; +} + + +export default [ + { + input: 'src/assets/index.umd.ts', + output: [ + { + format: 'umd', + name: 'Nette', + dir: 'src/assets', + entryFileNames: 'netteForms.js', + generatedCode: 'es2015', + }, + { + format: 'umd', + name: 'Nette', + dir: 'src/assets', + entryFileNames: 'netteForms.min.js', + generatedCode: 'es2015', + plugins: [ + terser(), + ], + }, + ], + plugins: [ + json(), + nodeResolve(), + typescript(), + fix(), + spaces2tabs(), + ], + }, + + { + input: 'src/assets/index.umd.ts', + output: [{ + file: 'src/assets/netteForms.d.ts', + format: 'es', + }], + plugins: [ + dts(), + spaces2tabs(), + ], + }, +]; diff --git a/vendor/nette/forms/src/Bridges/FormsDI/FormsExtension.php b/vendor/nette/forms/src/Bridges/FormsDI/FormsExtension.php new file mode 100644 index 00000000..95207d0c --- /dev/null +++ b/vendor/nette/forms/src/Bridges/FormsDI/FormsExtension.php @@ -0,0 +1,44 @@ +} $config + */ +class FormsExtension extends Nette\DI\CompilerExtension +{ + public function __construct() + { + $this->config = new class { + /** @var string[] */ + public array $messages = []; + }; + } + + + public function afterCompile(Nette\PhpGenerator\ClassType $class): void + { + $initialize = $this->initialization ?? $class->getMethod('initialize'); + + foreach ($this->config->messages as $name => $text) { + if (defined('Nette\Forms\Form::' . $name)) { + $initialize->addBody('Nette\Forms\Validator::$messages[Nette\Forms\Form::?] = ?;', [$name, $text]); + } elseif (defined($name)) { + $initialize->addBody('Nette\Forms\Validator::$messages[' . $name . '] = ?;', [$text]); + } else { + throw new Nette\InvalidArgumentException('Constant Nette\Forms\Form::' . $name . ' or constant ' . $name . ' does not exist.'); + } + } + } +} diff --git a/vendor/nette/forms/src/Bridges/FormsLatte/FormsExtension.php b/vendor/nette/forms/src/Bridges/FormsLatte/FormsExtension.php new file mode 100644 index 00000000..a985e0a5 --- /dev/null +++ b/vendor/nette/forms/src/Bridges/FormsLatte/FormsExtension.php @@ -0,0 +1,52 @@ + Nodes\FormNode::create(...), + 'formContext' => Nodes\FormNode::create(...), + 'formContainer' => Nodes\FormContainerNode::create(...), + 'label' => Nodes\LabelNode::create(...), + 'input' => Nodes\InputNode::create(...), + 'inputError' => Nodes\InputErrorNode::create(...), + 'formPrint' => Nodes\FormPrintNode::create(...), + 'formClassPrint' => Nodes\FormPrintNode::create(...), + 'n:name' => function (Latte\Compiler\Tag $tag) { + assert($tag->htmlElement !== null); + return yield from strtolower($tag->htmlElement->name) === 'form' + ? Nodes\FormNNameNode::create($tag) + : Nodes\FieldNNameNode::create($tag); + }, + ]; + } + + + public function getProviders(): array + { + return [ + 'forms' => new Runtime, + ]; + } + + + public function getCacheKey(Latte\Engine $engine): mixed + { + return 2; + } +} diff --git a/vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php b/vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php new file mode 100644 index 00000000..9699a69a --- /dev/null +++ b/vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php @@ -0,0 +1,131 @@ +,

+ + + + + + + + + '; +echo Tracy\Helpers::escapeHtml($title) /* pos 22:9 */; +echo ': '; +echo Tracy\Helpers::escapeHtml($exception->getMessage()) /* pos 22:19 */; +echo Tracy\Helpers::escapeHtml($code) /* pos 22:45 */; +echo ' + +'; +if (count($chain) > 1) /* pos 24:2 */ { + echo ' +'; +} +echo ' + + + + + + +'; +require __DIR__ . '/content.phtml'; +echo ' + +\'use strict\'; +'; +echo str_replace([' + + + + +Server Error + + + +
+
+

Server Error

+ +

We\'re sorry! The server encountered an internal error and + was unable to complete your request. Please try again later.

+ +

error 500 | '; +echo Tracy\Helpers::escapeHtml(date('j. n. Y H:i')) /* pos 27:32 */; +echo ''; +if (!$logged) /* pos 27:60 */ { + echo '
Tracy is unable to log error.'; +} +echo '

+
+
+ + + document.body.insertBefore(document.getElementById(\'tracy-error\'), document.body.firstChild); + if (navigator.webdriver) { + console.error(\'Tracy: Server Error 500. '; +if ($logged) /* pos 34:43 */ { + echo 'Details have been logged on the server.'; +} else /* pos 34:94 */ { + echo 'Tracy was unable to log the error.'; +} +echo '\'); + } + +'; diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Describer.php b/vendor/tracy/tracy/src/Tracy/Dumper/Describer.php new file mode 100644 index 00000000..d71b6746 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Describer.php @@ -0,0 +1,347 @@ + */ + public array $keysToHide = []; + + /** @var ?(callable(string $key, mixed $value, ?string $class): bool) */ + public $scrubber; + + public bool $location = false; + + /** @var array> */ + public array $resourceExposers = []; + + /** @var array> */ + public array $objectExposers = []; + + /** @var array */ + public array $enumProperties = []; + + /** @var array */ + public array $references = []; + + + public function describe(mixed $var): \stdClass + { + uksort($this->objectExposers, fn($a, $b): int => $b === '' || (class_exists($a, autoload: false) && is_subclass_of($a, $b)) ? -1 : 1); + + try { + return (object) [ + 'value' => $this->describeVar($var), + 'snapshot' => $this->snapshot, + 'location' => $this->location ? self::findDumpCallSite() : null, + ]; + + } finally { + $free = [[], []]; + $this->snapshot = &$free[0]; + $this->references = &$free[1]; + } + } + + + private function describeVar(mixed $var, int $depth = 0, ?int $refId = null): mixed + { + if ($var === null || is_bool($var)) { + return $var; + } + + $m = 'describe' . explode(' ', gettype($var))[0]; + return $this->$m($var, $depth, $refId); + } + + + private function describeInteger(int $num): Value|int + { + return $num <= self::JsSafeInteger && $num >= -self::JsSafeInteger + ? $num + : new Value(Value::TypeNumber, "$num"); + } + + + private function describeDouble(float $num): Value|float + { + if (is_nan($num)) { + return new Value(Value::TypeNumber, 'NAN'); + } elseif (is_infinite($num)) { + return new Value(Value::TypeNumber, $num < 0 ? '-INF' : 'INF'); + } + + $js = json_encode($num); + return strpos($js, '.') + ? $num + : new Value(Value::TypeNumber, "$js.0"); // to distinct int and float in JS + } + + + private function describeString(string $s, int $depth = 0): Value|string + { + $encoded = Helpers::encodeString($s, $depth ? $this->maxLength : null); + if ($encoded === $s) { + return $encoded; + } elseif (Helpers::isUtf8($s)) { + return new Value(Value::TypeStringHtml, $encoded, Helpers::utf8Length($s)); + } else { + return new Value(Value::TypeBinaryHtml, $encoded, strlen($s)); + } + } + + + /** + * @param mixed[] $arr + * @return Value|array + */ + private function describeArray(array $arr, int $depth = 0, ?int $refId = null): Value|array + { + if ($refId) { + $res = new Value(Value::TypeRef, 'p' . $refId); + $value = &$this->snapshot[$res->value]; + if ($value && $value->depth <= $depth) { + return $res; + } + + $value = new Value(Value::TypeArray); + $value->id = $res->value; + $value->depth = $depth; + if ($this->maxDepth && $depth >= $this->maxDepth) { + $value->length = count($arr); + return $res; + } elseif ($depth && $this->maxItems && count($arr) > $this->maxItems) { + $value->length = count($arr); + $arr = array_slice($arr, 0, $this->maxItems, preserve_keys: true); + } + + $items = &$value->items; + + } elseif ($arr && $this->maxDepth && $depth >= $this->maxDepth) { + return new Value(Value::TypeArray, null, count($arr)); + + } elseif ($depth && $this->maxItems && count($arr) > $this->maxItems) { + $res = new Value(Value::TypeArray, null, count($arr)); + $res->depth = $depth; + $items = &$res->items; + $arr = array_slice($arr, 0, $this->maxItems, preserve_keys: true); + } + + $items = []; + foreach ($arr as $k => $v) { + $refId = $this->getReferenceId($arr, $k); + $items[] = [ + $this->describeVar($k, $depth + 1), + $this->isSensitive((string) $k, $v) + ? new Value(Value::TypeText, self::hideValue($v)) + : $this->describeVar($v, $depth + 1, $refId), + ] + ($refId ? [2 => $refId] : []); + } + + return $res ?? $items; + } + + + private function describeObject(object $obj, int $depth = 0): Value + { + $id = spl_object_id($obj); + $value = &$this->snapshot[$id]; + if ($value && $value->depth <= $depth) { + return new Value(Value::TypeRef, $id); + } + + $value = new Value(Value::TypeObject, get_debug_type($obj)); + $value->id = $id; + $value->depth = $depth; + $value->holder = $obj; // to be not released by garbage collector in collecting mode + if ($this->location) { + $rc = $obj instanceof \Closure + ? new \ReflectionFunction($obj) + : new \ReflectionClass($obj); + if ($rc->getFileName() && ($editor = Helpers::editorUri($rc->getFileName(), $rc->getStartLine() ?: null))) { + $value->editor = (object) ['file' => $rc->getFileName(), 'line' => $rc->getStartLine(), 'url' => $editor]; + } + } + + if ($this->maxDepth && $depth < $this->maxDepth) { + $value->items = []; + $props = $this->exposeObject($obj, $value); + foreach ($props ?? [] as $k => $v) { + $this->addPropertyTo($value, (string) $k, $v, Value::PropertyVirtual, $this->getReferenceId($props ?? [], $k)); + } + } + + return new Value(Value::TypeRef, $id); + } + + + /** + * @param resource $resource + */ + private function describeResource($resource, int $depth = 0): Value + { + $id = 'r' . (int) $resource; + $value = &$this->snapshot[$id]; + if (!$value) { + $type = is_resource($resource) ? get_resource_type($resource) : 'closed'; + $value = new Value(Value::TypeResource, $type . ' resource'); + $value->id = $id; + $value->depth = $depth; + $value->items = []; + if (isset($this->resourceExposers[$type])) { + foreach (($this->resourceExposers[$type])($resource) as $k => $v) { + $value->items[] = [htmlspecialchars($k), $this->describeVar($v, $depth + 1)]; + } + } + } + + return new Value(Value::TypeRef, $id); + } + + + public function describeKey(string $key): Value|string + { + if (preg_match('#^[\w!\#$%&*+./;<>?@^{|}~-]{1,50}$#D', $key) && !preg_match('#^(true|false|null)$#iD', $key)) { + return $key; + } + + $value = $this->describeString($key); + return is_string($value) // ensure result is Value + ? new Value(Value::TypeStringHtml, $key, Helpers::utf8Length($key)) + : $value; + } + + + public function addPropertyTo( + Value $value, + string $k, + mixed $v, + int $type = Value::PropertyVirtual, + ?int $refId = null, + ?string $class = null, + ?Value $described = null, + ): void + { + if ($value->depth && $this->maxItems && count($value->items ?? []) >= $this->maxItems) { + $value->length = ($value->length ?? count($value->items ?? [])) + 1; + return; + } + + $class ??= is_string($value->value) ? $value->value : null; + $value->items[] = [ + $this->describeKey($k), + $type !== Value::PropertyVirtual && $this->isSensitive($k, $v, $class) + ? new Value(Value::TypeText, self::hideValue($v)) + : ($described ?? $this->describeVar($v, $value->depth + 1, $refId)), + $type === Value::PropertyPrivate ? $class : $type, + ] + ($refId ? [3 => $refId] : []); + } + + + /** @return ?array */ + private function exposeObject(object $obj, Value $value): ?array + { + foreach ($this->objectExposers as $type => $dumper) { + if (!$type || $obj instanceof $type) { + return $dumper($obj, $value, $this); + } + } + + if ($this->debugInfo && method_exists($obj, '__debugInfo')) { + return $obj->__debugInfo(); + } + + Exposer::exposeObject($obj, $value, $this); + return null; + } + + + private function isSensitive(string $key, mixed $val, ?string $class = null): bool + { + return $val instanceof \SensitiveParameterValue + || ($this->scrubber !== null && ($this->scrubber)($key, $val, $class)) + || isset($this->keysToHide[strtolower($key)]) + || isset($this->keysToHide[strtolower($class . '::$' . $key)]); + } + + + private static function hideValue(mixed $val): string + { + if ($val instanceof \SensitiveParameterValue) { + $val = $val->getValue(); + } + + return self::HiddenValue . ' (' . get_debug_type($val) . ')'; + } + + + /** @param class-string $class */ + public function describeEnumProperty(string $class, string $property, mixed $value): ?Value + { + [$set, $constants] = $this->enumProperties["$class::$property"] ?? [false, []]; + if (!is_int($value) + || !$constants + || !($constants = Helpers::decomposeFlags($value, $set, $constants)) + ) { + return null; + } + + $constants = array_map(fn(string $const): string => str_replace("$class::", 'self::', $const), $constants); + return new Value(Value::TypeNumber, implode(' | ', $constants) . " ($value)"); + } + + + /** @param mixed[] $arr */ + public function getReferenceId(array $arr, string|int $key): ?int + { + return ($rr = \ReflectionReference::fromArrayElement($arr, $key)) + ? ($this->references[$rr->getId()] ??= count($this->references) + 1) + : null; + } + + + /** + * Finds the location where dump() was called and extracts the call's source snippet. + * @return ?array{string, int, string} + */ + private static function findDumpCallSite(): ?array + { + $location = Helpers::findCallerLocation(); + if (!$location || !($lines = @file($location['file']))) { // @ - file may not be readable + return null; + } + + $line = $lines[$location['line'] - 1]; + return [ + $location['file'], + $location['line'], + trim(preg_match('#\w*dump(er::\w+)?\(.*\)#i', $line, $m) ? $m[0] : $line), + ]; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php b/vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php new file mode 100644 index 00000000..5bee48b4 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php @@ -0,0 +1,287 @@ + */ + public static ?array $terminalColors = [ + 'bool' => '1;33', + 'null' => '1;33', + 'number' => '1;32', + 'string' => '1;36', + 'array' => '1;31', + 'public' => '1;37', + 'protected' => '1;37', + 'private' => '1;37', + 'dynamic' => '1;37', + 'virtual' => '1;37', + 'object' => '1;31', + 'resource' => '1;37', + 'indent' => '1;30', + ]; + + /** @var array */ + public static array $resources = [ + 'stream' => 'stream_get_meta_data', + 'stream-context' => 'stream_context_get_options', + 'curl' => 'curl_getinfo', + ]; + + /** @var array */ + public static array $objectExporters = [ + \Closure::class => [Exposer::class, 'exposeClosure'], + \UnitEnum::class => [Exposer::class, 'exposeEnum'], + \ArrayObject::class => [Exposer::class, 'exposeArrayObject'], + \SplFileInfo::class => [Exposer::class, 'exposeSplFileInfo'], + \SplObjectStorage::class => [Exposer::class, 'exposeSplObjectStorage'], + \__PHP_Incomplete_Class::class => [Exposer::class, 'exposePhpIncompleteClass'], + \Generator::class => [Exposer::class, 'exposeGenerator'], + \Fiber::class => [Exposer::class, 'exposeFiber'], + \DOMNode::class => [Exposer::class, 'exposeDOMNode'], + \DOMNodeList::class => [Exposer::class, 'exposeDOMNodeList'], + \DOMNamedNodeMap::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\Node::class => [Exposer::class, 'exposeDOMNode'], + Dom\NodeList::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\NamedNodeMap::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\TokenList::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\HTMLCollection::class => [Exposer::class, 'exposeDOMNodeList'], + Ds\Collection::class => [Exposer::class, 'exposeDsCollection'], + Ds\Seq::class => [Exposer::class, 'exposeDsCollection'], + Ds\Set::class => [Exposer::class, 'exposeDsCollection'], + Ds\Heap::class => [Exposer::class, 'exposeDsCollection'], + Ds\Map::class => [Exposer::class, 'exposeDsMap'], + \WeakMap::class => [Exposer::class, 'exposeWeakMap'], + ]; + + /** @var array */ + private static array $enumProperties = []; + + private Describer $describer; + private Renderer $renderer; + + + /** + * Dumps variable to the output. + * @template T + * @param T $var + * @param array $options + * @return T + */ + public static function dump(mixed $var, array $options = []): mixed + { + if (Helpers::isCli()) { + $useColors = self::$terminalColors && Helpers::detectColors(); + $dumper = new self($options); + fwrite(STDOUT, $dumper->asTerminal($var, $useColors ? self::$terminalColors ?? [] : [])); + + } elseif (Helpers::isHtmlMode()) { + $options[self::LOCATION] ??= true; + self::renderAssets(); + echo self::toHtml($var, $options); + + } else { + echo self::toText($var, $options); + } + + return $var; + } + + + /** + * Dumps variable to HTML. + * @param array $options + */ + public static function toHtml(mixed $var, array $options = [], mixed $key = null): string + { + return (new self($options))->asHtml($var, $key); + } + + + /** + * Returns variable dump as plain text. + * @param array $options + */ + public static function toText(mixed $var, array $options = [], mixed $key = null): string + { + return (new self($options))->asTerminal($var, [], $key); + } + + + /** + * Returns variable dump as ANSI-colored terminal output. + * @param array $options + */ + public static function toTerminal(mixed $var, array $options = []): string + { + return (new self($options))->asTerminal($var, self::$terminalColors ?? []); + } + + + /** + * Renders \n"; + } + } + + + /** @param array $options */ + private function __construct(array $options = []) + { + $location = $options[self::LOCATION] ?? 0; + $location = $location === true ? ~0 : (int) $location; + + $describer = $this->describer = new Describer; + $describer->maxDepth = (int) ($options[self::DEPTH] ?? $describer->maxDepth); + $describer->maxLength = (int) ($options[self::TRUNCATE] ?? $describer->maxLength); + $describer->maxItems = (int) ($options[self::ITEMS] ?? $describer->maxItems); + $describer->debugInfo = (bool) ($options[self::DEBUGINFO] ?? $describer->debugInfo); + $describer->scrubber = $options[self::SCRUBBER] ?? $describer->scrubber; + $describer->keysToHide = array_flip(array_map(strtolower(...), $options[self::KEYS_TO_HIDE] ?? [])); + $describer->resourceExposers = ($options['resourceExporters'] ?? []) + self::$resources; + $describer->objectExposers = ($options[self::OBJECT_EXPORTERS] ?? []) + self::$objectExporters; + $describer->enumProperties = self::$enumProperties; + $describer->location = (bool) $location; + if ($options[self::LIVE] ?? false) { + $tmp = &self::$liveSnapshot; + } elseif (isset($options[self::SNAPSHOT])) { + $tmp = &$options[self::SNAPSHOT]; + } + + if (isset($tmp)) { + $tmp[0] ??= []; + $tmp[1] ??= []; + $describer->snapshot = &$tmp[0]; + $describer->references = &$tmp[1]; + } + + $renderer = $this->renderer = new Renderer; + $renderer->collapseTop = $options[self::COLLAPSE] ?? $renderer->collapseTop; + $renderer->collapseSub = $options[self::COLLAPSE_COUNT] ?? $renderer->collapseSub; + $renderer->collectingMode = isset($options[self::SNAPSHOT]) || !empty($options[self::LIVE]); + $renderer->lazy = $renderer->collectingMode + ? true + : ($options[self::LAZY] ?? $renderer->lazy); + $renderer->sourceLocation = !(~$location & self::LOCATION_SOURCE); + $renderer->classLocation = !(~$location & self::LOCATION_CLASS); + $renderer->theme = ($options[self::THEME] ?? $renderer->theme) ?: null; + $renderer->hash = $options[self::HASH] ?? true; + } + + + /** + * Dumps variable to HTML. + */ + private function asHtml(mixed $var, mixed $key = null): string + { + if ($key === null) { + $model = $this->describer->describe($var); + } else { + $model = $this->describer->describe([$key => $var]); + $model->value = $model->value[0][1]; + } + + return $this->renderer->renderAsHtml($model); + } + + + /** + * Dumps variable to x-terminal. + * @param array $colors + */ + private function asTerminal(mixed $var, array $colors = [], mixed $key = null): string + { + if ($key === null) { + $model = $this->describer->describe($var); + } else { + $model = $this->describer->describe([$key => $var]); + $model->value = $model->value[0][1]; + } + + return $this->renderer->renderAsText($model, $colors); + } + + + /** @param array{0?: Dumper\Value[], 1?: mixed[]} $snapshot */ + public static function formatSnapshotAttribute(array &$snapshot): string + { + $res = "'" . Helpers::jsonEncode($snapshot[0] ?? []) . "'"; + $snapshot = []; + return $res; + } + + + /** + * @param class-string $class + * @param string[] $constants + */ + public static function addEnumProperty(string $class, string $property, array $constants, bool $set = false): void + { + self::$enumProperties["$class::$property"] = [$set, $constants]; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php b/vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php new file mode 100644 index 00000000..35a0165d --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php @@ -0,0 +1,310 @@ += 80400 && (new \ReflectionClass($obj))->isUninitializedLazyObject($obj)) { + self::exposeLazyObject($obj, $describer, $value); + return; + } + + $values = get_mangled_object_vars($obj); + $props = self::getProperties($obj::class); + + foreach (array_diff_key((array) $obj, $values) as $k => $v) { + $describer->addPropertyTo($value, (string) $k, $v); + } + + foreach (array_diff_key($values, $props) as $k => $v) { + $describer->addPropertyTo( + $value, + (string) $k, + $v, + Value::PropertyDynamic, + $describer->getReferenceId($values, $k), + ); + } + + foreach ($props as $k => [$name, $class, $type]) { + if (array_key_exists($k, $values)) { + $describer->addPropertyTo( + $value, + $name, + $values[$k], + $type, + $describer->getReferenceId($values, $k), + $class, + $describer->describeEnumProperty($class, $name, $values[$k]), + ); + } else { + $describer->addPropertyTo( + $value, + $name, + null, + $type, + class: $class, + described: new Value(Value::TypeText, 'unset'), + ); + } + } + } + + + /** + * @param class-string $class + * @return array + */ + private static function getProperties(string $class): array + { + static $cache; + if (isset($cache[$class])) { + return $cache[$class]; + } + + $rc = new \ReflectionClass($class); + $parentProps = $rc->getParentClass() ? self::getProperties($rc->getParentClass()->getName()) : []; + $props = []; + + foreach ($rc->getProperties() as $prop) { + $name = $prop->getName(); + if ($prop->isStatic() || $prop->getDeclaringClass()->getName() !== $class) { + // nothing + } elseif ($prop->isPrivate()) { + $props["\x00" . $class . "\x00" . $name] = [$name, $class, Value::PropertyPrivate]; + } elseif ($prop->isProtected()) { + $props["\x00*\x00" . $name] = [$name, $class, Value::PropertyProtected]; + } else { + $props[$name] = [$name, $class, Value::PropertyPublic]; + unset($parentProps["\x00*\x00" . $name]); + } + } + + return $cache[$class] = $props + $parentProps; + } + + + public static function exposeClosure(\Closure $obj, Value $value, Describer $describer): void + { + $rc = new \ReflectionFunction($obj); + if ($describer->location) { + $describer->addPropertyTo($value, 'file', $rc->getFileName() . ':' . $rc->getStartLine()); + } + + $params = []; + foreach ($rc->getParameters() as $param) { + $params[] = '$' . $param->getName(); + } + + $value->value .= '(' . implode(', ', $params) . ')'; + + $uses = []; + $useValue = new Value(Value::TypeObject); + $useValue->depth = $value->depth + 1; + foreach ($rc->getStaticVariables() as $name => $v) { + $uses[] = '$' . $name; + $describer->addPropertyTo($useValue, '$' . $name, $v); + } + + if ($uses) { + $useValue->value = implode(', ', $uses); + $useValue->collapsed = true; + $describer->addPropertyTo($value, 'use', null, described: $useValue); + } + } + + + public static function exposeEnum(\UnitEnum $enum, Value $value, Describer $describer): void + { + $value->value = $enum::class . '::' . $enum->name; + if ($enum instanceof \BackedEnum) { + $describer->addPropertyTo($value, 'value', $enum->value); + $value->collapsed = true; + } + } + + + public static function exposeArrayObject(\ArrayObject $obj, Value $value, Describer $describer): void + { + $flags = $obj->getFlags(); + $obj->setFlags(\ArrayObject::STD_PROP_LIST); + self::exposeObject($obj, $value, $describer); + $obj->setFlags($flags); + $describer->addPropertyTo($value, 'storage', $obj->getArrayCopy(), Value::PropertyPrivate, null, \ArrayObject::class); + $value->value .= ' (' . count($obj) . ')'; + } + + + public static function exposeDOMNode(\DOMNode|Dom\Node $obj, Value $value, Describer $describer): void + { + $props = preg_match_all('#^\s*\[([^\]]+)\] =>#m', print_r($obj, return: true), $tmp) ? $tmp[1] : []; + sort($props); + foreach ($props as $p) { + $describer->addPropertyTo($value, $p, @$obj->$p, Value::PropertyPublic); // @ some props may be deprecated + } + } + + + public static function exposeDOMNodeList( + \DOMNodeList|\DOMNamedNodeMap|Dom\NodeList|Dom\NamedNodeMap|Dom\TokenList|Dom\HTMLCollection $obj, + Value $value, + Describer $describer, + ): void + { + $describer->addPropertyTo($value, 'length', $obj->length, Value::PropertyPublic); + $describer->addPropertyTo($value, 'items', iterator_to_array($obj)); + } + + + public static function exposeGenerator(\Generator $gen, Value $value, Describer $describer): void + { + try { + $r = new \ReflectionGenerator($gen); + $describer->addPropertyTo($value, 'file', $r->getExecutingFile() . ':' . $r->getExecutingLine()); + $describer->addPropertyTo($value, 'this', $r->getThis()); + } catch (\ReflectionException) { + $value->value = $gen::class . ' (terminated)'; + } + } + + + public static function exposeFiber(\Fiber $fiber, Value $value, Describer $describer): void + { + if ($fiber->isTerminated()) { + $value->value = $fiber::class . ' (terminated)'; + } elseif (!$fiber->isStarted()) { + $value->value = $fiber::class . ' (not started)'; + } else { + $r = new \ReflectionFiber($fiber); + $describer->addPropertyTo($value, 'file', $r->getExecutingFile() . ':' . $r->getExecutingLine()); + $describer->addPropertyTo($value, 'callable', $r->getCallable()); + } + } + + + /** @return array{path: string} */ + public static function exposeSplFileInfo(\SplFileInfo $obj): array + { + return ['path' => $obj->getPathname()]; + } + + + public static function exposeSplObjectStorage(\SplObjectStorage $obj, Value $value, Describer $describer): void + { + $value->value .= ' (' . count($obj) . ')'; + foreach (clone $obj as $v) { + $pair = new Value(Value::TypeObject, ''); + $pair->depth = $value->depth + 1; + $describer->addPropertyTo($pair, 'key', $v); + $describer->addPropertyTo($pair, 'value', $obj[$v]); + $describer->addPropertyTo($value, '', null, described: $pair); + assert($value->items !== null); + $value->items[count($value->items) - 1][0] = ''; + } + } + + + public static function exposeWeakMap(\WeakMap $obj, Value $value, Describer $describer): void + { + $value->value .= ' (' . count($obj) . ')'; + foreach ($obj as $k => $v) { + $pair = new Value(Value::TypeObject, ''); + $pair->depth = $value->depth + 1; + $describer->addPropertyTo($pair, 'key', $k); + $describer->addPropertyTo($pair, 'value', $v); + $describer->addPropertyTo($value, '', null, described: $pair); + assert($value->items !== null); + $value->items[count($value->items) - 1][0] = ''; + } + } + + + public static function exposePhpIncompleteClass( + \__PHP_Incomplete_Class $obj, + Value $value, + Describer $describer, + ): void + { + $values = get_mangled_object_vars($obj); + $class = $values['__PHP_Incomplete_Class_Name']; + unset($values['__PHP_Incomplete_Class_Name']); + foreach ($values as $k => $v) { + $refId = $describer->getReferenceId($values, $k); + if (isset($k[0]) && $k[0] === "\x00") { + $info = explode("\00", $k); + $k = end($info); + $type = $info[1] === '*' ? Value::PropertyProtected : Value::PropertyPrivate; + $decl = $type === Value::PropertyPrivate ? $info[1] : null; + } else { + $type = Value::PropertyPublic; + $k = (string) $k; + $decl = null; + } + + $describer->addPropertyTo($value, $k, $v, $type, $refId, $decl); + } + + $value->value = $class . ' (Incomplete Class)'; + } + + + public static function exposeDsCollection( + Ds\Collection|Ds\Seq|Ds\Set|Ds\Heap $obj, + Value $value, + Describer $describer, + ): void + { + foreach (clone $obj as $k => $v) { + $describer->addPropertyTo($value, (string) $k, $v); + } + } + + + public static function exposeDsMap( + Ds\Map $obj, + Value $value, + Describer $describer, + ): void + { + $i = 0; + foreach ($obj as $k => $v) { + $describer->addPropertyTo($value, (string) $i++, new Ds\Pair($k, $v)); + } + } + + + private static function exposeLazyObject(object $obj, Describer $describer, Value $value): void + { + $rc = new \ReflectionClass($obj); + foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { + if (!$prop->isLazy($obj)) { + $describer->addPropertyTo( + $value, + $prop->getName(), + $prop->getValue($obj), + Value::PropertyPublic, + described: $describer->describeEnumProperty($obj::class, $prop->getName(), $prop->getValue($obj)), + ); + } + } + + $value->value .= ' (lazy)'; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php b/vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php new file mode 100644 index 00000000..e849c6f7 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php @@ -0,0 +1,417 @@ +value; + $this->snapshot = $model->snapshot; + + if ($this->lazy === false) { // no lazy-loading + $html = $this->renderVar($value); + $json = $snapshot = null; + + } elseif ($this->lazy && (is_array($value) && $value || is_object($value))) { // full lazy-loading + $html = ''; + $snapshot = $this->collectingMode ? null : $this->snapshot; + $json = $value; + + } else { // lazy-loading of collapsed parts + $html = $this->renderVar($value); + $snapshot = $this->snapshotSelection; + $json = null; + } + } finally { + $this->parents = $this->snapshot = $this->above = []; + $this->snapshotSelection = null; + } + + $location = null; + if ($model->location && $this->sourceLocation) { + [$file, $line, $code] = $model->location; + $uri = Helpers::editorUri($file, $line); + $location = Helpers::formatHtml( + '', + $uri ?? '#', + $file, + $line, + $uri ? "\nClick to open in editor" : '', + ) . Helpers::encodeString($code, 50) . " 📍"; + } + + return '
 100 ? "\n" : '')
+			. '>'
+			. $location
+			. $html
+			. "
\n"; + } + + + /** @param array $colors */ + public function renderAsText(\stdClass $model, array $colors = []): string + { + try { + $this->snapshot = $model->snapshot; + $this->lazy = false; + $s = $this->renderVar($model->value); + } finally { + $this->parents = $this->snapshot = $this->above = []; + } + + $s = $colors ? Helpers::htmlToAnsi($s, $colors) : Helpers::htmlToText($s); + $s = str_replace('…', '...', $s); + $s .= str_ends_with($s, "\n") ? '' : "\n"; + + if ($this->sourceLocation && ([$file, $line] = $model->location)) { + $s .= "in $file:$line\n"; + } + + return $s; + } + + + private function renderVar(mixed $value, int $depth = 0, string|int|null $keyType = null): string + { + return match (true) { + $value === null => 'null', + is_bool($value) => '' . ($value ? 'true' : 'false') . '', + is_int($value) => '' . $value . '', + is_float($value) => '' . Helpers::jsonEncode($value) . '', + is_string($value) => $this->renderString($value, $depth, $keyType), + is_array($value), $value->type === Value::TypeArray => $this->renderArray($value, $depth), + $value->type === Value::TypeRef => $this->renderVar($this->snapshot[$value->value], $depth, $keyType), + $value->type === Value::TypeObject => $this->renderObject($value, $depth), + $value->type === Value::TypeNumber => '' . Helpers::escapeHtml($value->value) . '', + $value->type === Value::TypeText => '' . Helpers::escapeHtml($value->value) . '', + $value->type === Value::TypeStringHtml, $value->type === Value::TypeBinaryHtml => $this->renderString($value, $depth, $keyType), + $value->type === Value::TypeResource => $this->renderResource($value, $depth), + default => throw new \Exception('Unknown type'), + }; + } + + + private function renderString(string|Value $str, int $depth, string|int|null $keyType): string + { + if ($keyType === self::TypeArrayKey) { + $indent = ' ' . str_repeat('| ', $depth - 1) . ' '; + return '' + . "'" + . (is_string($str) ? Helpers::escapeHtml($str) : str_replace("\n", "\n" . $indent, (string) $str->value)) + . "'" + . ''; + + } elseif ($keyType !== null) { + $classes = [ + Value::PropertyPublic => 'tracy-dump-public', + Value::PropertyProtected => 'tracy-dump-protected', + Value::PropertyDynamic => 'tracy-dump-dynamic', + Value::PropertyVirtual => 'tracy-dump-virtual', + ]; + $indent = ' ' . str_repeat('| ', $depth - 1) . ' '; + $title = is_string($keyType) + ? ' title="declared in ' . Helpers::escapeHtml($keyType) . '"' + : null; + return '' + . (is_string($str) + ? Helpers::escapeHtml($str) + : "'" . str_replace("\n", "\n" . $indent, (string) $str->value) . "'") + . ''; + + } elseif (is_string($str)) { + $len = Helpers::utf8Length($str); + return ' 1 ? ' title="' . $len . ' characters"' : '') + . '>' + . "'" + . Helpers::escapeHtml($str) + . "'" + . ''; + + } else { + $unit = $str->type === Value::TypeStringHtml ? 'characters' : 'bytes'; + $count = substr_count((string) $str->value, "\n"); + if ($count) { + $collapsed = $indent1 = $toggle = null; + $indent = ' '; + if ($depth) { + $collapsed = $count >= $this->collapseSub; + $indent1 = ' ' . str_repeat('| ', $depth) . ''; + $indent = ' ' . str_repeat('| ', $depth) . ' '; + $toggle = 'string' . "\n"; + } + + return $toggle + . '
' + . $indent1 + . ''" + . str_replace("\n", "\n" . $indent, (string) $str->value) + . "'" + . ($depth ? "\n" : '') + . '
'; + } + + return 'length > 1 ? " title=\"{$str->length} $unit\"" : '') + . '>' + . "'" + . $str->value + . "'" + . ''; + } + } + + + /** @param mixed[]|Value $array */ + private function renderArray(array|Value $array, int $depth): string + { + $out = 'array ('; + + if (is_array($array)) { + $items = $array; + $count = count($items); + $out .= $count . ')'; + } elseif ($array->items === null) { + return $out . $array->length . ') …'; + } else { + $items = $array->items; + $count = $array->length ?? count($items); + $out .= $count . ')'; + if ($array->id && isset($this->parents[$array->id])) { + return $out . ' RECURSION'; + + } elseif ($array->id && ($array->depth < $depth || isset($this->above[$array->id]))) { + if ($this->lazy !== false) { + $ref = new Value(Value::TypeRef, $array->id); + $this->copySnapshot($ref); + return '" . $out . ''; + + } elseif ($this->hash) { + return $out . (isset($this->above[$array->id]) ? ' see above' : ' see below'); + } + } + } + + if (!$count) { + return $out; + } + + $collapsed = $depth + ? ($this->lazy === false || $depth === 1 ? $count >= $this->collapseSub : true) + : (is_int($this->collapseTop) ? $count >= $this->collapseTop : $this->collapseTop); + + $span = 'lazy !== false) { + $array = isset($array->id) ? new Value(Value::TypeRef, $array->id) : $array; + $this->copySnapshot($array); + return $span . " data-tracy-dump='" . Helpers::jsonEncode($array) . "'>" . $out . ''; + } + + $out = $span . '>' . $out . "\n" . ''; + $indent = ' ' . str_repeat('| ', $depth) . ''; + $this->parents[$array->id ?? ''] = $this->above[$array->id ?? ''] = true; + + foreach ($items as $info) { + [$k, $v, $ref] = $info + [2 => null]; + $out .= $indent + . $this->renderVar($k, $depth + 1, self::TypeArrayKey) + . ' => ' + . ($ref && $this->hash ? '&' . $ref . ' ' : '') + . ($tmp = $this->renderVar($v, $depth + 1)) + . (str_ends_with($tmp, '') ? '' : "\n"); + } + + if ($count > count($items)) { + $out .= $indent . "…\n"; + } + + unset($this->parents[$array->id ?? '']); + return $out . ''; + } + + + private function renderObject(Value $object, int $depth): string + { + $editorAttributes = ''; + if ($this->classLocation && $object->editor) { + $editorAttributes = Helpers::formatHtml( + ' title="Declared in file % on line %%%" data-tracy-href="%"', + $object->editor->file, + $object->editor->line, + $object->editor->url ? "\nCtrl-Click to open in editor" : '', + "\nAlt-Click to expand/collapse all child nodes", + $object->editor->url, + ); + } + + $name = (string) $object->value; + $pos = strrpos($name, '\\'); + $out = '' + . ($pos + ? Helpers::escapeHtml(substr($name, 0, $pos + 1)) . '' . Helpers::escapeHtml(substr($name, $pos + 1)) . '' + : Helpers::escapeHtml($name)) + . '' + . ($object->id && $this->hash ? ' #' . $object->id . '' : ''); + + if ($object->items === null) { + return $out . ' …'; + + } elseif (!$object->items) { + return $out; + + } elseif ($object->id && isset($this->parents[$object->id])) { + return $out . ' RECURSION'; + + } elseif ($object->id && ($object->depth < $depth || isset($this->above[$object->id]))) { + if ($this->lazy !== false) { + $ref = new Value(Value::TypeRef, $object->id); + $this->copySnapshot($ref); + return '" . $out . ''; + + } elseif ($this->hash) { + return $out . (isset($this->above[$object->id]) ? ' see above' : ' see below'); + } + } + + $collapsed = $object->collapsed ?? ($depth + ? ($this->lazy === false || $depth === 1 ? count($object->items) >= $this->collapseSub : true) + : (is_int($this->collapseTop) ? count($object->items) >= $this->collapseTop : $this->collapseTop)); + + $span = 'lazy !== false) { + $value = $object->id ? new Value(Value::TypeRef, $object->id) : $object; + $this->copySnapshot($value); + return $span . " data-tracy-dump='" . Helpers::jsonEncode($value) . "'>" . $out . ''; + } + + $out = $span . '>' . $out . "\n" . ''; + $indent = ' ' . str_repeat('| ', $depth) . ''; + $this->parents[$object->id ?? ''] = $this->above[$object->id ?? ''] = true; + + foreach ($object->items as $info) { + [$k, $v, $type, $ref] = $info + [2 => Value::PropertyVirtual, null]; + $out .= $indent + . $this->renderVar($k, $depth + 1, $type) + . ': ' + . ($ref && $this->hash ? '&' . $ref . ' ' : '') + . ($tmp = $this->renderVar($v, $depth + 1)) + . (str_ends_with($tmp, '') ? '' : "\n"); + } + + if ($object->length > count($object->items)) { + $out .= $indent . "…\n"; + } + + unset($this->parents[$object->id ?? '']); + return $out . ''; + } + + + private function renderResource(Value $resource, int $depth): string + { + $out = '' . Helpers::escapeHtml((string) $resource->value) . ' ' + . ($this->hash ? '@' . substr((string) $resource->id, 1) . '' : ''); + + if (!$resource->items) { + return $out; + + } elseif (isset($this->above[$resource->id])) { + if ($this->lazy !== false) { + $ref = new Value(Value::TypeRef, $resource->id); + $this->copySnapshot($ref); + return '" . $out . ''; + } + + return $out . ' see above'; + + } else { + $this->above[$resource->id] = true; + $out = "$out\n
"; + foreach ($resource->items as [$k, $v]) { + $out .= ' ' . str_repeat('| ', $depth) . '' + . $this->renderVar($k, $depth + 1, Value::PropertyVirtual) + . ': ' + . ($tmp = $this->renderVar($v, $depth + 1)) + . (str_ends_with($tmp, '
') ? '' : "\n"); + } + + return $out . ''; + } + } + + + private function copySnapshot(mixed $value): void + { + if ($this->collectingMode) { + return; + } + + if ($this->snapshotSelection === null) { + $this->snapshotSelection = []; + } + + if (is_array($value)) { + foreach ($value as [, $v]) { + $this->copySnapshot($v); + } + } elseif ($value instanceof Value && $value->type === Value::TypeRef) { + if (!isset($this->snapshotSelection[$value->value])) { + $ref = $this->snapshotSelection[$value->value] = $this->snapshot[$value->value]; + $this->copySnapshot($ref); + } + } elseif ($value instanceof Value && $value->items) { + foreach ($value->items as [, $v]) { + $this->copySnapshot($v); + } + } + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Value.php b/vendor/tracy/tracy/src/Tracy/Dumper/Value.php new file mode 100644 index 00000000..c129cb03 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Value.php @@ -0,0 +1,66 @@ +|null */ + public ?array $items = null; + public ?\stdClass $editor = null; + public ?bool $collapsed = null; + + + public function __construct(string $type, string|int|null $value = null, ?int $length = null) + { + $this->type = $type; + $this->value = $value; + $this->length = $length; + } + + + /** @return array */ + public function jsonSerialize(): array + { + $res = [$this->type => $this->value]; + foreach (['length', 'editor', 'items', 'collapsed'] as $k) { + if ($this->$k !== null) { + $res[$k] = $this->$k; + } + } + + return $res; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css new file mode 100644 index 00000000..8346d721 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css @@ -0,0 +1,145 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-dump.tracy-dark { + text-align: left; + color: #f8f8f2; + background: #29292e; + border-radius: 4px; + padding: var(--tracy-space); + margin: var(--tracy-space) 0; + word-break: break-all; + white-space: pre-wrap; +} + +.tracy-dump.tracy-dark div { + padding-left: 2.5ex; +} + +.tracy-dump.tracy-dark div div { + border-left: 1px solid rgba(255, 255, 255, .1); + margin-left: .5ex; +} + +.tracy-dump.tracy-dark div div:hover { + border-left-color: rgba(255, 255, 255, .25); +} + +.tracy-dark .tracy-dump-location { + color: silver; + font-size: 80%; + text-decoration: none; + background: none; + opacity: .5; + float: right; + cursor: pointer; +} + +.tracy-dark .tracy-dump-location:hover, +.tracy-dark .tracy-dump-location:focus { + opacity: 1; +} + +.tracy-dark .tracy-dump-array, +.tracy-dark .tracy-dump-object { + color: #f69c2e; + user-select: text; +} + +.tracy-dark .tracy-dump-string { + color: #3cdfef; + white-space: break-spaces; +} + +.tracy-dark div.tracy-dump-string { + position: relative; + padding-left: 3.5ex; +} + +.tracy-dark .tracy-dump-lq { + margin-left: calc(-1ex - 1px); +} + +.tracy-dark div.tracy-dump-string:before { + content: ''; + position: absolute; + left: calc(3ex - 1px); + top: 1.5em; + bottom: 0; + border-left: 1px solid rgba(255, 255, 255, .1); +} + +.tracy-dark .tracy-dump-virtual span, +.tracy-dark .tracy-dump-dynamic span, +.tracy-dark .tracy-dump-string span { + color: rgba(255, 255, 255, 0.5); +} + +.tracy-dark .tracy-dump-virtual i, +.tracy-dark .tracy-dump-dynamic i, +.tracy-dark .tracy-dump-string i { + font-size: 80%; + font-style: normal; + color: rgba(255, 255, 255, 0.5); + user-select: none; +} + +.tracy-dark .tracy-dump-number { + color: #77d285; +} + +.tracy-dark .tracy-dump-null, +.tracy-dark .tracy-dump-bool { + color: #f3cb44; +} + +.tracy-dark .tracy-dump-virtual { + font-style: italic; +} + +.tracy-dark .tracy-dump-public::after { + content: ' pub'; +} + +.tracy-dark .tracy-dump-protected::after { + content: ' pro'; +} + +.tracy-dark .tracy-dump-private::after { + content: ' pri'; +} + +.tracy-dark .tracy-dump-public::after, +.tracy-dark .tracy-dump-protected::after, +.tracy-dark .tracy-dump-private::after, +.tracy-dark .tracy-dump-hash { + font-size: 85%; + color: rgba(255, 255, 255, 0.35); +} + +.tracy-dark .tracy-dump-indent { + display: none; +} + +.tracy-dark .tracy-dump-highlight { + background: #C22; + color: white; + border-radius: 2px; + padding: 0 2px; + margin: 0 -2px; +} + +span[data-tracy-href] { + border-bottom: 1px dotted rgba(255, 255, 255, .2); +} + +.tracy-dark .tracy-dump-flash { + animation: tracy-dump-flash .2s ease; +} + +@keyframes tracy-dump-flash { + 0% { + background: #c0c0c033; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css new file mode 100644 index 00000000..fb865920 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css @@ -0,0 +1,145 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-dump.tracy-light { + text-align: left; + color: #444; + background: #fdf9e2; + border-radius: 4px; + padding: var(--tracy-space); + margin: var(--tracy-space) 0; + word-break: break-all; + white-space: pre-wrap; +} + +.tracy-dump.tracy-light div { + padding-left: 2.5ex; +} + +.tracy-dump.tracy-light div div { + border-left: 1px solid rgba(0, 0, 0, .1); + margin-left: .5ex; +} + +.tracy-dump.tracy-light div div:hover { + border-left-color: rgba(0, 0, 0, .25); +} + +.tracy-light .tracy-dump-location { + color: gray; + font-size: 80%; + text-decoration: none; + background: none; + opacity: .5; + float: right; + cursor: pointer; +} + +.tracy-light .tracy-dump-location:hover, +.tracy-light .tracy-dump-location:focus { + opacity: 1; +} + +.tracy-light .tracy-dump-array, +.tracy-light .tracy-dump-object { + color: #C22; + user-select: text; +} + +.tracy-light .tracy-dump-string { + color: #35D; + white-space: break-spaces; +} + +.tracy-light div.tracy-dump-string { + position: relative; + padding-left: 3.5ex; +} + +.tracy-light .tracy-dump-lq { + margin-left: calc(-1ex - 1px); +} + +.tracy-light div.tracy-dump-string:before { + content: ''; + position: absolute; + left: calc(3ex - 1px); + top: 1.5em; + bottom: 0; + border-left: 1px solid rgba(0, 0, 0, .1); +} + +.tracy-light .tracy-dump-virtual span, +.tracy-light .tracy-dump-dynamic span, +.tracy-light .tracy-dump-string span { + color: rgba(0, 0, 0, 0.5); +} + +.tracy-light .tracy-dump-virtual i, +.tracy-light .tracy-dump-dynamic i, +.tracy-light .tracy-dump-string i { + font-size: 80%; + font-style: normal; + color: rgba(0, 0, 0, 0.5); + user-select: none; +} + +.tracy-light .tracy-dump-number { + color: #090; +} + +.tracy-light .tracy-dump-null, +.tracy-light .tracy-dump-bool { + color: #850; +} + +.tracy-light .tracy-dump-virtual { + font-style: italic; +} + +.tracy-light .tracy-dump-public::after { + content: ' pub'; +} + +.tracy-light .tracy-dump-protected::after { + content: ' pro'; +} + +.tracy-light .tracy-dump-private::after { + content: ' pri'; +} + +.tracy-light .tracy-dump-public::after, +.tracy-light .tracy-dump-protected::after, +.tracy-light .tracy-dump-private::after, +.tracy-light .tracy-dump-hash { + font-size: 85%; + color: rgba(0, 0, 0, 0.35); +} + +.tracy-light .tracy-dump-indent { + display: none; +} + +.tracy-light .tracy-dump-highlight { + background: #C22; + color: white; + border-radius: 2px; + padding: 0 2px; + margin: 0 -2px; +} + +span[data-tracy-href] { + border-bottom: 1px dotted rgba(0, 0, 0, .2); +} + +.tracy-light .tracy-dump-flash { + animation: tracy-dump-flash .2s ease; +} + +@keyframes tracy-dump-flash { + 0% { + background: #c0c0c033; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js new file mode 100644 index 00000000..81417ad7 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js @@ -0,0 +1,392 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +const + COLLAPSE_COUNT = 7, + COLLAPSE_COUNT_TOP = 14, + TYPE_ARRAY = 'a', + TYPE_OBJECT = 'o', + TYPE_RESOURCE = 'r', + PROP_VIRTUAL = 4, + PROP_PRIVATE = 2; + +const + HINT_CTRL = 'Ctrl-Click to open in editor', + HINT_ALT = 'Alt-Click to expand/collapse all child nodes'; + +class Dumper { + static init(context) { + // full lazy + (context || document).querySelectorAll('[data-tracy-snapshot][data-tracy-dump]').forEach((pre) => { //
+			let snapshot = JSON.parse(pre.getAttribute('data-tracy-snapshot'));
+			pre.removeAttribute('data-tracy-snapshot');
+			pre.appendChild(build(JSON.parse(pre.getAttribute('data-tracy-dump')), snapshot, pre.classList.contains('tracy-collapsed')));
+			pre.removeAttribute('data-tracy-dump');
+			pre.classList.remove('tracy-collapsed');
+		});
+
+		// snapshots
+		(context || document).querySelectorAll('meta[itemprop=tracy-snapshot]').forEach((meta) => {
+			let snapshot = JSON.parse(meta.getAttribute('content'));
+			meta.parentElement.querySelectorAll('[data-tracy-dump]').forEach((pre) => { // 
+				if (pre.closest('[data-tracy-snapshot]')) { // ignore unrelated 
+					return;
+				}
+				pre.appendChild(build(JSON.parse(pre.getAttribute('data-tracy-dump')), snapshot, pre.classList.contains('tracy-collapsed')));
+				pre.removeAttribute('data-tracy-dump');
+				pre.classList.remove('tracy-collapsed');
+			});
+			//  must be left for debug bar panel content
+		});
+
+		if (Dumper.inited) {
+			return;
+		}
+		Dumper.inited = true;
+
+		document.documentElement.addEventListener('click', (e) => {
+			let el;
+			// enables  & ctrl or cmd key
+			if ((e.ctrlKey || e.metaKey) && (el = e.target.closest('[data-tracy-href]'))) {
+				location.href = el.getAttribute('data-tracy-href');
+				return false;
+			}
+
+		});
+
+		document.documentElement.addEventListener('tracy-beforetoggle', (e) => {
+			let el;
+			// initializes lazy  inside 
+			if ((el = e.target.closest('[data-tracy-snapshot]'))) {
+				let snapshot = JSON.parse(el.getAttribute('data-tracy-snapshot'));
+				el.removeAttribute('data-tracy-snapshot');
+				el.querySelectorAll('[data-tracy-dump]').forEach((toggler) => {
+					if (!toggler.nextSibling) {
+						toggler.after(document.createTextNode('\n')); // enforce \n after toggler
+					}
+					toggler.nextSibling.after(buildStruct(JSON.parse(toggler.getAttribute('data-tracy-dump')), snapshot, toggler, true, []));
+					toggler.removeAttribute('data-tracy-dump');
+				});
+			}
+		});
+
+		document.documentElement.addEventListener('tracy-toggle', (e) => {
+			if (!e.target.matches('.tracy-dump *')) {
+				return;
+			}
+
+			let cont = e.detail.relatedTarget;
+			let origE = e.detail.originalEvent;
+
+			if (origE && origE.usedIds) { // triggered by expandChild()
+				toggleChildren(cont, origE.usedIds);
+				return;
+
+			} else if (origE && origE.altKey && cont.querySelector('.tracy-toggle')) { // triggered by alt key
+				if (e.detail.collapsed) { // reopen
+					e.target.classList.toggle('tracy-collapsed', false);
+					cont.classList.toggle('tracy-collapsed', false);
+					e.detail.collapsed = false;
+				}
+
+				let expand = e.target.tracyAltExpand = !e.target.tracyAltExpand;
+				toggleChildren(cont, expand ? {} : false);
+			}
+
+			cont.classList.toggle('tracy-dump-flash', !e.detail.collapsed);
+		});
+
+		document.documentElement.addEventListener('animationend', (e) => {
+			if (e.animationName === 'tracy-dump-flash') {
+				e.target.classList.toggle('tracy-dump-flash', false);
+			}
+		});
+
+		document.addEventListener('mouseover', (e) => {
+			if (!e.target.matches('.tracy-dump *')) {
+				return;
+			}
+
+			let el;
+
+			if (e.target.matches('.tracy-dump-hash') && (el = e.target.closest('tracy-div'))) {
+				el.querySelectorAll('.tracy-dump-hash').forEach((el) => {
+					if (el.textContent === e.target.textContent) {
+						el.classList.add('tracy-dump-highlight');
+					}
+				});
+				return;
+			}
+
+			if ((el = e.target.closest('.tracy-toggle')) && !el.title) {
+				el.title = HINT_ALT;
+			}
+		});
+
+		document.addEventListener('mouseout', (e) => {
+			if (e.target.matches('.tracy-dump-hash')) {
+				document.querySelectorAll('.tracy-dump-hash.tracy-dump-highlight').forEach((el) => {
+					el.classList.remove('tracy-dump-highlight');
+				});
+			}
+		});
+
+		Tracy.Toggle.init();
+	}
+}
+
+
+function build(data, repository, collapsed, parentIds, keyType) {
+	let id, type = data === null ? 'null' : typeof data,
+		collapseCount = collapsed === null ? COLLAPSE_COUNT : COLLAPSE_COUNT_TOP;
+
+	if (type === 'null' || type === 'number' || type === 'boolean') {
+		return createEl(null, null, [
+			createEl(
+				'span',
+				{ class: 'tracy-dump-' + type.replace('ean', '') },
+				[data + ''],
+			),
+		]);
+
+	} else if (type === 'string') {
+		data = {
+			string: data.replace(/&/g, '&').replace(/\'' + s + '\'' },
+				),
+			]);
+
+		} else if (keyType !== undefined) {
+			if (type !== 'string') {
+				s = '\'' + s + '\'';
+			}
+
+			const classes = [
+				'tracy-dump-public',
+				'tracy-dump-protected',
+				'tracy-dump-private',
+				'tracy-dump-dynamic',
+				'tracy-dump-virtual',
+			];
+			return createEl(null, null, [
+				createEl(
+					'span',
+					{
+						class: classes[typeof keyType === 'string' ? PROP_PRIVATE : keyType],
+						title: typeof keyType === 'string' ? 'declared in ' + keyType : null,
+					},
+					{ html: s },
+				),
+			]);
+		}
+
+		let count = (s.match(/\n/g) || []).length;
+		if (count) {
+			let collapsed = count >= COLLAPSE_COUNT;
+			return createEl(null, null, [
+				createEl('span', { class: collapsed ? 'tracy-toggle tracy-collapsed' : 'tracy-toggle' }, ['string']),
+				'\n',
+				createEl(
+					'div',
+					{
+						class: 'tracy-dump-string' + (collapsed ? ' tracy-collapsed' : ''),
+						title: data.length + (data.bin ? ' bytes' : ' characters'),
+					},
+					{ html: '\'' + s + '\'' },
+				),
+			]);
+		}
+
+		return createEl(null, null, [
+			createEl(
+				'span',
+				{
+					class: 'tracy-dump-string',
+					title: data.length + (data.bin ? ' bytes' : ' characters'),
+				},
+				{ html: '\'' + s + '\'' },
+			),
+		]);
+
+	} else if (data.number) {
+		return createEl(null, null, [
+			createEl('span', { class: 'tracy-dump-number' }, [data.number]),
+		]);
+
+	} else if (data.text !== undefined) {
+		return createEl(null, null, [
+			createEl('span', { class: 'tracy-dump-virtual' }, [data.text]),
+		]);
+
+	} else { // object || resource || array
+		let pos, nameEl;
+		nameEl = data.object && (pos = data.object.lastIndexOf('\\')) > 0
+			? [data.object.substr(0, pos + 1), createEl('b', null, [data.object.substr(pos + 1)])]
+			: [data.object || data.resource];
+
+		let span = data.array !== undefined
+			? [
+					createEl('span', { class: 'tracy-dump-array' }, ['array']),
+					' (' + (data.length || data.items.length) + ')',
+				]
+			: [
+					createEl('span', {
+						'class': data.object ? 'tracy-dump-object' : 'tracy-dump-resource',
+						'title': data.editor ? 'Declared in file ' + data.editor.file + ' on line ' + data.editor.line + (data.editor.url ? '\n' + HINT_CTRL : '') + '\n' + HINT_ALT : null,
+						'data-tracy-href': data.editor ? data.editor.url : null,
+					}, nameEl),
+					...(id ? [' ', createEl('span', { class: 'tracy-dump-hash' }, [data.resource ? '@' + id.substr(1) : '#' + id])] : []),
+				];
+
+		parentIds = parentIds ? parentIds.slice() : [];
+		let recursive = id && parentIds.indexOf(id) > -1;
+		parentIds.push(id);
+
+		if (recursive || !data.items || !data.items.length) {
+			span.push(recursive ? ' RECURSION' : (!data.items || data.items.length ? ' …' : ''));
+			return createEl(null, null, span);
+		}
+
+		collapsed = collapsed === true || data.collapsed || (data.items && data.items.length >= collapseCount);
+		let toggle = createEl('span', { class: collapsed ? 'tracy-toggle tracy-collapsed' : 'tracy-toggle' }, span);
+
+		return createEl(null, null, [
+			toggle,
+			'\n',
+			buildStruct(data, repository, toggle, collapsed, parentIds),
+		]);
+	}
+}
+
+
+function buildStruct(data, repository, toggle, collapsed, parentIds) {
+	if (Array.isArray(data)) {
+		data = { items: data };
+
+	} else if (data.ref) {
+		parentIds = parentIds.slice();
+		parentIds.push(data.ref);
+		data = repository[data.ref];
+	}
+
+	let cut = data.items && data.length > data.items.length;
+	let type = data.object ? TYPE_OBJECT : data.resource ? TYPE_RESOURCE : TYPE_ARRAY;
+	let div = createEl('div', { class: collapsed ? 'tracy-collapsed' : null });
+
+	if (collapsed) {
+		let handler;
+		toggle.addEventListener('tracy-toggle', handler = function () {
+			toggle.removeEventListener('tracy-toggle', handler);
+			createItems(div, data.items, type, repository, parentIds, null);
+			if (cut) {
+				createEl(div, null, ['…\n']);
+			}
+		});
+	} else {
+		createItems(div, data.items, type, repository, parentIds, true);
+		if (cut) {
+			createEl(div, null, ['…\n']);
+		}
+	}
+
+	return div;
+}
+
+
+function createEl(el, attrs, content) {
+	if (!(el instanceof Node)) {
+		el = el ? document.createElement(el) : document.createDocumentFragment();
+	}
+	for (let id in attrs || {}) {
+		if (attrs[id] !== null) {
+			el.setAttribute(id, attrs[id]);
+		}
+	}
+
+	if (content && content.html !== undefined) {
+		el.innerHTML = content.html;
+		return el;
+	}
+
+	content = content || [];
+	el.append(...content.filter((child) => (child !== null)));
+	return el;
+}
+
+
+function createItems(el, items, type, repository, parentIds, collapsed) {
+	let key, val, vis, ref, i, tmp;
+
+	for (i = 0; i < items.length; i++) {
+		if (type === TYPE_ARRAY) {
+			[key, val, ref] = items[i];
+		} else {
+			[key, val, vis = PROP_VIRTUAL, ref] = items[i];
+		}
+
+		createEl(el, null, [
+			build(key, null, null, null, type === TYPE_ARRAY ? TYPE_ARRAY : vis),
+			type === TYPE_ARRAY ? ' => ' : ': ',
+			...(ref ? [createEl('span', { class: 'tracy-dump-hash' }, ['&' + ref]), ' '] : []),
+			tmp = build(val, repository, collapsed, parentIds),
+			tmp.lastElementChild.tagName === 'DIV' ? '' : '\n',
+		]);
+	}
+}
+
+
+function toggleChildren(cont, usedIds) {
+	let hashEl, id;
+
+	cont.querySelectorAll(':scope > .tracy-toggle').forEach((el) => {
+		hashEl = (el.querySelector('.tracy-dump-hash') || el.previousElementSibling);
+		id = hashEl && hashEl.matches('.tracy-dump-hash') ? hashEl.textContent : null;
+
+		if (!usedIds || (id && usedIds[id])) {
+			Tracy.Toggle.toggle(el, false);
+		} else {
+			usedIds[id] = true;
+			Tracy.Toggle.toggle(el, true, { usedIds: usedIds });
+		}
+	});
+}
+
+
+function UnknownEntityException() {}
+
+
+let Tracy = window.Tracy = window.Tracy || {};
+Tracy.Dumper = Tracy.Dumper || Dumper;
+
+function init() {
+	Tracy.Dumper.init();
+}
+
+if (document.readyState === 'loading') {
+	document.addEventListener('DOMContentLoaded', init);
+} else {
+	init();
+}
diff --git a/vendor/tracy/tracy/src/Tracy/Helpers.php b/vendor/tracy/tracy/src/Tracy/Helpers.php
new file mode 100644
index 00000000..e439f078
--- /dev/null
+++ b/vendor/tracy/tracy/src/Tracy/Helpers.php
@@ -0,0 +1,761 @@
+%%%',
+				$editor,
+				$origFile . ($line ? ":$line" : ''),
+				rtrim(dirname($file), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR,
+				basename($file),
+				$line ? ":$line" : '',
+			);
+		} else {
+			return self::formatHtml('%', $file . ($line ? ":$line" : ''));
+		}
+	}
+
+
+	/**
+	 * Returns link to editor.
+	 */
+	public static function editorUri(
+		string $file,
+		?int $line = null,
+		string $action = 'open',
+		string $search = '',
+		string $replace = '',
+	): ?string
+	{
+		if (Debugger::$editor && $file && ($action === 'create' || @is_file($file))) { // @ - may trigger error
+			$file = strtr($file, '/', DIRECTORY_SEPARATOR);
+			$file = strtr($file, Debugger::$editorMapping);
+			$search = str_replace("\n", PHP_EOL, $search);
+			$replace = str_replace("\n", PHP_EOL, $replace);
+			return strtr(Debugger::$editor, [
+				'%action' => $action,
+				'%file' => rawurlencode($file),
+				'%line' => $line ?: 1,
+				'%search' => rawurlencode($search),
+				'%replace' => rawurlencode($replace),
+			]);
+		}
+
+		return null;
+	}
+
+
+	/**
+	 * Formats an HTML string by replacing each % placeholder with the next argument, HTML-escaped.
+	 */
+	public static function formatHtml(string $mask): string
+	{
+		$args = func_get_args();
+		return preg_replace_callback('#%#', function () use (&$args, &$count): string {
+			return str_replace("\n", '
', self::escapeHtml($args[++$count]));
+		}, $mask);
+	}
+
+
+	public static function escapeHtml(mixed $s): string
+	{
+		return htmlspecialchars((string) $s, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
+	}
+
+
+	public static function escapeMd(mixed $s): string
+	{
+		$s = (string) $s;
+		// inline-anywhere: \ ` * [ ] < | ~ and _ at word boundary
+		$s = preg_replace('/[\\\`*\[\]<|~]|(? always; # + need following whitespace; - = need whitespace, repeat, or EOL
+		$s = preg_replace('/(?:^|(?<=[\r\n]))(>|#(?=[\s#]|$)|\+(?=\s|$)|-(?=[\s-]|$)|=(?=[\s=]|$))/', '\\\$0', $s);
+		// line-start ordered list marker: 1-9 digits + . or ) followed by whitespace or EOL
+		return preg_replace('/(?:^|(?<=[\r\n]))(\d{1,9})([.)])(?=\s|$)/', '$1\\\$2', $s);
+	}
+
+
+	public static function htmlToText(string $s): string
+	{
+		return htmlspecialchars_decode(strip_tags($s), ENT_QUOTES | ENT_HTML5);
+	}
+
+
+	/**
+	 * Finds the file+line in user code from which a Tracy call originated.
+	 * @param  string[]|null  $paths  defaults to Debugger::$transparentPaths
+	 * @return ?array{file: string, line: int}
+	 */
+	public static function findCallerLocation(?array $paths = null): ?array
+	{
+		$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+		$n = self::countTransparentFrames($trace, $paths);
+		return isset($trace[$n]['file'], $trace[$n]['line'])
+			? ['file' => $trace[$n]['file'], 'line' => $trace[$n]['line']]
+			: null;
+	}
+
+
+	/**
+	 * Returns the index of the first user-visible frame in $trace. A frame is transparent
+	 * when its file is missing, synthetic, in $paths, or its containing function (trace[n+1])
+	 * is annotated @tracySkipLocation.
+	 * @param  list}>  $trace
+	 * @param  string[]|null  $paths  defaults to Debugger::$transparentPaths
+	 * @internal
+	 */
+	public static function countTransparentFrames(array $trace, ?array $paths = null): int
+	{
+		$paths ??= Debugger::$transparentPaths;
+		foreach ($trace as $key => $item) {
+			$next = $trace[$key + 1] ?? null;
+			$nextReflection = match (true) {
+				$next === null => null,
+				isset($next['class'], $next['function']) && method_exists($next['class'], $next['function']) => new \ReflectionMethod($next['class'], $next['function']),
+				isset($next['function']) && function_exists($next['function']) => new \ReflectionFunction($next['function']),
+				default => null,
+			};
+
+			if (isset($item['file'])
+				&& @is_file($item['file']) // @ - synthetic paths like eval()'d code, CLI, etc.
+				&& (!preg_match('#\s@tracySkipLocation\s#', (string) $nextReflection?->getDocComment()))
+			) {
+				$file = strtr($item['file'], '\\', '/') . '/';
+				foreach ($paths as $path) {
+					if (str_starts_with($file, strtr($path, '\\', '/') . '/')) {
+						continue 2;
+					}
+				}
+				return $key;
+			}
+		}
+		return count($trace);
+	}
+
+
+	/**
+	 * @param  array  $trace
+	 * @param  string|string[]  $method
+	 * @return ?array{file?: string, line?: int, class?: string, function?: string, args?: mixed[]}
+	 */
+	public static function findTrace(array $trace, array|string $method, ?int &$index = null): ?array
+	{
+		$m = is_array($method) ? $method : explode('::', $method);
+		foreach ($trace as $i => $item) {
+			if (
+				isset($item['function'])
+				&& $item['function'] === end($m)
+				&& isset($item['class']) === isset($m[1])
+				&& (!isset($item['class']) || $m[0] === '*' || is_a($item['class'], $m[0], allow_string: true))
+			) {
+				$index = $i;
+				return $item;
+			}
+		}
+
+		return null;
+	}
+
+
+	/** @internal */
+	public static function errorTypeToString(int $type): string
+	{
+		$types = [
+			E_ERROR => 'Fatal Error',
+			E_USER_ERROR => 'User Error',
+			E_RECOVERABLE_ERROR => 'Recoverable Error',
+			E_CORE_ERROR => 'Core Error',
+			E_COMPILE_ERROR => 'Compile Error',
+			E_PARSE => 'Parse Error',
+			E_WARNING => 'Warning',
+			E_CORE_WARNING => 'Core Warning',
+			E_COMPILE_WARNING => 'Compile Warning',
+			E_USER_WARNING => 'User Warning',
+			E_NOTICE => 'Notice',
+			E_USER_NOTICE => 'User Notice',
+			E_DEPRECATED => 'Deprecated',
+			E_USER_DEPRECATED => 'User Deprecated',
+		];
+		return $types[$type] ?? 'Unknown error';
+	}
+
+
+	/** @internal */
+	public static function getSource(): string
+	{
+		if (self::isCli()) {
+			return 'CLI (PID: ' . getmypid() . ')'
+				. (isset($_SERVER['argv']) ? ': ' . implode(' ', array_map(self::escapeArg(...), $_SERVER['argv'])) : '');
+
+		} elseif (isset($_SERVER['REQUEST_URI'])) {
+			return (!empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off') ? 'https://' : 'http://')
+				. ($_SERVER['HTTP_HOST'] ?? '')
+				. $_SERVER['REQUEST_URI'];
+
+		} else {
+			return PHP_SAPI;
+		}
+	}
+
+
+	/** @internal */
+	public static function improveException(\Throwable $e): void
+	{
+		$message = $e->getMessage();
+		if (
+			!($e instanceof \Error || $e instanceof \ErrorException)
+			|| str_contains($e->getMessage(), 'did you mean')
+		) {
+			// do nothing
+		} elseif (preg_match('~Argument #(\d+)(?: \(\$\w+\))? must be of type callable, (.+ given)~', $message, $m)) {
+			$arg = $e->getTrace()[0]['args'][(int) $m[1] - 1] ?? null;
+			if (is_string($arg) && str_contains($arg, '::')) {
+				$arg = explode('::', $arg, 2);
+			}
+			if (!is_callable($arg, syntax_only: true)) {
+				// do nothing
+			} elseif (is_array($arg) && is_string($arg[0]) && !class_exists($arg[0]) && !trait_exists($arg[0])) {
+				$message = str_replace($m[2], "but class '$arg[0]' does not exist", $message);
+			} elseif (is_array($arg) && !method_exists($arg[0], $arg[1])) {
+				$hint = self::getSuggestion(get_class_methods($arg[0]) ?: [], $arg[1]);
+				$class = is_object($arg[0]) ? $arg[0]::class : $arg[0];
+				$message = str_replace($m[2], "but method $class::$arg[1]() does not exist" . ($hint ? " (did you mean $hint?)" : ''), $message);
+			} elseif (is_string($arg) && !function_exists($arg)) {
+				$funcs = array_merge(get_defined_functions()['internal'], get_defined_functions()['user']);
+				$hint = self::getSuggestion($funcs, $arg);
+				$message = str_replace($m[2], "but function '$arg' does not exist" . ($hint ? " (did you mean $hint?)" : ''), $message);
+			}
+
+		} elseif (preg_match('#^Call to undefined function (\S+\\\)?(\w+)\(#', $message, $m)) {
+			$funcs = array_merge(get_defined_functions()['internal'], get_defined_functions()['user']);
+			if ($hint = self::getSuggestion($funcs, $m[1] . $m[2]) ?: self::getSuggestion($funcs, $m[2])) {
+				$message = "Call to undefined function $m[2](), did you mean $hint()?";
+				$replace = ["$m[2](", "$hint("];
+			}
+
+		} elseif (preg_match('#^Call to undefined method ([\w\\\]+)::(\w+)#', $message, $m)) {
+			if ($hint = self::getSuggestion(get_class_methods($m[1]) ?: [], $m[2])) {
+				$message .= ", did you mean $hint()?";
+				$replace = ["$m[2](", "$hint("];
+			}
+
+		} elseif (preg_match('#^Undefined property: ([\w\\\]+)::\$(\w+)#', $message, $m) && class_exists($m[1])) {
+			$rc = new \ReflectionClass($m[1]);
+			$items = array_filter($rc->getProperties(\ReflectionProperty::IS_PUBLIC), fn($prop) => !$prop->isStatic());
+			if ($hint = self::getSuggestion($items, $m[2])) {
+				$message .= ", did you mean $$hint?";
+				$replace = ["->$m[2]", "->$hint"];
+			}
+
+		} elseif (
+			preg_match('#^Access to undeclared static property:? ([\w\\\]+)::\$(\w+)#', $message, $m)
+			&& class_exists($m[1])
+		) {
+			$rc = new \ReflectionClass($m[1]);
+			$items = array_filter($rc->getProperties(\ReflectionProperty::IS_STATIC), fn($prop) => $prop->isPublic());
+			if ($hint = self::getSuggestion($items, $m[2])) {
+				$message .= ", did you mean $$hint?";
+				$replace = ["::$$m[2]", "::$$hint"];
+			}
+		}
+
+		if ($message !== $e->getMessage()) {
+			$ref = new \ReflectionProperty($e, 'message');
+			$ref->setValue($e, $message);
+		}
+
+		if (isset($replace)) {
+			$loc = Debugger::mapSource($e->getFile(), $e->getLine()) ?? ['file' => $e->getFile(), 'line' => $e->getLine()];
+			@$e->tracyAction = [ // dynamic properties are deprecated since PHP 8.2
+				'link' => self::editorUri($loc['file'], $loc['line'], 'fix', $replace[0], $replace[1]),
+				'label' => 'fix it',
+			];
+		}
+	}
+
+
+	/** @internal */
+	public static function improveError(string $message): string
+	{
+		if (preg_match('#^Undefined property: ([\w\\\]+)::\$(\w+)#', $message, $m) && class_exists($m[1])) {
+			$rc = new \ReflectionClass($m[1]);
+			$items = array_filter($rc->getProperties(\ReflectionProperty::IS_PUBLIC), fn($prop) => !$prop->isStatic());
+			$hint = self::getSuggestion($items, $m[2]);
+			return $hint ? $message . ", did you mean $$hint?" : $message;
+		}
+
+		return $message;
+	}
+
+
+	/** @internal */
+	public static function guessClassFile(string $class): ?string
+	{
+		$segments = explode('\\', $class);
+		$res = null;
+		$max = 0;
+		foreach (get_declared_classes() as $class) {
+			$parts = explode('\\', $class);
+			foreach ($parts as $i => $part) {
+				if ($part !== ($segments[$i] ?? null)) {
+					break;
+				}
+			}
+
+			if ($i > $max && $i < count($segments) && ($file = (new \ReflectionClass($class))->getFileName())) {
+				$max = $i;
+				$res = array_merge(array_slice(explode(DIRECTORY_SEPARATOR, $file), 0, $i - count($parts)), array_slice($segments, $i));
+				$res = implode(DIRECTORY_SEPARATOR, $res) . '.php';
+			}
+		}
+
+		return $res;
+	}
+
+
+	/**
+	 * Finds the best suggestion.
+	 * @param  string[]|\ReflectionMethod[]|\ReflectionProperty[]  $items
+	 * @internal
+	 */
+	public static function getSuggestion(array $items, string $value): ?string
+	{
+		$best = null;
+		$min = (strlen($value) / 4 + 1) * 10 + .1;
+		$items = array_map(fn($item) => $item instanceof \ReflectionMethod || $item instanceof \ReflectionProperty ? $item->getName() : (string) $item, $items);
+		foreach (array_unique($items) as $item) {
+			if (($len = levenshtein($item, $value, 10, 11, 10)) > 0 && $len < $min) {
+				$min = $len;
+				$best = $item;
+			}
+		}
+
+		return $best;
+	}
+
+
+	/** @internal */
+	public static function isHtmlMode(): bool
+	{
+		return empty($_SERVER['HTTP_X_REQUESTED_WITH'])
+			&& empty($_SERVER['HTTP_X_TRACY_AJAX'])
+			&& isset($_SERVER['HTTP_HOST'])
+			&& !self::isCli()
+			&& !preg_match('#^Content-Type: *+(?!text/html)#im', implode("\n", headers_list()));
+	}
+
+
+	/** @internal */
+	public static function consoleLog(string $data): void
+	{
+		echo 'console.log(' . self::jsonEncode($data, inScript: true) . ');';
+	}
+
+
+	/** @internal */
+	public static function isAgent(): bool
+	{
+		return ($_COOKIE['tracy-webdriver'] ?? null) === '1';
+	}
+
+
+	/** @internal */
+	public static function isRedirect(): bool
+	{
+		return (bool) preg_match('#^Location:#im', implode("\n", headers_list()));
+	}
+
+
+	/** @internal */
+	public static function createId(): string
+	{
+		return bin2hex(random_bytes(5));
+	}
+
+
+	/** @internal */
+	public static function isCli(): bool
+	{
+		return PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg';
+	}
+
+
+	/** @internal */
+	public static function getNonce(bool $attr = false): ?string
+	{
+		return preg_match('#^Content-Security-Policy(?:-Report-Only)?:.*\sscript-src(?:-elem)?\s+(?:[^;]+\s)?\'nonce-([\w+/]+=*)\'#mi', implode("\n", headers_list()), $m)
+			? ($attr ? ' nonce="' . self::escapeHtml($m[1]) . '"' : $m[1])
+			: null;
+	}
+
+
+	/**
+	 * Escape a string to be used as a shell argument.
+	 */
+	private static function escapeArg(string $s): string
+	{
+		if (preg_match('#^[a-z0-9._=/:-]+$#Di', $s)) {
+			return $s;
+		}
+
+		return defined('PHP_WINDOWS_VERSION_BUILD')
+			? '"' . str_replace('"', '""', $s) . '"'
+			: escapeshellarg($s);
+	}
+
+
+	/**
+	 * Captures PHP output into a string.
+	 * @param  callable(): void  $func
+	 */
+	public static function capture(callable $func): string
+	{
+		ob_start(fn() => '');
+		try {
+			$func();
+			return ob_get_clean();
+		} catch (\Throwable $e) {
+			ob_end_clean();
+			throw $e;
+		}
+	}
+
+
+	/** @internal */
+	public static function encodeString(string $s, ?int $maxLength = null, bool $showWhitespaces = true): string
+	{
+		$utf8 = self::isUtf8($s);
+		$len = $utf8 ? self::utf8Length($s) : strlen($s);
+		return $maxLength && $len > $maxLength + 20
+			? self::doEncodeString(self::truncateString($s, $maxLength, $utf8), $utf8, $showWhitespaces)
+				. ' … '
+				. self::doEncodeString(self::truncateString($s, -10, $utf8), $utf8, $showWhitespaces)
+			: self::doEncodeString($s, $utf8, $showWhitespaces);
+	}
+
+
+	private static function doEncodeString(string $s, bool $utf8, bool $showWhitespaces): string
+	{
+		$specials = [
+			true => [
+				"\r" => '\r',
+				"\n" => "\\n\n",
+				"\t" => '\t    ',
+				"\e" => '\e',
+				'<' => '<',
+				'&' => '&',
+			],
+			false => [
+				"\r" => "\r",
+				"\n" => "\n",
+				"\t" => "\t",
+				"\e" => '\e',
+				'<' => '<',
+				'&' => '&',
+			],
+		];
+		$special = $specials[$showWhitespaces];
+		$s = preg_replace_callback(
+			$utf8 ? '#[\p{C}<&]#u' : '#[\x00-\x1F\x7F-\xFF<&]#',
+			fn($m) => $special[$m[0]] ?? (strlen($m[0]) === 1
+					? '\x' . str_pad(strtoupper(dechex(ord($m[0]))), 2, '0', STR_PAD_LEFT) . ''
+					: '\u{' . strtoupper(ltrim(dechex(self::utf8Ord($m[0])), '0')) . '}'),
+			$s,
+		);
+		$s = str_replace('', '', $s);
+		$s = preg_replace('~\n$~D', '', $s);
+		return $s;
+	}
+
+
+	private static function utf8Ord(string $c): int
+	{
+		$ord0 = ord($c[0]);
+		if ($ord0 < 0x80) {
+			return $ord0;
+		} elseif ($ord0 < 0xE0) {
+			return ($ord0 << 6) + ord($c[1]) - 0x3080;
+		} elseif ($ord0 < 0xF0) {
+			return ($ord0 << 12) + (ord($c[1]) << 6) + ord($c[2]) - 0xE2080;
+		} else {
+			return ($ord0 << 18) + (ord($c[1]) << 12) + (ord($c[2]) << 6) + ord($c[3]) - 0x3C82080;
+		}
+	}
+
+
+	/** @internal */
+	public static function utf8Length(string $s): int
+	{
+		return match (true) {
+			extension_loaded('mbstring') => mb_strlen($s, 'UTF-8'),
+			extension_loaded('iconv') => iconv_strlen($s, 'UTF-8') ?: strlen($s),
+			default => strlen(@utf8_decode($s)), // deprecated
+		};
+	}
+
+
+	/** @internal */
+	public static function isUtf8(string $s): bool
+	{
+		return (bool) preg_match('##u', $s);
+	}
+
+
+	/** @internal */
+	public static function truncateString(string $s, int $len, bool $utf8): string
+	{
+		if (!$utf8) {
+			return $len < 0 ? substr($s, $len) : substr($s, 0, $len);
+		} elseif (function_exists('mb_substr')) {
+			return $len < 0
+				? mb_substr($s, $len, -$len, 'UTF-8')
+				: mb_substr($s, 0, $len, 'UTF-8');
+		} else {
+			$len < 0
+				? preg_match('#.{0,' . -$len . '}\z#us', $s, $m)
+				: preg_match("#^.{0,$len}#us", $s, $m);
+			return $m[0];
+		}
+	}
+
+
+	/**
+	 * @param  array  $colors
+	 * @internal
+	 */
+	public static function htmlToAnsi(string $s, array $colors): string
+	{
+		$stack = ['0'];
+		$s = preg_replace_callback(
+			'#<\w+(?: class=["\']tracy-(?:dump-)?([\w-]+)["\'])?[^>]*>|#',
+			function ($m) use ($colors, &$stack): string {
+				if ($m[0][1] === '/') {
+					array_pop($stack);
+				} else {
+					$stack[] = isset($m[1], $colors[$m[1]]) ? $colors[$m[1]] : '0';
+				}
+				return "\e[" . end($stack) . 'm';
+			},
+			$s,
+		);
+		$s = preg_replace('/\e\[0m( *)(?=\e)/', '$1', $s);
+		$s = self::htmlToText($s);
+		return $s;
+	}
+
+
+	/** @internal */
+	public static function minifyJs(string $s): string
+	{
+		// author: Jakub Vrana https://php.vrana.cz/minifikace-javascriptu.php
+		$last = '';
+		return preg_replace_callback(
+			<<<'XX'
+				(
+					(?:
+						(^|[-+\([{}=,:;!%^&*|?~]|/(?![/*])|return|throw) # context before regexp
+						(?:\s|//[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+						(/(?![/*])(?:\\[^\n]|[^[\n/\\]|\[(?:\\[^\n]|[^]])++)+/) # regexp
+						|(^
+							|'(?:\\.|[^\n'\\])*'
+							|"(?:\\.|[^\n"\\])*"
+							|([0-9A-Za-z_$]+)
+							|([-+]+)
+							|.
+						)
+					)(?:\s|//[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+				())sx
+				XX,
+			function ($match) use (&$last) {
+				[, $context, $regexp, $result, $word, $operator] = $match;
+				if ($word !== '') {
+					$result = ($last === 'word' ? ' ' : ($last === 'return' ? ' ' : '')) . $result;
+					$last = ($word === 'return' || $word === 'throw' || $word === 'break' ? 'return' : 'word');
+				} elseif ($operator) {
+					$result = ($last === $operator[0] ? ' ' : '') . $result;
+					$last = $operator[0];
+				} else {
+					if ($regexp) {
+						$result = $context . ($context === '/' ? ' ' : '') . $regexp;
+					}
+
+					$last = '';
+				}
+
+				return $result;
+			},
+			$s . "\n",
+		);
+	}
+
+
+	/** @internal */
+	public static function minifyCss(string $s): string
+	{
+		$last = '';
+		return preg_replace_callback(
+			<<<'XX'
+				(
+					(^
+						|'(?:\\.|[^\n'\\])*'
+						|"(?:\\.|[^\n"\\])*"
+						|([0-9A-Za-z_*#.%:()[\]-]+)
+						|.
+					)(?:\s|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+				())sx
+				XX,
+			function ($match) use (&$last) {
+				[, $result, $word] = $match;
+				if ($last === ';') {
+					$result = $result === '}' ? '}' : ';' . $result;
+					$last = '';
+				}
+
+				if ($word !== '') {
+					$result = ($last === 'word' ? ' ' : '') . $result;
+					$last = 'word';
+				} elseif ($result === ';') {
+					$last = ';';
+					$result = '';
+				} else {
+					$last = '';
+				}
+
+				return $result;
+			},
+			$s . "\n",
+		);
+	}
+
+
+	public static function detectColors(): bool
+	{
+		return self::isCli()
+			&& getenv('NO_COLOR') === false // https://no-color.org
+			&& (getenv('FORCE_COLOR')
+				|| (function_exists('sapi_windows_vt100_support')
+					? sapi_windows_vt100_support(STDOUT)
+					: @stream_isatty(STDOUT)) // @ may trigger error 'cannot cast a filtered stream on this system'
+			);
+	}
+
+
+	/** @return list<\Throwable> */
+	public static function getExceptionChain(\Throwable $ex): array
+	{
+		$res = [$ex];
+		while (($ex = $ex->getPrevious()) && !in_array($ex, $res, strict: true)) {
+			$res[] = $ex;
+		}
+
+		return $res;
+	}
+
+
+	/**
+	 * @param  callable(object): void  $callback
+	 * @param  true[]  $skip
+	 */
+	public static function traverseValue(mixed $val, callable $callback, array &$skip = [], ?string $refId = null): void
+	{
+		if (is_object($val)) {
+			$id = spl_object_id($val);
+			if (!isset($skip[$id])) {
+				$skip[$id] = true;
+				$callback($val);
+				self::traverseValue((array) $val, $callback, $skip);
+			}
+
+		} elseif (is_array($val)) {
+			if ($refId) {
+				if (isset($skip[$refId])) {
+					return;
+				}
+				$skip[$refId] = true;
+			}
+
+			foreach ($val as $k => $v) {
+				$refId = \ReflectionReference::fromArrayElement($val, $k)?->getId();
+				self::traverseValue($v, $callback, $skip, $refId);
+			}
+		}
+	}
+
+
+	/**
+	 * Decomposes an integer flags value into matching constant names.
+	 * When $set is true, finds all flags set in the value (bitmask decomposition).
+	 * When $set is false, finds a single constant that equals the value exactly.
+	 * @param  string[]  $constants
+	 * @return list|null
+	 * @internal
+	 */
+	public static function decomposeFlags(int $flags, bool $set, array $constants): ?array
+	{
+		$res = null;
+		foreach ($constants as $constant) {
+			if (defined($constant)) {
+				$v = constant($constant);
+				if ($set) {
+					if ($v && ($flags & $v) === $v) {
+						$res[] = $constant;
+						$flags &= ~$v;
+					}
+				} elseif ($flags === $v) {
+					return [$constant];
+				}
+			}
+		}
+
+		if ($flags && $res && $set) {
+			$res[] = (string) $flags;
+		}
+		return $res;
+	}
+
+
+	/**
+	 * Encodes a value to JSON safe for use in any HTML context (attributes, script tags, etc.)
+	 */
+	public static function jsonEncode(mixed $value, bool $inScript = false): string
+	{
+		$old = @ini_set('serialize_precision', '-1'); // @ may be disabled
+		try {
+			return json_encode($value, ($inScript ? JSON_HEX_TAG : 0) | JSON_HEX_APOS | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE);
+		} finally {
+			if ($old !== false) {
+				ini_set('serialize_precision', $old);
+			}
+		}
+	}
+}
diff --git a/vendor/tracy/tracy/src/Tracy/Logger/ILogger.php b/vendor/tracy/tracy/src/Tracy/Logger/ILogger.php
new file mode 100644
index 00000000..13d39cd4
--- /dev/null
+++ b/vendor/tracy/tracy/src/Tracy/Logger/ILogger.php
@@ -0,0 +1,25 @@
+directory = $directory;
+		$this->email = $email;
+		$this->blueScreen = $blueScreen;
+		$this->mailer = $this->defaultMailer(...);
+	}
+
+
+	/**
+	 * Logs message or exception to file and sends email notification.
+	 * For levels ERROR, EXCEPTION and CRITICAL it sends email.
+	 * @return ?string  logged error filename
+	 */
+	public function log(mixed $message, string $level = self::INFO)
+	{
+		if (!$this->directory) {
+			throw new \LogicException('Logging directory is not specified.');
+		} elseif (!is_dir($this->directory)) {
+			throw new \RuntimeException("Logging directory '$this->directory' is not found or is not directory.");
+		}
+
+		$exceptionFile = $message instanceof \Throwable
+			? $this->getExceptionFile($message, $level)
+			: null;
+		$line = static::formatLogLine($message, $exceptionFile);
+		$file = $this->directory . '/' . strtolower($level ?: self::INFO) . '.log';
+
+		if (!@file_put_contents($file, $line . PHP_EOL, FILE_APPEND | LOCK_EX)) { // @ is escalated to exception
+			throw new \RuntimeException("Unable to write to log file '$file'. Is directory writable?");
+		}
+
+		if ($exceptionFile) {
+			$this->logException($message, $exceptionFile);
+		}
+
+		if (in_array($level, [self::ERROR, self::EXCEPTION, self::CRITICAL], strict: true)) {
+			$this->sendEmail($message);
+		}
+
+		return $exceptionFile;
+	}
+
+
+	/**
+	 * @param  mixed  $message
+	 */
+	public static function formatMessage($message): string
+	{
+		if ($message instanceof \Throwable) {
+			$tmp = [];
+			foreach (Helpers::getExceptionChain($message) as $exception) {
+				$tmp[] = ($exception instanceof \ErrorException
+					? Helpers::errorTypeToString($exception->getSeverity()) . ': ' . $exception->getMessage()
+					: get_debug_type($exception) . ': ' . $exception->getMessage() . ($exception->getCode() ? ' #' . $exception->getCode() : '')
+				) . ' in ' . $exception->getFile() . ':' . $exception->getLine();
+			}
+
+			$message = implode("\ncaused by ", $tmp);
+
+		} elseif (!is_string($message)) {
+			$message = Dumper::toText($message);
+		}
+
+		return trim($message);
+	}
+
+
+	/**
+	 * @param  mixed  $message
+	 */
+	public static function formatLogLine($message, ?string $exceptionFile = null): string
+	{
+		return implode(' ', [
+			date('[Y-m-d H-i-s]'),
+			preg_replace('#\s*\r?\n\s*#', ' ', static::formatMessage($message)),
+			' @  ' . Helpers::getSource(),
+			$exceptionFile ? ' @@  ' . basename($exceptionFile) : null,
+		]);
+	}
+
+
+	public function getExceptionFile(\Throwable $exception, string $level = self::EXCEPTION): string
+	{
+		$data = [];
+		foreach (Helpers::getExceptionChain($exception) as $exception) {
+			$data[] = [
+				$exception::class, $exception->getMessage(), $exception->getCode(), $exception->getFile(), $exception->getLine(),
+				array_map(function (array $item): array {
+					unset($item['args']);
+					return $item;
+				}, $exception->getTrace()),
+			];
+		}
+
+		$hash = substr(hash('xxh128', serialize($data)), 0, 10);
+		assert($this->directory !== null);
+		$dir = strtr($this->directory . '/', '\/', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);
+		foreach (new \DirectoryIterator($this->directory) as $file) {
+			if (str_ends_with($file->getBasename(), "$hash.html")) {
+				return $dir . $file;
+			}
+		}
+
+		return $dir . $level . '--' . date('Y-m-d--H-i') . "--$hash.html";
+	}
+
+
+	/**
+	 * Logs exception to the file if file doesn't exist.
+	 * @return string logged error filename
+	 */
+	protected function logException(\Throwable $exception, ?string $file = null): string
+	{
+		$file ??= $this->getExceptionFile($exception);
+		$bs = $this->blueScreen ?? new BlueScreen;
+		$bs->renderToFile($exception, $file, Helpers::findCallerLocation());
+		return $file;
+	}
+
+
+	/**
+	 * @param  mixed  $message
+	 */
+	protected function sendEmail($message): void
+	{
+		$snooze = is_numeric($this->emailSnooze)
+			? $this->emailSnooze
+			: strtotime($this->emailSnooze) - time();
+
+		if (
+			$this->email
+			&& $this->mailer
+			&& @filemtime($this->directory . '/email-sent') + $snooze < time() // @ file may not exist
+			&& @file_put_contents($this->directory . '/email-sent', 'sent') // @ file may not be writable
+		) {
+			($this->mailer)($message, implode(', ', (array) $this->email));
+		}
+	}
+
+
+	/**
+	 * Default mailer.
+	 * @param  mixed  $message
+	 * @internal
+	 */
+	public function defaultMailer($message, string $email): void
+	{
+		$host = preg_replace('#[^\w.-]+#', '', $_SERVER['SERVER_NAME'] ?? php_uname('n'));
+		mail(
+			$email,
+			"PHP: An error occurred on the server $host",
+			static::formatMessage($message) . "\n\nsource: " . Helpers::getSource(),
+			implode("\r\n", [
+				'From: ' . ($this->fromEmail ?? "noreply@$host"),
+				'X-Mailer: Tracy',
+				'Content-Type: text/plain; charset=UTF-8',
+				'Content-Transfer-Encoding: 8bit',
+			]),
+		);
+	}
+}
diff --git a/vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php b/vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php
new file mode 100644
index 00000000..87b21605
--- /dev/null
+++ b/vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php
@@ -0,0 +1,83 @@
+>}> */
+	private array $list = [];
+
+
+	public static function enable(): void
+	{
+		$me = new self;
+		$me->start();
+	}
+
+
+	public function start(): void
+	{
+		foreach (get_included_files() as $file) {
+			if (file_get_contents($file, length: 3) === self::BOM) {
+				$this->list[] = [$file, 1, self::BOM, []];
+			}
+		}
+
+		ob_start($this->handler(...), 1);
+	}
+
+
+	private function handler(string $s, int $phase): string
+	{
+		$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+		if (isset($trace[0]['file'], $trace[0]['line'])) {
+			$stack = $trace;
+			unset($stack[0]['line'], $stack[0]['args']);
+			$i = count($this->list);
+			if ($i && $this->list[$i - 1][3] === $stack) {
+				$this->list[$i - 1][2] .= $s;
+			} else {
+				$this->list[] = [$trace[0]['file'], $trace[0]['line'], $s, $stack];
+			}
+		}
+
+		return $phase === PHP_OUTPUT_HANDLER_FINAL
+			? $this->renderHtml()
+			: '';
+	}
+
+
+	private function renderHtml(): string
+	{
+		$res = '';
+		foreach ($this->list as $item) {
+			$stack = [];
+			foreach (array_slice($item[3], 1) as $t) {
+				$t += ['class' => '', 'type' => '', 'function' => ''];
+				$stack[] = "$t[class]$t[type]$t[function]()"
+					. (isset($t['file'], $t['line']) ? ' in ' . basename($t['file']) . ":$t[line]" : '');
+			}
+
+			$res .= ''
+				. Helpers::editorLink($item[0], $item[1]) . ' '
+				. str_replace(self::BOM, 'BOM', Dumper::toHtml($item[2]))
+				. "
\n"; + } + + return $res . '
'; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Session/FileSession.php b/vendor/tracy/tracy/src/Tracy/Session/FileSession.php new file mode 100644 index 00000000..f3cc3e21 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Session/FileSession.php @@ -0,0 +1,110 @@ + */ + private array $data = []; + + + public function __construct( + private readonly string $dir, + ) { + } + + + public function isAvailable(): bool + { + if (!$this->file) { + $this->open(); + } + + return true; + } + + + private function open(): void + { + $id = $_COOKIE[$this->cookieName] ?? null; + if ( + !is_string($id) + || !preg_match('#^\w{10}\z#i', $id) + || !($file = @fopen($path = $this->dir . '/' . self::FilePrefix . $id, 'r+')) // intentionally @ + ) { + $id = Helpers::createId(); + setcookie($this->cookieName, $id, time() + self::CookieLifetime, '/', '', secure: false, httponly: true); + + $file = @fopen($path = $this->dir . '/' . self::FilePrefix . $id, 'c+'); // intentionally @ + if ($file === false) { + throw new \RuntimeException("Unable to create file '$path'. " . (error_get_last()['message'] ?? '')); + } + } + + if (!@flock($file, LOCK_EX)) { // intentionally @ + throw new \RuntimeException("Unable to acquire exclusive lock on '$path'. " . (error_get_last()['message'] ?? '')); + } + + $this->file = $file; + $this->data = @unserialize(stream_get_contents($this->file)) ?: []; // @ - file may be empty + + if (mt_rand() / mt_getrandmax() < $this->gcProbability) { + $this->clean(); + } + } + + + public function &getData(): array + { + return $this->data; + } + + + public function clean(): void + { + $old = strtotime('-1 week'); + foreach (glob($this->dir . '/' . self::FilePrefix . '*') ?: [] as $file) { + if (filemtime($file) < $old) { + unlink($file); + } + } + } + + + public function __destruct() + { + if (!$this->file) { + return; + } + + ftruncate($this->file, 0); + fseek($this->file, 0); + fwrite($this->file, serialize($this->data)); + flock($this->file, LOCK_UN); + fclose($this->file); + $this->file = null; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Session/NativeSession.php b/vendor/tracy/tracy/src/Tracy/Session/NativeSession.php new file mode 100644 index 00000000..b662ed2e --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Session/NativeSession.php @@ -0,0 +1,29 @@ + */ + function &getData(): array; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/helpers.js b/vendor/tracy/tracy/src/Tracy/assets/helpers.js new file mode 100644 index 00000000..83c71b8e --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/helpers.js @@ -0,0 +1,20 @@ + +function init() { + // fixes DNA-106639 "Close tabs created for opening external apps" since Opera 99 + if (navigator.userAgent.includes('OPR/')) { + document.addEventListener( + 'click', + (e) => { + e.target.closest('a[href^="editor:"]')?.setAttribute('target', '_blank'); + }, + true, + ); + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +if (!Tracy.helpers) { + init(); + Tracy.helpers = true; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/reset.css b/vendor/tracy/tracy/src/Tracy/assets/reset.css new file mode 100644 index 00000000..b0a6a6fc --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/reset.css @@ -0,0 +1,386 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +:root { + --tracy-space: 16px; +} + +@media (max-width: 600px) { + :root { + --tracy-space: 8px; + } +} + +tracy-div:not(a b), +tracy-div:not(a b) * { + font: inherit; + line-height: inherit; + color: inherit; + background: transparent; + margin: 0; + padding: 0; + border: none; + text-align: inherit; + list-style: inherit; + opacity: 1; + border-radius: 0; + box-shadow: none; + text-shadow: none; + box-sizing: border-box; + text-decoration: none; + text-transform: inherit; + white-space: inherit; + float: none; + clear: none; + max-width: initial; + min-width: initial; + max-height: initial; + min-height: initial; +} + +tracy-div:not(a b) *:hover { + color: inherit; + background: transparent; +} + +tracy-div:not(a b) *:not(svg):not(img):not(table) { + width: initial; + height: initial; +} + +tracy-div:not(a b):before, +tracy-div:not(a b):after, +tracy-div:not(a b) *:before, +tracy-div:not(a b) *:after { + all: unset; +} + +tracy-div:not(a b) b, +tracy-div:not(a b) strong { + font-weight: bold; +} + +tracy-div:not(a b) small { + font-size: smaller; +} + +tracy-div:not(a b) i, +tracy-div:not(a b) em { + font-style: italic; +} + +tracy-div:not(a b) big { + font-size: larger; +} + +tracy-div:not(a b) small, +tracy-div:not(a b) sub, +tracy-div:not(a b) sup { + font-size: smaller; +} + +tracy-div:not(a b) ins { + text-decoration: underline; +} + +tracy-div:not(a b) del { + text-decoration: line-through; +} + +tracy-div:not(a b) table { + border-collapse: collapse; +} + +tracy-div:not(a b) pre { + font-family: monospace; + white-space: pre; +} + +tracy-div:not(a b) code, +tracy-div:not(a b) kbd, +tracy-div:not(a b) samp { + font-family: monospace; +} + +tracy-div:not(a b) input { + background-color: white; + padding: 1px; + border: 1px solid; +} + +tracy-div:not(a b) textarea { + background-color: white; + border: 1px solid; + padding: 2px; + white-space: pre-wrap; +} + +tracy-div:not(a b) select { + border: 1px solid; + white-space: pre; +} + +tracy-div:not(a b) article, +tracy-div:not(a b) aside, +tracy-div:not(a b) details, +tracy-div:not(a b) div, +tracy-div:not(a b) figcaption, +tracy-div:not(a b) footer, +tracy-div:not(a b) form, +tracy-div:not(a b) header, +tracy-div:not(a b) hgroup, +tracy-div:not(a b) main, +tracy-div:not(a b) nav, +tracy-div:not(a b) section, +tracy-div:not(a b) summary, +tracy-div:not(a b) pre, +tracy-div:not(a b) p, +tracy-div:not(a b) dl, +tracy-div:not(a b) dd, +tracy-div:not(a b) dt, +tracy-div:not(a b) blockquote, +tracy-div:not(a b) figure, +tracy-div:not(a b) address, +tracy-div:not(a b) h1, +tracy-div:not(a b) h2, +tracy-div:not(a b) h3, +tracy-div:not(a b) h4, +tracy-div:not(a b) h5, +tracy-div:not(a b) h6, +tracy-div:not(a b) ul, +tracy-div:not(a b) ol, +tracy-div:not(a b) li, +tracy-div:not(a b) hr { + display: block; +} + +tracy-div:not(a b) a, +tracy-div:not(a b) b, +tracy-div:not(a b) big, +tracy-div:not(a b) code, +tracy-div:not(a b) em, +tracy-div:not(a b) i, +tracy-div:not(a b) small, +tracy-div:not(a b) span, +tracy-div:not(a b) strong { + display: inline; +} + +tracy-div:not(a b) table { + display: table; +} + +tracy-div:not(a b) tr { + display: table-row; +} + +tracy-div:not(a b) col { + display: table-column; +} + +tracy-div:not(a b) colgroup { + display: table-column-group; +} + +tracy-div:not(a b) tbody { + display: table-row-group; +} + +tracy-div:not(a b) thead { + display: table-header-group; +} + +tracy-div:not(a b) tfoot { + display: table-footer-group; +} + +tracy-div:not(a b) td { + display: table-cell; +} + +tracy-div:not(a b) th { + display: table-cell; +} + + + +/* TableSort */ +tracy-div:not(a b) .tracy-sortable > :first-child > tr:first-child > * { + position: relative; +} + +tracy-div:not(a b) .tracy-sortable > :first-child > tr:first-child > *:hover:before { + position: absolute; + right: .3em; + content: "\21C5"; + opacity: .4; + font-weight: normal; +} + + +/* dump */ +tracy-div:not(a b) .tracy-dump div { + padding-left: 3ex; +} + +tracy-div:not(a b) .tracy-dump div div { + border-left: 1px solid rgba(0, 0, 0, .1); + margin-left: .5ex; +} + +tracy-div:not(a b) .tracy-dump div div:hover { + border-left-color: rgba(0, 0, 0, .25); +} + +tracy-div:not(a b) .tracy-dump { + background: #FDF5CE; + padding: .4em .7em; + border: 1px dotted silver; + overflow: auto; +} + +tracy-div:not(a b) table .tracy-dump.tracy-dump { /* overwrite .tracy-dump.tracy-light etc. */ + padding: 0; + margin: 0; + border: none; +} + +tracy-div:not(a b) .tracy-dump-location { + color: gray; + font-size: 80%; + text-decoration: none; + background: none; + opacity: .5; + float: right; + cursor: pointer; +} + +tracy-div:not(a b) .tracy-dump-location:hover, +tracy-div:not(a b) .tracy-dump-location:focus { + color: gray; + background: none; + opacity: 1; +} + +tracy-div:not(a b) .tracy-dump-array, +tracy-div:not(a b) .tracy-dump-object { + color: #C22; +} + +tracy-div:not(a b) .tracy-dump-string { + color: #35D; + white-space: break-spaces; +} + +tracy-div:not(a b) div.tracy-dump-string { + position: relative; + padding-left: 3.5ex; +} + +tracy-div:not(a b) .tracy-dump-lq { + margin-left: calc(-1ex - 1px); +} + +tracy-div:not(a b) div.tracy-dump-string:before { + content: ''; + position: absolute; + left: calc(3ex - 1px); + top: 1.5em; + bottom: 0; + border-left: 1px solid rgba(0, 0, 0, .1); +} + +tracy-div:not(a b) .tracy-dump-virtual span, +tracy-div:not(a b) .tracy-dump-dynamic span, +tracy-div:not(a b) .tracy-dump-string span { + color: rgba(0, 0, 0, 0.5); +} + +tracy-div:not(a b) .tracy-dump-virtual i, +tracy-div:not(a b) .tracy-dump-dynamic i, +tracy-div:not(a b) .tracy-dump-string i { + font-size: 80%; + font-style: normal; + color: rgba(0, 0, 0, 0.5); + user-select: none; +} + +tracy-div:not(a b) .tracy-dump-number { + color: #090; +} + +tracy-div:not(a b) .tracy-dump-null, +tracy-div:not(a b) .tracy-dump-bool { + color: #850; +} + +tracy-div:not(a b) .tracy-dump-virtual { + font-style: italic; +} + +tracy-div:not(a b) .tracy-dump-public::after { + content: ' pub'; +} + +tracy-div:not(a b) .tracy-dump-protected::after { + content: ' pro'; +} + +tracy-div:not(a b) .tracy-dump-private::after { + content: ' pri'; +} + +tracy-div:not(a b) .tracy-dump-public::after, +tracy-div:not(a b) .tracy-dump-protected::after, +tracy-div:not(a b) .tracy-dump-private::after, +tracy-div:not(a b) .tracy-dump-hash { + font-size: 85%; + color: rgba(0, 0, 0, 0.5); +} + +tracy-div:not(a b) .tracy-dump-indent { + display: none; +} + +tracy-div:not(a b) .tracy-dump-highlight { + background: #C22; + color: white; + border-radius: 2px; + padding: 0 2px; + margin: 0 -2px; +} + +tracy-div:not(a b) span[data-tracy-href] { + border-bottom: 1px dotted rgba(0, 0, 0, .2); +} + + +/* toggle */ +tracy-div:not(a b) .tracy-toggle:after { + content: ''; + display: inline-block; + vertical-align: middle; + line-height: 0; + border-top: .6ex solid; + border-right: .6ex solid transparent; + border-left: .6ex solid transparent; + transform: scale(1, 1.5); + margin: 0 .2ex 0 .7ex; + transition: .1s transform; + opacity: .5; +} + +tracy-div:not(a b) .tracy-toggle.tracy-collapsed:after { + transform: rotate(-90deg) scale(1, 1.5) translate(.1ex, 0); +} + + +/* tabs */ +tracy-div:not(a b) .tracy-tab-label { + user-select: none; +} + +tracy-div:not(a b) .tracy-tab-panel:not(.tracy-active) { + display: none; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/table-sort.css b/vendor/tracy/tracy/src/Tracy/assets/table-sort.css new file mode 100644 index 00000000..7967a642 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/table-sort.css @@ -0,0 +1,15 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-sortable > :first-child > tr:first-child > * { + position: relative; +} + +.tracy-sortable > :first-child > tr:first-child > *:hover:before { + position: absolute; + right: .3em; + content: "\21C5"; + opacity: .4; + font-weight: normal; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/table-sort.js b/vendor/tracy/tracy/src/Tracy/assets/table-sort.js new file mode 100644 index 00000000..39bae80f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/table-sort.js @@ -0,0 +1,39 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +// enables +class TableSort { + static init() { + document.documentElement.addEventListener('click', (e) => { + if ((window.getSelection().type !== 'Range') + && e.target.matches('.tracy-sortable > :first-child > tr:first-child *') + ) { + TableSort.sort(e.target.closest('td,th')); + } + }); + + TableSort.init = function () {}; + } + + static sort(tcell) { + let tbody = tcell.closest('table').tBodies[0]; + let preserveFirst = !tcell.closest('thead') && !tcell.parentNode.querySelectorAll('td').length; + let asc = !(tbody.tracyAsc === tcell.cellIndex); + tbody.tracyAsc = asc ? tcell.cellIndex : null; + let getText = (cell) => cell ? (cell.getAttribute('data-order') || cell.innerText) : ''; + + Array.from(tbody.children) + .slice(preserveFirst ? 1 : 0) + .sort((a, b) => (function (v1, v2) { + return v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) + ? v1 - v2 + : v1.toString().localeCompare(v2, undefined, { numeric: true, sensitivity: 'base' }); + }(getText((asc ? a : b).children[tcell.cellIndex]), getText((asc ? b : a).children[tcell.cellIndex])))) + .forEach((tr) => { tbody.appendChild(tr); }); + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +Tracy.TableSort = Tracy.TableSort || TableSort; diff --git a/vendor/tracy/tracy/src/Tracy/assets/tabs.css b/vendor/tracy/tracy/src/Tracy/assets/tabs.css new file mode 100644 index 00000000..9add853a --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/tabs.css @@ -0,0 +1,11 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-tab-label { + user-select: none; +} + +.tracy-tab-panel:not(.tracy-active) { + display: none; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/tabs.js b/vendor/tracy/tracy/src/Tracy/assets/tabs.js new file mode 100644 index 00000000..8ec2fe7b --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/tabs.js @@ -0,0 +1,40 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +// enables .tracy-tabs, .tracy-tab-label, .tracy-tab-panel, .tracy-active +class Tabs { + static init() { + document.documentElement.addEventListener('click', (e) => { + let label, context; + if ( + !e.shiftKey && !e.ctrlKey && !e.metaKey + && (label = e.target.closest('.tracy-tab-label')) + && (context = e.target.closest('.tracy-tabs')) + ) { + Tabs.toggle(context, label); + e.preventDefault(); + e.stopImmediatePropagation(); + } + }); + + Tabs.init = function () {}; + } + + static toggle(context, label) { + let labels = context.querySelector('.tracy-tab-label').parentNode.querySelectorAll('.tracy-tab-label'), + panels = context.querySelector('.tracy-tab-panel').parentNode.querySelectorAll(':scope > .tracy-tab-panel'); + + for (let i = 0; i < labels.length; i++) { + labels[i].classList.toggle('tracy-active', labels[i] === label); + } + + for (let i = 0; i < panels.length; i++) { + panels[i].classList.toggle('tracy-active', labels[i] === label); + } + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +Tracy.Tabs = Tracy.Tabs || Tabs; diff --git a/vendor/tracy/tracy/src/Tracy/assets/toggle.css b/vendor/tracy/tracy/src/Tracy/assets/toggle.css new file mode 100644 index 00000000..acce8e4f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/toggle.css @@ -0,0 +1,35 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-collapsed { + display: none; +} + +.tracy-toggle.tracy-collapsed { + display: inline; +} + +.tracy-toggle { + cursor: pointer; + user-select: none; + white-space: nowrap; +} + +.tracy-toggle:after { + content: ''; + display: inline-block; + vertical-align: middle; + line-height: 0; + border-top: .6ex solid; + border-right: .6ex solid transparent; + border-left: .6ex solid transparent; + transform: scale(1, 1.5); + margin: 0 .2ex 0 .7ex; + transition: .1s transform; + opacity: .5; +} + +.tracy-toggle.tracy-collapsed:after { + transform: rotate(-90deg) scale(1, 1.5) translate(.1ex, 0); +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/toggle.js b/vendor/tracy/tracy/src/Tracy/assets/toggle.js new file mode 100644 index 00000000..aabefb5f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/toggle.js @@ -0,0 +1,116 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +const MOVE_THRESHOLD = 100; + +// enables or toggling +class Toggle { + static init() { + let start; + document.documentElement.addEventListener('mousedown', (e) => { + start = [e.clientX, e.clientY]; + }); + + document.documentElement.addEventListener('click', (e) => { + let el; + if ( + !e.shiftKey && !e.ctrlKey && !e.metaKey + && (el = e.target.closest('.tracy-toggle')) + && Math.pow(start[0] - e.clientX, 2) + Math.pow(start[1] - e.clientY, 2) < MOVE_THRESHOLD + ) { + Toggle.toggle(el, undefined, e); + e.preventDefault(); + e.stopImmediatePropagation(); + } + }); + Toggle.init = function () {}; + } + + + // changes element visibility + static toggle(el, expand, e) { + let collapsed = el.classList.contains('tracy-collapsed'), + ref = el.getAttribute('data-tracy-ref') || el.getAttribute('href', 2), + dest = el; + + if (typeof expand === 'undefined') { + expand = collapsed; + } + + el.dispatchEvent(new CustomEvent('tracy-beforetoggle', { + bubbles: true, + detail: { collapsed: !expand, originalEvent: e }, + })); + + if (!ref || ref === '#') { + ref = '+'; + } else if (ref.substr(0, 1) === '#') { + dest = document; + } + ref = ref.match(/(\^\s*([^+\s]*)\s*)?(\+\s*(\S*)\s*)?(.*)/); + dest = ref[1] ? dest.parentNode : dest; + dest = ref[2] ? dest.closest(ref[2]) : dest; + dest = ref[3] ? Toggle.nextElement(dest.nextElementSibling, ref[4]) : dest; + dest = ref[5] ? dest.querySelector(ref[5]) : dest; + + el.classList.toggle('tracy-collapsed', !expand); + dest.classList.toggle('tracy-collapsed', !expand); + + el.dispatchEvent(new CustomEvent('tracy-toggle', { + bubbles: true, + detail: { relatedTarget: dest, collapsed: !expand, originalEvent: e }, + })); + } + + + // save & restore toggles + static persist(baseEl, restore) { + let saved = []; + baseEl.addEventListener('tracy-toggle', (e) => { + if (saved.indexOf(e.target) < 0) { + saved.push(e.target); + } + }); + + let toggles = JSON.parse(sessionStorage.getItem('tracy-toggles-' + baseEl.id)); + if (toggles && restore !== false) { + toggles.forEach((item) => { + let el = baseEl; + for (let i in item.path) { + if (!(el = el.children[item.path[i]])) { + return; + } + } + if (el.textContent === item.text) { + Toggle.toggle(el, item.expand); + } + }); + } + + window.addEventListener('pagehide', () => { + toggles = saved.map((el) => { + let item = { path: [], text: el.textContent, expand: !el.classList.contains('tracy-collapsed') }; + do { + item.path.unshift(Array.from(el.parentNode.children).indexOf(el)); + el = el.parentNode; + } while (el && el !== baseEl); + return item; + }); + sessionStorage.setItem('tracy-toggles-' + baseEl.id, JSON.stringify(toggles)); + }); + } + + + // finds next matching element + static nextElement(el, selector) { + while (el && selector && !el.matches(selector)) { + el = el.nextElementSibling; + } + return el; + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +Tracy.Toggle = Tracy.Toggle || Toggle; diff --git a/vendor/tracy/tracy/src/Tracy/functions.php b/vendor/tracy/tracy/src/Tracy/functions.php new file mode 100644 index 00000000..fa394d78 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/functions.php @@ -0,0 +1,50 @@ +setStub("startBuffering(); +foreach ($iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__ . '/../../src', RecursiveDirectoryIterator::SKIP_DOTS)) as $file) { + if (!in_array($file->getExtension(), ['php', 'phtml', 'js', 'css'], true)) { + continue; + } + + $s = file_get_contents($file->getPathname()); + if (!str_contains($s, '@tracySkipLocation')) { + $s = php_strip_whitespace($file->getPathname()); + } + + echo "adding: {$iterator->getSubPathname()}\n"; + $phar[$iterator->getSubPathname()] = $s; +} + +$phar->stopBuffering(); +$phar->compressFiles(Phar::GZ); + +echo "OK\n"; diff --git a/vendor/tracy/tracy/tools/open-in-editor/linux/install.sh b/vendor/tracy/tracy/tools/open-in-editor/linux/install.sh new file mode 100644 index 00000000..5a7bfb31 --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/linux/install.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# This shell script sets open-editor.sh as handler for editor:// protocol + +matches=0 +while read -r line +do + if [ "editor=" == "${line:0:7}" ]; then + matches=1 + break + fi +done < "open-editor.sh" + +if [ "$matches" == "0" ]; then + echo -e "\e[31;1mError: it seems like you have not set command to run your editor." + echo -e "Before install, set variable \`\$editor\` in file \`open-editor.sh\`.\e[0m" + exit 1 +fi + +# -------------------------------------------------------------- + +echo "[Desktop Entry] +Name=Tracy Open Editor +Exec=tracy-openeditor.sh %u +Terminal=false +NoDisplay=true +Type=Application +MimeType=x-scheme-handler/editor;" > tracy-openeditor.desktop + +chmod +x open-editor.sh +chmod +x tracy-openeditor.desktop + +sudo cp open-editor.sh /usr/bin/tracy-openeditor.sh +sudo xdg-desktop-menu install tracy-openeditor.desktop +sudo update-desktop-database +rm tracy-openeditor.desktop + +echo -e "\e[32;1mDone.\e[0m" diff --git a/vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh b/vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh new file mode 100644 index 00000000..69e37be8 --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh @@ -0,0 +1,109 @@ +#!/bin/bash +declare -A mapping + +# +# Configure your editor by setting the $editor variable: +# + +# Visual Studio Code +#editor='code --goto "$FILE":"$LINE"' +# Emacs +#editor='emacs +$LINE "$FILE"' +# gVim +#editor='gvim +$LINE "$FILE"' +# gEdit +#editor='gedit +$LINE "$FILE"' +# Pluma +#editor='pluma +$LINE "$FILE"' +# PHPStorm +# To enable PHPStorm command-line interface, folow this guide: https://www.jetbrains.com/help/phpstorm/working-with-the-ide-features-from-command-line.html +#editor='phpstorm --line $LINE "$FILE"' +# VS Codium +#editor='codium --goto "$FILE":"$LINE"' +# Visual Studio Code +#editor='code --goto "$FILE":"$LINE"' + +# +# Optionally configure custom mapping here: +# + +#mapping["/remotepath"]="/localpath" +#mapping["/mnt/d/"]="d:/" + +# +# Please, do not modify the code below. +# + +# Find and return URI parameter value. Or nothing, if the param is missing. +# Arguments: 1) URI, 2) Parameter name. +function get_param { + echo "$1" | sed -n -r "s/.*$2=([^&]*).*/\1/ip" +} + +if [[ -z "$editor" ]]; then + echo "You need to set the \$editor variable in file '`realpath $0`'" + exit +fi + +url=$1 +if [ "${url:0:9}" != "editor://" ]; then + exit +fi + +# Parse action and essential data from the URI. +regex='editor\:\/\/(open|create|fix)\/?\?(.*)' +action=`echo $url | sed -r "s/$regex/\1/i"` +uri_params=`echo $url | sed -r "s/$regex/\2/i"` + +file=`get_param $uri_params "file"` +line=`get_param $uri_params "line"` +search=`get_param $uri_params "search"` +replace=`get_param $uri_params "replace"` + +# Debug? +#echo "action '$action'" +#echo "file '$file'" +#echo "line '$line'" +#echo "search '$search'" +#echo "replace '$replace'" + +# Convert URI encoded codes to normal characters (e.g. '%2F' => '/'). +printf -v file "${file//%/\\x}" +# And escape double-quotes. +file=${file//\"/\\\"} + +# Apply custom mapping conversion. +for path in "${!mapping[@]}"; do + file="${file//$path/${mapping[$path]}}" +done + +# Action: Create a file (only if it does not already exist). +if [ "$action" == "create" ] && [[ ! -f "$file" ]]; then + mkdir -p $(dirname "$file") + touch "$file" + echo $replace > "$file" +fi + +# Action: Fix the file (if the file exists and while creating backup beforehand). +if [ "$action" == "fix" ]; then + + if [[ ! -f "$file" ]]; then + echo "Cannot fix non-existing file '$file'" + exit + fi + + # Backup the original file. + cp $file "$file.bak" + # Search and replace in place - only on the specified line. + sed -i "${line}s/${search}/${replace}/" $file + +fi + +# Format the command according to the selected editor. +command="${editor//\$FILE/$file}" +command="${command//\$LINE/$line}" + +# Debug? +#echo $command + +eval $command diff --git a/vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd b/vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd new file mode 100644 index 00000000..aa91aca0 --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd @@ -0,0 +1,11 @@ +@echo off +:: This Windows batch file sets open-editor.js as handler for editor:// protocol + +if defined PROCESSOR_ARCHITEW6432 (set reg="%systemroot%\sysnative\reg.exe") else (set reg=reg) + +%reg% ADD HKCR\editor /ve /d "URL:editor Protocol" /f +%reg% ADD HKCR\editor /v "URL Protocol" /d "" /f +%reg% ADD HKCR\editor\shell\open\command /ve /d "wscript \"%~dp0open-editor.js\" \"%%1\"" /f +%reg% ADD HKLM\SOFTWARE\Policies\Google\Chrome /v "AutoLaunchProtocolsFromOrigins" /d "[{\"allowed_origins\": [\"*\"],\"protocol\": \"editor\"}]" /t REG_SZ /f +:: Vivaldi (uncomment if needed) +:: %reg% ADD HKLM\SOFTWARE\Policies\Vivaldi /v "AutoLaunchProtocolsFromOrigins" /d "[{\"allowed_origins\": [\"*\"],\"protocol\": \"editor\"}]" /t REG_SZ /f diff --git a/vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js b/vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js new file mode 100644 index 00000000..ac1093e7 --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js @@ -0,0 +1,84 @@ +var settings = { + + // PhpStorm + // editor: '"C:\\Program Files\\JetBrains\\PhpStorm 2018.1.2\\bin\\phpstorm64.exe" --line %line% "%file%"', + // title: 'PhpStorm', + + // NetBeans + // editor: '"C:\\Program Files\\NetBeans 8.1\\bin\\netbeans.exe" "%file%:%line%" --console suppress', + + // Nusphere PHPEd + // editor: '"C:\\Program Files\\NuSphere\\PhpED\\phped.exe" "%file%" --line=%line%', + + // SciTE + // editor: '"C:\\Program Files\\SciTE\\scite.exe" "-open:%file%" -goto:%line%', + + // EmEditor + // editor: '"C:\\Program Files\\EmEditor\\EmEditor.exe" "%file%" /l %line%', + + // PSPad Editor + // editor: '"C:\\Program Files\\PSPad editor\\PSPad.exe" -%line% "%file%"', + + // gVim + // editor: '"C:\\Program Files\\Vim\\vim73\\gvim.exe" "%file%" +%line%', + + // Sublime Text 2 + // editor: '"C:\\Program Files\\Sublime Text 2\\sublime_text.exe" "%file%:%line%"', + + // Visual Studio Code / VSCodium + // editor: '"C:\\Program Files\\Microsoft VS Code\\Code.exe" --goto "%file%:%line%"', + + mappings: { + // '/remotepath': '/localpath' + } +}; + + + +if (!settings.editor) { + WScript.Echo('Create variable "settings.editor" in ' + WScript.ScriptFullName); + WScript.Quit(); +} + +var url = WScript.Arguments(0); +var match = /^editor:\/\/(open|create|fix)\/?\?file=([^&]+)&line=(\d+)(?:&search=([^&]*)&replace=([^&]*))?/.exec(url); +if (!match) { + WScript.Echo('Unexpected URI ' + url); + WScript.Quit(); +} +for (var i in match) { + match[i] = decodeURIComponent(match[i]).replace(/\+/g, ' '); +} + +var action = match[1]; +var file = match[2]; +var line = match[3]; +var search = match[4]; +var replace = match[5]; + +var shell = new ActiveXObject('WScript.Shell'); +var fileSystem = new ActiveXObject('Scripting.FileSystemObject'); + +for (var id in settings.mappings) { + if (file.indexOf(id) === 0) { + file = settings.mappings[id] + file.substr(id.length); + break; + } +} + +if (action === 'create' && !fileSystem.FileExists(file)) { + shell.Run('cmd /c mkdir "' + fileSystem.GetParentFolderName(file) + '"', 0, 1); + fileSystem.CreateTextFile(file).Write(replace); + +} else if (action === 'fix') { + var lines = fileSystem.OpenTextFile(file).ReadAll().split('\n'); + lines[line-1] = lines[line-1].replace(search, replace); + fileSystem.OpenTextFile(file, 2).Write(lines.join('\n')); +} + +var command = settings.editor.replace(/%line%/, line).replace(/%file%/, file); +shell.Exec(command); + +if (settings.title) { + shell.AppActivate(settings.title); +}